From fa5a8a2acb07d6194d0cd0e4b2931bfafa8a8cf5 Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Sat, 14 Mar 2026 08:27:50 -0600 Subject: [PATCH 01/17] docs: add workspace scanning & integration tests implementation plan Co-Authored-By: Claude Opus 4.6 (1M context) --- ...14-workspace-scanning-integration-tests.md | 822 ++++++++++++++++++ 1 file changed, 822 insertions(+) create mode 100644 docs/superpowers/plans/2026-03-14-workspace-scanning-integration-tests.md diff --git a/docs/superpowers/plans/2026-03-14-workspace-scanning-integration-tests.md b/docs/superpowers/plans/2026-03-14-workspace-scanning-integration-tests.md new file mode 100644 index 0000000..c34e0c1 --- /dev/null +++ b/docs/superpowers/plans/2026-03-14-workspace-scanning-integration-tests.md @@ -0,0 +1,822 @@ +# Workspace-Aware Scanning & Integration Tests + +> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Make the scanner discover skills from workspace packages when run from a monorepo root, and add integration tests with Verdaccio that verify scanning across all package managers (npm, pnpm, yarn, bun), project structures (single, monorepo root, monorepo workspace), and dependency depths (direct, transitive+1/+2/+3). + +**Architecture:** Two changes to the scanner: (1) export `resolveWorkspacePackages` from `setup.ts` so the scanner can discover workspace package directories, (2) add a workspace-aware phase to `scanForIntents` that scans each workspace package's `node_modules` and walks their deps. For integration tests, use Verdaccio (local npm registry) to publish fixture packages, then create real projects with each package manager, install deps, and run the scanner. Follows Knip's pattern: use workspace config to find packages, use direct node_modules path lookup for resolution. + +**Tech Stack:** Vitest, Verdaccio (dev dependency), npm/pnpm/yarn/bun CLIs + +--- + +## File Structure + +| File | Action | Responsibility | +|------|--------|----------------| +| `packages/intent/src/setup.ts` | Modify | Export `resolveWorkspacePackages` | +| `packages/intent/src/scanner.ts` | Modify | Add workspace scanning phase | +| `packages/intent/tests/scanner.test.ts` | Modify | Add unit tests for workspace scanning | +| `packages/intent/tests/fixtures/integration/skills-leaf/package.json` | Create | Fixture: package with skills | +| `packages/intent/tests/fixtures/integration/skills-leaf/skills/core/SKILL.md` | Create | Fixture: skill file | +| `packages/intent/tests/fixtures/integration/wrapper-1/package.json` | Create | Fixture: depends on skills-leaf | +| `packages/intent/tests/fixtures/integration/wrapper-2/package.json` | Create | Fixture: depends on wrapper-1 | +| `packages/intent/tests/fixtures/integration/wrapper-3/package.json` | Create | Fixture: depends on wrapper-2 | +| `packages/intent/tests/integration/scaffold.ts` | Create | Helpers: Verdaccio lifecycle, project scaffolding, CLI invocation | +| `packages/intent/tests/integration/scanner-integration.test.ts` | Create | Integration test grid | +| `packages/intent/src/scanner-arborist.ts` | Delete | Remove spike file | + +--- + +## Chunk 1: Scanner Workspace Support + +### Task 1: Export `resolveWorkspacePackages` from setup.ts + +**Files:** +- Modify: `packages/intent/src/setup.ts:483` + +- [ ] **Step 1: Make `resolveWorkspacePackages` exported** + +In `packages/intent/src/setup.ts`, change the function declaration at line 483 from: + +```typescript +function resolveWorkspacePackages( +``` + +to: + +```typescript +export function resolveWorkspacePackages( +``` + +No other changes needed — the function already has the right signature. + +- [ ] **Step 2: Run existing tests to verify no regression** + +Run: `pnpm vitest run tests/setup.test.ts` +Expected: All tests pass (no behavior change, just exported) + +- [ ] **Step 3: Commit** + +```bash +git add packages/intent/src/setup.ts +git commit -m "refactor: export resolveWorkspacePackages from setup.ts" +``` + +### Task 2: Write failing test for workspace scanning + +**Files:** +- Modify: `packages/intent/tests/scanner.test.ts` + +- [ ] **Step 1: Write a test that creates a pnpm-style monorepo and expects skills to be found from the root** + +Add this test to the `scanForIntents` describe block in `scanner.test.ts`: + +```typescript +it('discovers skills in workspace package dependencies from monorepo root', async () => { + // Monorepo root with pnpm-workspace.yaml + writeFileSync( + join(root, 'pnpm-workspace.yaml'), + 'packages:\n - packages/*\n', + ) + writeJson(join(root, 'package.json'), { + name: 'monorepo', + private: true, + }) + + // Workspace package that depends on a skills-enabled package + const appDir = join(root, 'packages', 'app') + createDir(root, 'packages', 'app') + writeJson(join(appDir, 'package.json'), { + name: '@monorepo/app', + version: '1.0.0', + dependencies: { '@tanstack/db': '0.5.0' }, + }) + + // The skills-enabled package installed in the workspace's node_modules + createDir(appDir, 'node_modules', '@tanstack', 'db') + const dbDir = join(appDir, 'node_modules', '@tanstack', 'db') + writeJson(join(dbDir, 'package.json'), { + name: '@tanstack/db', + version: '0.5.0', + intent: { version: 1, repo: 'TanStack/db', docs: 'https://db.tanstack.com' }, + }) + writeSkillMd(join(dbDir, 'skills', 'db-core'), { + name: 'db-core', + description: 'Core database concepts', + }) + + // Also create root node_modules (empty, typical for pnpm monorepos) + createDir(root, 'node_modules') + + const result = await scanForIntents(root) + expect(result.packages).toHaveLength(1) + expect(result.packages[0]!.name).toBe('@tanstack/db') + expect(result.packages[0]!.skills).toHaveLength(1) +}) +``` + +Also add a test for `package.json` workspaces (npm/yarn/bun): + +```typescript +it('discovers skills in workspace package dependencies using package.json workspaces', async () => { + writeJson(join(root, 'package.json'), { + name: 'monorepo', + private: true, + workspaces: ['packages/*'], + }) + + const appDir = join(root, 'packages', 'app') + createDir(root, 'packages', 'app') + writeJson(join(appDir, 'package.json'), { + name: '@monorepo/app', + version: '1.0.0', + dependencies: { '@tanstack/db': '0.5.0' }, + }) + + // In npm/yarn/bun monorepos, deps are hoisted to root node_modules + const dbDir = join(root, 'node_modules', '@tanstack', 'db') + writeJson(join(dbDir, 'package.json'), { + name: '@tanstack/db', + version: '0.5.0', + intent: { version: 1, repo: 'TanStack/db', docs: 'https://db.tanstack.com' }, + }) + writeSkillMd(join(dbDir, 'skills', 'db-core'), { + name: 'db-core', + description: 'Core database concepts', + }) + + const result = await scanForIntents(root) + expect(result.packages).toHaveLength(1) + expect(result.packages[0]!.name).toBe('@tanstack/db') +}) +``` + +- [ ] **Step 2: Run the tests to verify they fail** + +Run: `pnpm vitest run tests/scanner.test.ts -t "discovers skills in workspace"` +Expected: FAIL — the first test (pnpm-style with workspace package's own node_modules) should fail because the scanner doesn't look at workspace packages' node_modules. The second test (hoisted) may already pass since deps are in root node_modules. + +### Task 3: Add workspace scanning phase to scanner.ts + +**Files:** +- Modify: `packages/intent/src/scanner.ts` + +- [ ] **Step 1: Import workspace resolution functions** + +Add to the imports at the top of `scanner.ts`: + +```typescript +import { + readWorkspacePatterns, + resolveWorkspacePackages, +} from './setup.js' +``` + +- [ ] **Step 2: Add workspace scanning after Phase 1** + +After line 473 (`scanTarget(nodeModules.local)`), add the workspace scanning phase: + +```typescript + // Phase 1b: In monorepos, scan workspace packages' node_modules. + // This handles pnpm monorepos where each workspace package has its own + // node_modules with symlinks to its specific dependencies. + const workspacePatterns = readWorkspacePatterns(projectRoot) + if (workspacePatterns) { + for (const wsDir of resolveWorkspacePackages(projectRoot, workspacePatterns)) { + const wsNodeModules = join(wsDir, 'node_modules') + if (!existsSync(wsNodeModules)) continue + + for (const dirPath of listNodeModulesPackageDirs(wsNodeModules)) { + tryRegister(dirPath, 'unknown') + } + } + } +``` + +- [ ] **Step 3: Run the workspace tests to verify they pass** + +Run: `pnpm vitest run tests/scanner.test.ts -t "discovers skills in workspace"` +Expected: PASS + +- [ ] **Step 4: Run all scanner tests to verify no regression** + +Run: `pnpm vitest run tests/scanner.test.ts` +Expected: All tests pass + +- [ ] **Step 5: Commit** + +```bash +git add packages/intent/src/scanner.ts packages/intent/tests/scanner.test.ts +git commit -m "feat: scan workspace package dependencies from monorepo root" +``` + +### Task 4: Clean up Arborist spike + +**Files:** +- Delete: `packages/intent/src/scanner-arborist.ts` +- Modify: `packages/intent/package.json` (remove `@npmcli/arborist` devDependency) + +- [ ] **Step 1: Delete the spike file** + +```bash +rm packages/intent/src/scanner-arborist.ts +``` + +- [ ] **Step 2: Remove @npmcli/arborist from devDependencies** + +Run: `cd packages/intent && pnpm remove @npmcli/arborist` + +- [ ] **Step 3: Run all tests** + +Run: `pnpm test:lib` +Expected: All tests pass + +- [ ] **Step 4: Commit** + +```bash +git add packages/intent/src/scanner-arborist.ts packages/intent/package.json ../../pnpm-lock.yaml +git commit -m "chore: remove arborist spike and dependency" +``` + +--- + +## Chunk 2: Integration Test Fixtures + +### Task 5: Create fixture packages + +These are static packages that will be published to the local Verdaccio registry. Each has a `package.json` and optionally `skills/`. + +**Files:** +- Create: `packages/intent/tests/fixtures/integration/skills-leaf/package.json` +- Create: `packages/intent/tests/fixtures/integration/skills-leaf/skills/core/SKILL.md` +- Create: `packages/intent/tests/fixtures/integration/wrapper-1/package.json` +- Create: `packages/intent/tests/fixtures/integration/wrapper-2/package.json` +- Create: `packages/intent/tests/fixtures/integration/wrapper-3/package.json` + +- [ ] **Step 1: Create the skills-leaf package** + +`packages/intent/tests/fixtures/integration/skills-leaf/package.json`: +```json +{ + "name": "@test-intent/skills-leaf", + "version": "1.0.0", + "intent": { + "version": 1, + "repo": "test/skills-leaf", + "docs": "https://example.com/docs" + }, + "files": ["skills"] +} +``` + +`packages/intent/tests/fixtures/integration/skills-leaf/skills/core/SKILL.md`: +```markdown +--- +name: core +description: "Core skill for integration testing" +type: core +--- + +# Core Skill + +This is a test skill used by integration tests. +``` + +- [ ] **Step 2: Create wrapper-1 (depends on skills-leaf)** + +`packages/intent/tests/fixtures/integration/wrapper-1/package.json`: +```json +{ + "name": "@test-intent/wrapper-1", + "version": "1.0.0", + "dependencies": { + "@test-intent/skills-leaf": "1.0.0" + } +} +``` + +- [ ] **Step 3: Create wrapper-2 (depends on wrapper-1)** + +`packages/intent/tests/fixtures/integration/wrapper-2/package.json`: +```json +{ + "name": "@test-intent/wrapper-2", + "version": "1.0.0", + "dependencies": { + "@test-intent/wrapper-1": "1.0.0" + } +} +``` + +- [ ] **Step 4: Create wrapper-3 (depends on wrapper-2)** + +`packages/intent/tests/fixtures/integration/wrapper-3/package.json`: +```json +{ + "name": "@test-intent/wrapper-3", + "version": "1.0.0", + "dependencies": { + "@test-intent/wrapper-2": "1.0.0" + } +} +``` + +- [ ] **Step 5: Commit** + +```bash +git add packages/intent/tests/fixtures/integration/ +git commit -m "test: add integration test fixture packages" +``` + +--- + +## Chunk 3: Integration Test Infrastructure + +### Task 6: Install Verdaccio and create test helpers + +**Files:** +- Modify: `packages/intent/package.json` (add verdaccio devDependency) +- Create: `packages/intent/tests/integration/scaffold.ts` + +- [ ] **Step 1: Install Verdaccio** + +```bash +cd packages/intent && pnpm add -D verdaccio @verdaccio/node-api +``` + +- [ ] **Step 2: Create the scaffold helper module** + +`packages/intent/tests/integration/scaffold.ts`: + +```typescript +import { execSync, execFileSync } from 'node:child_process' +import { + existsSync, + mkdirSync, + mkdtempSync, + realpathSync, + rmSync, + writeFileSync, +} from 'node:fs' +import { tmpdir } from 'node:os' +import { dirname, join } from 'node:path' +import { fileURLToPath } from 'node:url' + +const thisDir = dirname(fileURLToPath(import.meta.url)) +const fixturesDir = join(thisDir, '..', 'fixtures', 'integration') +const cliPath = join(thisDir, '..', '..', 'dist', 'cli.mjs') +const realTmpdir = realpathSync(tmpdir()) + +// --------------------------------------------------------------------------- +// Verdaccio lifecycle +// --------------------------------------------------------------------------- + +export interface Registry { + url: string + stop: () => void +} + +export async function startRegistry(): Promise { + const { runServer } = await import('@verdaccio/node-api') + + const storageDir = mkdtempSync(join(realTmpdir, 'verdaccio-storage-')) + const port = 6000 + Math.floor(Math.random() * 4000) + const configPath = join(storageDir, 'config.yaml') + + // Write Verdaccio config file + writeFileSync( + configPath, + [ + `storage: ${storageDir}`, + 'uplinks:', + ' npmjs:', + ' url: https://registry.npmjs.org/', + 'packages:', + " '@test-intent/*':", + ' access: $all', + ' publish: $all', + " '**':", + ' access: $all', + ' proxy: npmjs', + 'log: { type: stdout, format: pretty, level: fatal }', + ].join('\n'), + ) + + const app = await runServer(configPath) + + return new Promise((resolve, reject) => { + const server = app.listen(port, () => { + const url = `http://localhost:${port}` + resolve({ + url, + stop: () => { + server.close() + rmSync(storageDir, { recursive: true, force: true }) + }, + }) + }) + server.on('error', reject) + }) +} + +// --------------------------------------------------------------------------- +// Publishing fixtures +// --------------------------------------------------------------------------- + +export function publishFixtures(registryUrl: string): void { + const packages = ['skills-leaf', 'wrapper-1', 'wrapper-2', 'wrapper-3'] + + for (const pkg of packages) { + const pkgDir = join(fixturesDir, pkg) + execSync(`npm publish --registry ${registryUrl} --access public`, { + cwd: pkgDir, + stdio: 'ignore', + }) + } +} + +// --------------------------------------------------------------------------- +// Project scaffolding +// --------------------------------------------------------------------------- + +export type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun' +export type ProjectStructure = 'single' | 'monorepo-root' | 'monorepo-workspace' + +interface ScaffoldResult { + /** Root of the created project */ + root: string + /** Directory to run the scanner from */ + cwd: string +} + +export function scaffoldProject(opts: { + pm: PackageManager + structure: ProjectStructure + dependency: string + registryUrl: string +}): ScaffoldResult { + const root = mkdtempSync(join(realTmpdir, `intent-integ-${opts.pm}-`)) + + // Create lockfile marker so detectPackageManager works + const lockfileMap: Record = { + npm: 'package-lock.json', + pnpm: 'pnpm-lock.yaml', + yarn: 'yarn.lock', + bun: 'bun.lock', + } + writeFileSync(join(root, lockfileMap[opts.pm]), '') + + if (opts.structure === 'single') { + writeJson(join(root, 'package.json'), { + name: 'test-project', + private: true, + dependencies: { [opts.dependency]: '1.0.0' }, + }) + install(root, opts.pm, opts.registryUrl) + return { root, cwd: root } + } + + // Monorepo setup + writeJson(join(root, 'package.json'), { + name: 'test-monorepo', + private: true, + ...(opts.pm !== 'pnpm' ? { workspaces: ['packages/*'] } : {}), + }) + if (opts.pm === 'pnpm') { + writeFileSync( + join(root, 'pnpm-workspace.yaml'), + 'packages:\n - packages/*\n', + ) + } + if (opts.pm === 'yarn') { + writeFileSync( + join(root, '.yarnrc.yml'), + 'nodeLinker: node-modules\n', + ) + } + + const appDir = join(root, 'packages', 'app') + mkdirSync(appDir, { recursive: true }) + writeJson(join(appDir, 'package.json'), { + name: '@test/app', + version: '1.0.0', + dependencies: { [opts.dependency]: '1.0.0' }, + }) + + install(root, opts.pm, opts.registryUrl) + + return { + root, + cwd: opts.structure === 'monorepo-root' ? root : appDir, + } +} + +function install(dir: string, pm: PackageManager, registryUrl: string): void { + const registryArg = `--registry=${registryUrl}` + const env = { ...process.env, npm_config_registry: registryUrl } + + switch (pm) { + case 'npm': + execSync(`npm install ${registryArg}`, { cwd: dir, stdio: 'ignore', env }) + break + case 'pnpm': + execSync(`pnpm install ${registryArg} --no-frozen-lockfile`, { + cwd: dir, + stdio: 'ignore', + env, + }) + break + case 'yarn': + execSync(`yarn install ${registryArg}`, { cwd: dir, stdio: 'ignore', env }) + break + case 'bun': + execSync(`bun install ${registryArg}`, { cwd: dir, stdio: 'ignore', env }) + break + } +} + +// --------------------------------------------------------------------------- +// CLI invocation +// --------------------------------------------------------------------------- + +export interface CliResult { + stdout: string + stderr: string + exitCode: number + parsed: any +} + +export async function runScanner( + cwd: string, + method: 'direct' | 'symlink' = 'direct', +): Promise { + let binPath = cliPath + + if (method === 'symlink') { + const { symlinkSync } = await import('node:fs') + const linkDir = mkdtempSync(join(realTmpdir, 'intent-link-')) + const linkPath = join(linkDir, 'intent-cli.mjs') + symlinkSync(cliPath, linkPath) + binPath = linkPath + } + + try { + const stdout = execFileSync('node', [binPath, 'list', '--json'], { + cwd, + encoding: 'utf8', + stdio: ['ignore', 'pipe', 'pipe'], + }) + const parsed = JSON.parse(stdout) + return { stdout, stderr: '', exitCode: 0, parsed } + } catch (err: any) { + return { + stdout: err.stdout ?? '', + stderr: err.stderr ?? '', + exitCode: err.status ?? 1, + parsed: null, + } + } +} + +// --------------------------------------------------------------------------- +// Helpers +// --------------------------------------------------------------------------- + +function writeJson(filePath: string, data: unknown): void { + mkdirSync(dirname(filePath), { recursive: true }) + writeFileSync(filePath, JSON.stringify(data, null, 2)) +} +``` + +- [ ] **Step 3: Exclude integration tests from `test:lib` and add `test:integration` script** + +In `packages/intent/package.json`, update `scripts`: +```json +"scripts": { + "test:lib": "vitest run --exclude tests/integration/**", + "test:integration": "vitest run tests/integration/" +} +``` + +- [ ] **Step 4: Commit** + +```bash +git add packages/intent/package.json packages/intent/tests/integration/scaffold.ts ../../pnpm-lock.yaml +git commit -m "test: add Verdaccio-based integration test infrastructure" +``` + +--- + +## Chunk 4: Integration Tests + +### Task 7: Write the integration test grid + +**Files:** +- Create: `packages/intent/tests/integration/scanner-integration.test.ts` + +This test file uses `describe.each` to create the full matrix: 4 package managers × 3 project structures × 4 dependency depths. + +- [ ] **Step 1: Write the integration test file** + +`packages/intent/tests/integration/scanner-integration.test.ts`: + +```typescript +import { rmSync } from 'node:fs' +import { afterAll, beforeAll, describe, expect, it } from 'vitest' +import type { PackageManager, ProjectStructure, Registry } from './scaffold.js' +import { + publishFixtures, + runScanner, + scaffoldProject, + startRegistry, +} from './scaffold.js' + +// These tests require npm, pnpm, yarn, and bun to be installed. +// They create real projects and install real packages from a local registry. +// Timeout is generous because installs can be slow. + +const PACKAGE_MANAGERS: Array = ['npm', 'pnpm', 'yarn', 'bun'] +const STRUCTURES: Array = [ + 'single', + 'monorepo-root', + 'monorepo-workspace', +] +const DEPENDENCY_CHAINS: Array<{ + label: string + dep: string + transitiveDepth: number +}> = [ + { label: 'direct', dep: '@test-intent/skills-leaf', transitiveDepth: 0 }, + { label: 'transitive+1', dep: '@test-intent/wrapper-1', transitiveDepth: 1 }, + { label: 'transitive+2', dep: '@test-intent/wrapper-2', transitiveDepth: 2 }, + { label: 'transitive+3', dep: '@test-intent/wrapper-3', transitiveDepth: 3 }, +] + +let registry: Registry +const tempDirs: Array = [] + +beforeAll(async () => { + registry = await startRegistry() + publishFixtures(registry.url) +}, 30_000) + +afterAll(() => { + registry?.stop() + for (const dir of tempDirs) { + rmSync(dir, { recursive: true, force: true }) + } +}) + +describe.each(PACKAGE_MANAGERS)('package manager: %s', (pm) => { + describe.each(STRUCTURES)('structure: %s', (structure) => { + describe.each(DEPENDENCY_CHAINS)( + 'dependency: $label', + ({ dep }) => { + it( + 'discovers @test-intent/skills-leaf and its core skill', + () => { + const { root, cwd } = scaffoldProject({ + pm, + structure, + dependency: dep, + registryUrl: registry.url, + }) + tempDirs.push(root) + + const result = await runScanner(cwd) + + expect(result.exitCode).toBe(0) + expect(result.parsed).toBeTruthy() + expect(result.parsed.packages).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + name: '@test-intent/skills-leaf', + version: '1.0.0', + skills: expect.arrayContaining([ + expect.objectContaining({ + name: 'core', + type: 'core', + }), + ]), + }), + ]), + ) + }, + 60_000, + ) + }, + ) + }) +}) + +// Test that symlink invocation also works (the isMain bug fix) +describe('symlink invocation', () => { + it('finds skills when CLI is invoked through a symlink', () => { + const { root, cwd } = scaffoldProject({ + pm: 'npm', + structure: 'single', + dependency: '@test-intent/skills-leaf', + registryUrl: registry.url, + }) + tempDirs.push(root) + + const result = await runScanner(cwd, 'symlink') + + expect(result.exitCode).toBe(0) + expect(result.parsed.packages).toHaveLength(1) + expect(result.parsed.packages[0].name).toBe('@test-intent/skills-leaf') + }, 60_000) +}) +``` + +- [ ] **Step 2: Build the CLI first (integration tests use the built binary)** + +Run: `pnpm run build` + +- [ ] **Step 3: Run the integration tests** + +Run: `pnpm vitest run tests/integration/scanner-integration.test.ts --test-timeout=120000` + +Expected: Tests may take a while (real installs). Debug any failures — likely candidates: +- Yarn may need `.yarnrc.yml` with `nodeLinker: node-modules` in the scaffolded project +- Bun may need special handling +- Transitive depth tests may fail if the scanner doesn't walk deep enough (existing behavior, not a new bug) + +Fix any issues in `scaffold.ts` or `scanner.ts` as they arise. + +- [ ] **Step 4: Run the full test suite** + +Run: `pnpm test:lib` +Expected: All tests pass (both existing unit tests and new integration tests) + +- [ ] **Step 5: Commit** + +```bash +git add packages/intent/tests/integration/scanner-integration.test.ts +git commit -m "test: add cross-package-manager integration test grid" +``` + +### Task 8: Handle edge cases discovered during integration testing + +This task is intentionally open-ended. During Task 7, some test scenarios may fail revealing real scanner bugs. Common expected issues: + +1. **Yarn classic** may need `nodeLinker: node-modules` in `.yarnrc.yml` — add this to `scaffoldProject` when `pm === 'yarn'` +2. **pnpm monorepo transitive deps** — workspace package's transitive deps may not be discovered if the scanner only scans the workspace's direct `node_modules` but doesn't walk deps from there. Solution: after scanning workspace node_modules, also call `walkDeps` on each discovered package. +3. **Bun monorepo workspace detection** — bun uses `package.json` workspaces, should work with existing code + +- [ ] **Step 1: Fix any failing test scenarios** + +For each failure: identify root cause, fix in scanner.ts or scaffold.ts, verify fix. + +- [ ] **Step 2: Run full test suite** + +Run: `pnpm test:lib` +Expected: All tests pass + +- [ ] **Step 3: Commit fixes** + +```bash +git add -A +git commit -m "fix: address integration test edge cases" +``` + +--- + +## Chunk 5: Final Verification + +### Task 9: End-to-end verification against real monorepo + +- [ ] **Step 1: Build the CLI** + +Run: `pnpm run build` + +- [ ] **Step 2: Test from the monorepo root (the new workspace scanning)** + +```bash +cd /Users/kylemathews/programs/darix/.worktrees/ts-darix-runtime +node /Users/kylemathews/programs/intent/packages/intent/dist/cli.mjs list +``` + +Expected: Should find `@tanstack/db` with 6 skills (new workspace scanning discovers it through workspace packages' node_modules) + +- [ ] **Step 4: Test from the workspace package subdir** + +```bash +cd /Users/kylemathews/programs/darix/.worktrees/ts-darix-runtime/packages/ts-darix-runtime +node /Users/kylemathews/programs/intent/packages/intent/dist/cli.mjs list +``` + +Expected: Should find `@tanstack/db` with 6 skills (was already working after the isMain fix) + +- [ ] **Step 5: Run full test suite one final time** + +Run: `pnpm test:lib` +Expected: All tests pass + +- [ ] **Step 6: Commit any remaining changes** + +```bash +git add -A +git commit -m "test: verify end-to-end against real monorepo" +``` From 53b23d14d744e8361865ab1a6a271b54fa9d6f0c Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Sat, 14 Mar 2026 09:31:03 -0600 Subject: [PATCH 02/17] docs: update plan with createRequire, transitive workspace walking, review fixes Addresses all 5 findings from external review: 1. Transitive workspace deps: walk workspace packages' deps, not just top-level scan 2. Hoisted deps: createRequire-based resolveDepDir walks up directory tree naturally 3. Async test callbacks: runScanner is now sync (execFileSync), no await needed 4. Missing createDir: added for all dirs before writeSkillMd/writeJson 5. test:lib vs test:integration: verification steps use both commands Co-Authored-By: Claude Opus 4.6 (1M context) --- ...14-workspace-scanning-integration-tests.md | 568 ++++++++++-------- 1 file changed, 327 insertions(+), 241 deletions(-) diff --git a/docs/superpowers/plans/2026-03-14-workspace-scanning-integration-tests.md b/docs/superpowers/plans/2026-03-14-workspace-scanning-integration-tests.md index c34e0c1..21fb38c 100644 --- a/docs/superpowers/plans/2026-03-14-workspace-scanning-integration-tests.md +++ b/docs/superpowers/plans/2026-03-14-workspace-scanning-integration-tests.md @@ -2,11 +2,11 @@ > **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking. -**Goal:** Make the scanner discover skills from workspace packages when run from a monorepo root, and add integration tests with Verdaccio that verify scanning across all package managers (npm, pnpm, yarn, bun), project structures (single, monorepo root, monorepo workspace), and dependency depths (direct, transitive+1/+2/+3). +**Goal:** Make the scanner discover skills from workspace packages when run from a monorepo root, fix dep resolution for hoisted workspace layouts, and add integration tests with Verdaccio that verify scanning across all package managers (npm, pnpm, yarn, bun), project structures (single, monorepo root, monorepo workspace), and dependency depths (direct, transitive+1/+2/+3). -**Architecture:** Two changes to the scanner: (1) export `resolveWorkspacePackages` from `setup.ts` so the scanner can discover workspace package directories, (2) add a workspace-aware phase to `scanForIntents` that scans each workspace package's `node_modules` and walks their deps. For integration tests, use Verdaccio (local npm registry) to publish fixture packages, then create real projects with each package manager, install deps, and run the scanner. Follows Knip's pattern: use workspace config to find packages, use direct node_modules path lookup for resolution. +**Architecture:** Three scanner changes: (1) replace `resolveDepDir` with Node's `createRequire` for dependency resolution — this naturally handles hoisted deps, pnpm symlinks, and workspace layouts because Node already walks up the directory tree; (2) add a workspace-aware phase that discovers workspace packages via `pnpm-workspace.yaml` / `package.json#workspaces` and walks their dependencies to find transitive skills packages; (3) export `resolveWorkspacePackages` from `setup.ts`. For integration tests, use Verdaccio (local npm registry) to publish fixture packages, then create real projects with each package manager, install deps, and run the scanner. Follows Knip's pattern: use workspace config to find packages, use Node's built-in module resolution for dep lookup. -**Tech Stack:** Vitest, Verdaccio (dev dependency), npm/pnpm/yarn/bun CLIs +**Tech Stack:** Vitest, Verdaccio / @verdaccio/node-api (dev dependency), npm/pnpm/yarn/bun CLIs --- @@ -14,8 +14,9 @@ | File | Action | Responsibility | |------|--------|----------------| +| `packages/intent/src/utils.ts` | Modify | Replace `resolveDepDir` with `createRequire`-based resolution, remove `listNodeModulesPackageDirs`, `getDeps`, `detectGlobalNodeModules` | | `packages/intent/src/setup.ts` | Modify | Export `resolveWorkspacePackages` | -| `packages/intent/src/scanner.ts` | Modify | Add workspace scanning phase | +| `packages/intent/src/scanner.ts` | Modify | Use new `resolveDepDir`, add workspace scanning phase, simplify by removing multi-phase scanning | | `packages/intent/tests/scanner.test.ts` | Modify | Add unit tests for workspace scanning | | `packages/intent/tests/fixtures/integration/skills-leaf/package.json` | Create | Fixture: package with skills | | `packages/intent/tests/fixtures/integration/skills-leaf/skills/core/SKILL.md` | Create | Fixture: skill file | @@ -28,53 +29,165 @@ --- -## Chunk 1: Scanner Workspace Support +## Chunk 1: Replace resolveDepDir with createRequire -### Task 1: Export `resolveWorkspacePackages` from setup.ts +### Task 1: Replace `resolveDepDir` in utils.ts + +The current `resolveDepDir` has a hand-rolled 3-layer resolution strategy (hoisted check, nested check, pnpm virtual store walk-up). Node's `createRequire` handles all of these — plus upward workspace-root walks — in one call. **Files:** -- Modify: `packages/intent/src/setup.ts:483` +- Modify: `packages/intent/src/utils.ts:146-199` -- [ ] **Step 1: Make `resolveWorkspacePackages` exported** +- [ ] **Step 1: Write the failing test for the new behavior** -In `packages/intent/src/setup.ts`, change the function declaration at line 483 from: +The existing scanner tests already exercise `resolveDepDir` indirectly through `scanForIntents`. We'll verify the new resolution by adding a test that proves workspace-hoisted deps are found when scanning from a workspace package subdir. Add to `scanner.test.ts`: ```typescript -function resolveWorkspacePackages( +it('finds hoisted deps when scanning from a workspace package subdir', async () => { + // Simulate npm/yarn/bun monorepo: deps hoisted to root node_modules + writeJson(join(root, 'package.json'), { + name: 'monorepo', + private: true, + workspaces: ['packages/*'], + }) + + const appDir = join(root, 'packages', 'app') + createDir(root, 'packages', 'app') + writeJson(join(appDir, 'package.json'), { + name: '@monorepo/app', + version: '1.0.0', + dependencies: { '@tanstack/db': '0.5.0' }, + }) + + // Dep is hoisted to root, NOT in app's node_modules + createDir(root, 'node_modules', '@tanstack', 'db') + createDir(root, 'node_modules', '@tanstack', 'db', 'skills', 'db-core') + const dbDir = join(root, 'node_modules', '@tanstack', 'db') + writeJson(join(dbDir, 'package.json'), { + name: '@tanstack/db', + version: '0.5.0', + intent: { version: 1, repo: 'TanStack/db', docs: 'https://db.tanstack.com' }, + }) + writeSkillMd(join(dbDir, 'skills', 'db-core'), { + name: 'db-core', + description: 'Core database concepts', + }) + + // Scan from the workspace package subdir (not root) + const result = await scanForIntents(appDir) + expect(result.packages).toHaveLength(1) + expect(result.packages[0]!.name).toBe('@tanstack/db') +}) ``` -to: +Run: `pnpm vitest run tests/scanner.test.ts -t "finds hoisted deps"` +Expected: FAIL — current `resolveDepDir` only checks explicit `resolutionRoots`, not upward walk. + +- [ ] **Step 2: Replace `resolveDepDir` in utils.ts** + +Replace the existing `resolveDepDir` function (lines 146-199 of `utils.ts`) with: ```typescript -export function resolveWorkspacePackages( +import { createRequire } from 'node:module' + +/** + * Resolve the directory of a dependency by name. Uses Node's built-in + * module resolution via createRequire, which handles: + * - Hoisted layouts (npm, yarn, bun) — walks up directory tree + * - pnpm symlinked virtual store — follows symlinks + * - Workspace packages — finds deps at workspace root + * - Nested node_modules — standard Node resolution + */ +export function resolveDepDir( + depName: string, + parentDir: string, +): string | null { + try { + const require = createRequire(join(parentDir, 'package.json')) + const pkgJsonPath = require.resolve(join(depName, 'package.json')) + return dirname(pkgJsonPath) + } catch { + return null + } +} ``` -No other changes needed — the function already has the right signature. +Also remove these functions that are no longer needed: +- `listNodeModulesPackageDirs` (scanner will scan via workspace resolution + dep walking instead) +- `detectGlobalNodeModules` (no longer used — `createRequire` finds global installs naturally) -- [ ] **Step 2: Run existing tests to verify no regression** +Keep `getDeps` — still needed to extract dep names from package.json. +Keep `findSkillFiles`, `parseFrontmatter`. -Run: `pnpm vitest run tests/setup.test.ts` -Expected: All tests pass (no behavior change, just exported) +- [ ] **Step 3: Update scanner.ts call sites** -- [ ] **Step 3: Commit** +The `resolveDepDir` signature changed from 4 args to 2. Update `walkDeps` in scanner.ts: + +```typescript +// Before: +const depDir = resolveDepDir(depName, pkgDir, pkgName, resolutionRoots) + +// After: +const depDir = resolveDepDir(depName, pkgDir) +``` + +And `walkProjectDeps`: +```typescript +// Before: +const depDir = resolveDepDir(depName, projectRoot, depName, resolutionRoots) + +// After: +const depDir = resolveDepDir(depName, projectRoot) +``` + +Remove the `resolutionRoots` array and all code that builds/manages it. Remove `scanTarget`, `ensureGlobalNodeModules`, and the `nodeModules.global` scanning phases. The scanner simplifies to: + +1. Scan `node_modules` at project root for packages with `skills/` +2. Walk project deps +3. Walk known packages' deps +4. (New) Workspace scanning + +- [ ] **Step 4: Run all tests** + +Run: `pnpm vitest run tests/scanner.test.ts` +Expected: Most tests pass. The global node_modules tests will need updating since we removed that feature. If any tests relied on `listNodeModulesPackageDirs` or the old `resolveDepDir` signature, update them. + +- [ ] **Step 5: Commit** + +```bash +git add packages/intent/src/utils.ts packages/intent/src/scanner.ts packages/intent/tests/scanner.test.ts +git commit -m "refactor: replace resolveDepDir with createRequire-based resolution" +``` + +--- + +## Chunk 2: Workspace Scanning + +### Task 2: Export `resolveWorkspacePackages` from setup.ts + +**Files:** +- Modify: `packages/intent/src/setup.ts:483` + +- [ ] **Step 1: Make `resolveWorkspacePackages` exported** + +Change `function resolveWorkspacePackages(` to `export function resolveWorkspacePackages(` in setup.ts. + +- [ ] **Step 2: Commit** ```bash git add packages/intent/src/setup.ts git commit -m "refactor: export resolveWorkspacePackages from setup.ts" ``` -### Task 2: Write failing test for workspace scanning +### Task 3: Write failing tests for workspace scanning **Files:** - Modify: `packages/intent/tests/scanner.test.ts` -- [ ] **Step 1: Write a test that creates a pnpm-style monorepo and expects skills to be found from the root** - -Add this test to the `scanForIntents` describe block in `scanner.test.ts`: +- [ ] **Step 1: Write tests for pnpm-style workspace and transitive deps** ```typescript it('discovers skills in workspace package dependencies from monorepo root', async () => { - // Monorepo root with pnpm-workspace.yaml writeFileSync( join(root, 'pnpm-workspace.yaml'), 'packages:\n - packages/*\n', @@ -84,7 +197,6 @@ it('discovers skills in workspace package dependencies from monorepo root', asyn private: true, }) - // Workspace package that depends on a skills-enabled package const appDir = join(root, 'packages', 'app') createDir(root, 'packages', 'app') writeJson(join(appDir, 'package.json'), { @@ -93,8 +205,8 @@ it('discovers skills in workspace package dependencies from monorepo root', asyn dependencies: { '@tanstack/db': '0.5.0' }, }) - // The skills-enabled package installed in the workspace's node_modules createDir(appDir, 'node_modules', '@tanstack', 'db') + createDir(appDir, 'node_modules', '@tanstack', 'db', 'skills', 'db-core') const dbDir = join(appDir, 'node_modules', '@tanstack', 'db') writeJson(join(dbDir, 'package.json'), { name: '@tanstack/db', @@ -106,7 +218,6 @@ it('discovers skills in workspace package dependencies from monorepo root', asyn description: 'Core database concepts', }) - // Also create root node_modules (empty, typical for pnpm monorepos) createDir(root, 'node_modules') const result = await scanForIntents(root) @@ -114,12 +225,54 @@ it('discovers skills in workspace package dependencies from monorepo root', asyn expect(result.packages[0]!.name).toBe('@tanstack/db') expect(result.packages[0]!.skills).toHaveLength(1) }) -``` -Also add a test for `package.json` workspaces (npm/yarn/bun): +it('discovers transitive skills through workspace package deps', async () => { + writeFileSync( + join(root, 'pnpm-workspace.yaml'), + 'packages:\n - packages/*\n', + ) + writeJson(join(root, 'package.json'), { + name: 'monorepo', + private: true, + }) -```typescript -it('discovers skills in workspace package dependencies using package.json workspaces', async () => { + const appDir = join(root, 'packages', 'app') + createDir(root, 'packages', 'app') + writeJson(join(appDir, 'package.json'), { + name: '@monorepo/app', + version: '1.0.0', + dependencies: { 'wrapper': '1.0.0' }, + }) + + // wrapper has no skills, but depends on skills-pkg + createDir(appDir, 'node_modules', 'wrapper') + writeJson(join(appDir, 'node_modules', 'wrapper', 'package.json'), { + name: 'wrapper', + version: '1.0.0', + dependencies: { 'skills-pkg': '1.0.0' }, + }) + + // skills-pkg is a transitive dep (sibling in node_modules) + createDir(appDir, 'node_modules', 'skills-pkg') + createDir(appDir, 'node_modules', 'skills-pkg', 'skills', 'core') + writeJson(join(appDir, 'node_modules', 'skills-pkg', 'package.json'), { + name: 'skills-pkg', + version: '1.0.0', + intent: { version: 1, repo: 'test/skills', docs: 'https://example.com' }, + }) + writeSkillMd(join(appDir, 'node_modules', 'skills-pkg', 'skills', 'core'), { + name: 'core', + description: 'Core skill', + }) + + createDir(root, 'node_modules') + + const result = await scanForIntents(root) + expect(result.packages).toHaveLength(1) + expect(result.packages[0]!.name).toBe('skills-pkg') +}) + +it('discovers skills using package.json workspaces', async () => { writeJson(join(root, 'package.json'), { name: 'monorepo', private: true, @@ -134,7 +287,8 @@ it('discovers skills in workspace package dependencies using package.json worksp dependencies: { '@tanstack/db': '0.5.0' }, }) - // In npm/yarn/bun monorepos, deps are hoisted to root node_modules + createDir(root, 'node_modules', '@tanstack', 'db') + createDir(root, 'node_modules', '@tanstack', 'db', 'skills', 'db-core') const dbDir = join(root, 'node_modules', '@tanstack', 'db') writeJson(join(dbDir, 'package.json'), { name: '@tanstack/db', @@ -155,17 +309,15 @@ it('discovers skills in workspace package dependencies using package.json worksp - [ ] **Step 2: Run the tests to verify they fail** Run: `pnpm vitest run tests/scanner.test.ts -t "discovers skills in workspace"` -Expected: FAIL — the first test (pnpm-style with workspace package's own node_modules) should fail because the scanner doesn't look at workspace packages' node_modules. The second test (hoisted) may already pass since deps are in root node_modules. +Expected: FAIL — scanner doesn't scan workspace packages' node_modules yet. -### Task 3: Add workspace scanning phase to scanner.ts +### Task 4: Add workspace scanning phase to scanner.ts **Files:** - Modify: `packages/intent/src/scanner.ts` - [ ] **Step 1: Import workspace resolution functions** -Add to the imports at the top of `scanner.ts`: - ```typescript import { readWorkspacePatterns, @@ -173,66 +325,85 @@ import { } from './setup.js' ``` -- [ ] **Step 2: Add workspace scanning after Phase 1** +- [ ] **Step 2: Add workspace scanning phase** -After line 473 (`scanTarget(nodeModules.local)`), add the workspace scanning phase: +After the existing Phase 1 (`scanTarget`), and after the `walkDeps`/`walkKnownPackages`/`walkProjectDeps` function definitions, add workspace scanning before the first `walkKnownPackages()` call: ```typescript - // Phase 1b: In monorepos, scan workspace packages' node_modules. - // This handles pnpm monorepos where each workspace package has its own - // node_modules with symlinks to its specific dependencies. + // Phase 1b: In monorepos, discover workspace packages and walk their deps. + // This handles pnpm monorepos (workspace-specific node_modules) and ensures + // transitive skills packages are found through workspace package dependencies. const workspacePatterns = readWorkspacePatterns(projectRoot) if (workspacePatterns) { for (const wsDir of resolveWorkspacePackages(projectRoot, workspacePatterns)) { + // Scan workspace package's own node_modules for skills const wsNodeModules = join(wsDir, 'node_modules') - if (!existsSync(wsNodeModules)) continue + if (existsSync(wsNodeModules)) { + for (const dirPath of listNodeModulesPackageDirs(wsNodeModules)) { + tryRegister(dirPath, 'unknown') + } + } - for (const dirPath of listNodeModulesPackageDirs(wsNodeModules)) { - tryRegister(dirPath, 'unknown') + // Walk workspace package's deps to find transitive skills packages. + // createRequire-based resolveDepDir walks up from wsDir, so it finds + // deps hoisted to the monorepo root too. + const wsPkg = readPkgJson(wsDir) + if (wsPkg) { + const wsName = typeof wsPkg.name === 'string' ? wsPkg.name : 'unknown' + for (const depName of getDeps(wsPkg, true)) { + const depDir = resolveDepDir(depName, wsDir) + if (depDir && !walkVisited.has(depDir)) { + tryRegister(depDir, depName) + walkDeps(depDir, depName) + } + } } } } ``` -- [ ] **Step 3: Run the workspace tests to verify they pass** +Note: keep `listNodeModulesPackageDirs` for the top-level scan (Phase 1) and workspace node_modules scan — it's still the right tool for "scan everything in this directory." The `createRequire` change is for `resolveDepDir` (resolving a specific dep by name from a parent). -Run: `pnpm vitest run tests/scanner.test.ts -t "discovers skills in workspace"` +- [ ] **Step 3: Run workspace tests** + +Run: `pnpm vitest run tests/scanner.test.ts -t "workspace\|hoisted"` Expected: PASS -- [ ] **Step 4: Run all scanner tests to verify no regression** +- [ ] **Step 4: Run all scanner tests** Run: `pnpm vitest run tests/scanner.test.ts` -Expected: All tests pass +Expected: All pass - [ ] **Step 5: Commit** ```bash git add packages/intent/src/scanner.ts packages/intent/tests/scanner.test.ts -git commit -m "feat: scan workspace package dependencies from monorepo root" +git commit -m "feat: scan workspace package dependencies from monorepo root + +Uses readWorkspacePatterns to discover workspace packages, then scans their +node_modules and walks their dependency trees. createRequire-based +resolveDepDir naturally finds deps hoisted to the workspace root." ``` -### Task 4: Clean up Arborist spike +### Task 5: Clean up Arborist spike **Files:** - Delete: `packages/intent/src/scanner-arborist.ts` -- Modify: `packages/intent/package.json` (remove `@npmcli/arborist` devDependency) +- Modify: `packages/intent/package.json` -- [ ] **Step 1: Delete the spike file** +- [ ] **Step 1: Delete spike and remove dependency** ```bash rm packages/intent/src/scanner-arborist.ts +cd packages/intent && pnpm remove @npmcli/arborist ``` -- [ ] **Step 2: Remove @npmcli/arborist from devDependencies** - -Run: `cd packages/intent && pnpm remove @npmcli/arborist` - -- [ ] **Step 3: Run all tests** +- [ ] **Step 2: Run all tests** Run: `pnpm test:lib` -Expected: All tests pass +Expected: All pass -- [ ] **Step 4: Commit** +- [ ] **Step 3: Commit** ```bash git add packages/intent/src/scanner-arborist.ts packages/intent/package.json ../../pnpm-lock.yaml @@ -241,11 +412,9 @@ git commit -m "chore: remove arborist spike and dependency" --- -## Chunk 2: Integration Test Fixtures - -### Task 5: Create fixture packages +## Chunk 3: Integration Test Fixtures & Infrastructure -These are static packages that will be published to the local Verdaccio registry. Each has a `package.json` and optionally `skills/`. +### Task 6: Create fixture packages **Files:** - Create: `packages/intent/tests/fixtures/integration/skills-leaf/package.json` @@ -254,9 +423,9 @@ These are static packages that will be published to the local Verdaccio registry - Create: `packages/intent/tests/fixtures/integration/wrapper-2/package.json` - Create: `packages/intent/tests/fixtures/integration/wrapper-3/package.json` -- [ ] **Step 1: Create the skills-leaf package** +- [ ] **Step 1: Create all fixture packages** -`packages/intent/tests/fixtures/integration/skills-leaf/package.json`: +`skills-leaf/package.json`: ```json { "name": "@test-intent/skills-leaf", @@ -270,7 +439,7 @@ These are static packages that will be published to the local Verdaccio registry } ``` -`packages/intent/tests/fixtures/integration/skills-leaf/skills/core/SKILL.md`: +`skills-leaf/skills/core/SKILL.md`: ```markdown --- name: core @@ -283,60 +452,44 @@ type: core This is a test skill used by integration tests. ``` -- [ ] **Step 2: Create wrapper-1 (depends on skills-leaf)** - -`packages/intent/tests/fixtures/integration/wrapper-1/package.json`: +`wrapper-1/package.json`: ```json { "name": "@test-intent/wrapper-1", "version": "1.0.0", - "dependencies": { - "@test-intent/skills-leaf": "1.0.0" - } + "dependencies": { "@test-intent/skills-leaf": "1.0.0" } } ``` -- [ ] **Step 3: Create wrapper-2 (depends on wrapper-1)** - -`packages/intent/tests/fixtures/integration/wrapper-2/package.json`: +`wrapper-2/package.json`: ```json { "name": "@test-intent/wrapper-2", "version": "1.0.0", - "dependencies": { - "@test-intent/wrapper-1": "1.0.0" - } + "dependencies": { "@test-intent/wrapper-1": "1.0.0" } } ``` -- [ ] **Step 4: Create wrapper-3 (depends on wrapper-2)** - -`packages/intent/tests/fixtures/integration/wrapper-3/package.json`: +`wrapper-3/package.json`: ```json { "name": "@test-intent/wrapper-3", "version": "1.0.0", - "dependencies": { - "@test-intent/wrapper-2": "1.0.0" - } + "dependencies": { "@test-intent/wrapper-2": "1.0.0" } } ``` -- [ ] **Step 5: Commit** +- [ ] **Step 2: Commit** ```bash git add packages/intent/tests/fixtures/integration/ git commit -m "test: add integration test fixture packages" ``` ---- - -## Chunk 3: Integration Test Infrastructure - -### Task 6: Install Verdaccio and create test helpers +### Task 7: Install Verdaccio and create scaffold helpers **Files:** -- Modify: `packages/intent/package.json` (add verdaccio devDependency) +- Modify: `packages/intent/package.json` - Create: `packages/intent/tests/integration/scaffold.ts` - [ ] **Step 1: Install Verdaccio** @@ -345,18 +498,18 @@ git commit -m "test: add integration test fixture packages" cd packages/intent && pnpm add -D verdaccio @verdaccio/node-api ``` -- [ ] **Step 2: Create the scaffold helper module** +- [ ] **Step 2: Create scaffold.ts** `packages/intent/tests/integration/scaffold.ts`: ```typescript import { execSync, execFileSync } from 'node:child_process' import { - existsSync, mkdirSync, mkdtempSync, realpathSync, rmSync, + symlinkSync, writeFileSync, } from 'node:fs' import { tmpdir } from 'node:os' @@ -384,7 +537,6 @@ export async function startRegistry(): Promise { const port = 6000 + Math.floor(Math.random() * 4000) const configPath = join(storageDir, 'config.yaml') - // Write Verdaccio config file writeFileSync( configPath, [ @@ -407,9 +559,8 @@ export async function startRegistry(): Promise { return new Promise((resolve, reject) => { const server = app.listen(port, () => { - const url = `http://localhost:${port}` resolve({ - url, + url: `http://localhost:${port}`, stop: () => { server.close() rmSync(storageDir, { recursive: true, force: true }) @@ -425,12 +576,10 @@ export async function startRegistry(): Promise { // --------------------------------------------------------------------------- export function publishFixtures(registryUrl: string): void { - const packages = ['skills-leaf', 'wrapper-1', 'wrapper-2', 'wrapper-3'] - - for (const pkg of packages) { - const pkgDir = join(fixturesDir, pkg) + // Order matters: leaf first, then wrappers that depend on it + for (const pkg of ['skills-leaf', 'wrapper-1', 'wrapper-2', 'wrapper-3']) { execSync(`npm publish --registry ${registryUrl} --access public`, { - cwd: pkgDir, + cwd: join(fixturesDir, pkg), stdio: 'ignore', }) } @@ -444,9 +593,7 @@ export type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun' export type ProjectStructure = 'single' | 'monorepo-root' | 'monorepo-workspace' interface ScaffoldResult { - /** Root of the created project */ root: string - /** Directory to run the scanner from */ cwd: string } @@ -458,14 +605,14 @@ export function scaffoldProject(opts: { }): ScaffoldResult { const root = mkdtempSync(join(realTmpdir, `intent-integ-${opts.pm}-`)) - // Create lockfile marker so detectPackageManager works - const lockfileMap: Record = { + // Lockfile marker so detectPackageManager works + const lockfiles: Record = { npm: 'package-lock.json', pnpm: 'pnpm-lock.yaml', yarn: 'yarn.lock', bun: 'bun.lock', } - writeFileSync(join(root, lockfileMap[opts.pm]), '') + writeFileSync(join(root, lockfiles[opts.pm]), '') if (opts.structure === 'single') { writeJson(join(root, 'package.json'), { @@ -477,23 +624,17 @@ export function scaffoldProject(opts: { return { root, cwd: root } } - // Monorepo setup + // Monorepo writeJson(join(root, 'package.json'), { name: 'test-monorepo', private: true, ...(opts.pm !== 'pnpm' ? { workspaces: ['packages/*'] } : {}), }) if (opts.pm === 'pnpm') { - writeFileSync( - join(root, 'pnpm-workspace.yaml'), - 'packages:\n - packages/*\n', - ) + writeFileSync(join(root, 'pnpm-workspace.yaml'), 'packages:\n - packages/*\n') } if (opts.pm === 'yarn') { - writeFileSync( - join(root, '.yarnrc.yml'), - 'nodeLinker: node-modules\n', - ) + writeFileSync(join(root, '.yarnrc.yml'), 'nodeLinker: node-modules\n') } const appDir = join(root, 'packages', 'app') @@ -513,25 +654,21 @@ export function scaffoldProject(opts: { } function install(dir: string, pm: PackageManager, registryUrl: string): void { - const registryArg = `--registry=${registryUrl}` const env = { ...process.env, npm_config_registry: registryUrl } + const reg = `--registry=${registryUrl}` switch (pm) { case 'npm': - execSync(`npm install ${registryArg}`, { cwd: dir, stdio: 'ignore', env }) + execSync(`npm install ${reg}`, { cwd: dir, stdio: 'ignore', env }) break case 'pnpm': - execSync(`pnpm install ${registryArg} --no-frozen-lockfile`, { - cwd: dir, - stdio: 'ignore', - env, - }) + execSync(`pnpm install ${reg} --no-frozen-lockfile`, { cwd: dir, stdio: 'ignore', env }) break case 'yarn': - execSync(`yarn install ${registryArg}`, { cwd: dir, stdio: 'ignore', env }) + execSync(`yarn install ${reg}`, { cwd: dir, stdio: 'ignore', env }) break case 'bun': - execSync(`bun install ${registryArg}`, { cwd: dir, stdio: 'ignore', env }) + execSync(`bun install ${reg}`, { cwd: dir, stdio: 'ignore', env }) break } } @@ -547,14 +684,13 @@ export interface CliResult { parsed: any } -export async function runScanner( +export function runScanner( cwd: string, method: 'direct' | 'symlink' = 'direct', -): Promise { +): CliResult { let binPath = cliPath if (method === 'symlink') { - const { symlinkSync } = await import('node:fs') const linkDir = mkdtempSync(join(realTmpdir, 'intent-link-')) const linkPath = join(linkDir, 'intent-cli.mjs') symlinkSync(cliPath, linkPath) @@ -567,8 +703,7 @@ export async function runScanner( encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], }) - const parsed = JSON.parse(stdout) - return { stdout, stderr: '', exitCode: 0, parsed } + return { stdout, stderr: '', exitCode: 0, parsed: JSON.parse(stdout) } } catch (err: any) { return { stdout: err.stdout ?? '', @@ -589,14 +724,12 @@ function writeJson(filePath: string, data: unknown): void { } ``` -- [ ] **Step 3: Exclude integration tests from `test:lib` and add `test:integration` script** +- [ ] **Step 3: Exclude integration tests from `test:lib`, add `test:integration`** -In `packages/intent/package.json`, update `scripts`: +In `packages/intent/package.json`, update scripts: ```json -"scripts": { - "test:lib": "vitest run --exclude tests/integration/**", - "test:integration": "vitest run tests/integration/" -} +"test:lib": "vitest run --exclude tests/integration/**", +"test:integration": "vitest run tests/integration/" ``` - [ ] **Step 4: Commit** @@ -608,18 +741,14 @@ git commit -m "test: add Verdaccio-based integration test infrastructure" --- -## Chunk 4: Integration Tests +## Chunk 4: Integration Test Grid -### Task 7: Write the integration test grid +### Task 8: Write the integration test matrix **Files:** - Create: `packages/intent/tests/integration/scanner-integration.test.ts` -This test file uses `describe.each` to create the full matrix: 4 package managers × 3 project structures × 4 dependency depths. - -- [ ] **Step 1: Write the integration test file** - -`packages/intent/tests/integration/scanner-integration.test.ts`: +- [ ] **Step 1: Write the test file** ```typescript import { rmSync } from 'node:fs' @@ -632,25 +761,17 @@ import { startRegistry, } from './scaffold.js' -// These tests require npm, pnpm, yarn, and bun to be installed. -// They create real projects and install real packages from a local registry. -// Timeout is generous because installs can be slow. - const PACKAGE_MANAGERS: Array = ['npm', 'pnpm', 'yarn', 'bun'] const STRUCTURES: Array = [ 'single', 'monorepo-root', 'monorepo-workspace', ] -const DEPENDENCY_CHAINS: Array<{ - label: string - dep: string - transitiveDepth: number -}> = [ - { label: 'direct', dep: '@test-intent/skills-leaf', transitiveDepth: 0 }, - { label: 'transitive+1', dep: '@test-intent/wrapper-1', transitiveDepth: 1 }, - { label: 'transitive+2', dep: '@test-intent/wrapper-2', transitiveDepth: 2 }, - { label: 'transitive+3', dep: '@test-intent/wrapper-3', transitiveDepth: 3 }, +const DEPENDENCY_CHAINS: Array<{ label: string; dep: string }> = [ + { label: 'direct', dep: '@test-intent/skills-leaf' }, + { label: 'transitive+1', dep: '@test-intent/wrapper-1' }, + { label: 'transitive+2', dep: '@test-intent/wrapper-2' }, + { label: 'transitive+3', dep: '@test-intent/wrapper-3' }, ] let registry: Registry @@ -670,47 +791,36 @@ afterAll(() => { describe.each(PACKAGE_MANAGERS)('package manager: %s', (pm) => { describe.each(STRUCTURES)('structure: %s', (structure) => { - describe.each(DEPENDENCY_CHAINS)( - 'dependency: $label', - ({ dep }) => { - it( - 'discovers @test-intent/skills-leaf and its core skill', - () => { - const { root, cwd } = scaffoldProject({ - pm, - structure, - dependency: dep, - registryUrl: registry.url, - }) - tempDirs.push(root) - - const result = await runScanner(cwd) - - expect(result.exitCode).toBe(0) - expect(result.parsed).toBeTruthy() - expect(result.parsed.packages).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - name: '@test-intent/skills-leaf', - version: '1.0.0', - skills: expect.arrayContaining([ - expect.objectContaining({ - name: 'core', - type: 'core', - }), - ]), - }), + describe.each(DEPENDENCY_CHAINS)('dependency: $label', ({ dep }) => { + it('discovers @test-intent/skills-leaf and its core skill', () => { + const { root, cwd } = scaffoldProject({ + pm, + structure, + dependency: dep, + registryUrl: registry.url, + }) + tempDirs.push(root) + + const result = runScanner(cwd) + + expect(result.exitCode).toBe(0) + expect(result.parsed).toBeTruthy() + expect(result.parsed.packages).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + name: '@test-intent/skills-leaf', + version: '1.0.0', + skills: expect.arrayContaining([ + expect.objectContaining({ name: 'core', type: 'core' }), ]), - ) - }, - 60_000, + }), + ]), ) - }, - ) + }, 60_000) + }) }) }) -// Test that symlink invocation also works (the isMain bug fix) describe('symlink invocation', () => { it('finds skills when CLI is invoked through a symlink', () => { const { root, cwd } = scaffoldProject({ @@ -721,7 +831,7 @@ describe('symlink invocation', () => { }) tempDirs.push(root) - const result = await runScanner(cwd, 'symlink') + const result = runScanner(cwd, 'symlink') expect(result.exitCode).toBe(0) expect(result.parsed.packages).toHaveLength(1) @@ -730,91 +840,67 @@ describe('symlink invocation', () => { }) ``` -- [ ] **Step 2: Build the CLI first (integration tests use the built binary)** - -Run: `pnpm run build` - -- [ ] **Step 3: Run the integration tests** - -Run: `pnpm vitest run tests/integration/scanner-integration.test.ts --test-timeout=120000` - -Expected: Tests may take a while (real installs). Debug any failures — likely candidates: -- Yarn may need `.yarnrc.yml` with `nodeLinker: node-modules` in the scaffolded project -- Bun may need special handling -- Transitive depth tests may fail if the scanner doesn't walk deep enough (existing behavior, not a new bug) - -Fix any issues in `scaffold.ts` or `scanner.ts` as they arise. +- [ ] **Step 2: Build CLI and run integration tests** -- [ ] **Step 4: Run the full test suite** +```bash +pnpm run build +pnpm test:integration +``` -Run: `pnpm test:lib` -Expected: All tests pass (both existing unit tests and new integration tests) +Expected: 4 PMs × 3 structures × 4 depths = 48 tests + 1 symlink test = 49 total. Debug failures as they arise (Task 9). -- [ ] **Step 5: Commit** +- [ ] **Step 3: Commit** ```bash git add packages/intent/tests/integration/scanner-integration.test.ts -git commit -m "test: add cross-package-manager integration test grid" +git commit -m "test: add cross-package-manager integration test grid (49 scenarios)" ``` -### Task 8: Handle edge cases discovered during integration testing - -This task is intentionally open-ended. During Task 7, some test scenarios may fail revealing real scanner bugs. Common expected issues: - -1. **Yarn classic** may need `nodeLinker: node-modules` in `.yarnrc.yml` — add this to `scaffoldProject` when `pm === 'yarn'` -2. **pnpm monorepo transitive deps** — workspace package's transitive deps may not be discovered if the scanner only scans the workspace's direct `node_modules` but doesn't walk deps from there. Solution: after scanning workspace node_modules, also call `walkDeps` on each discovered package. -3. **Bun monorepo workspace detection** — bun uses `package.json` workspaces, should work with existing code - -- [ ] **Step 1: Fix any failing test scenarios** - -For each failure: identify root cause, fix in scanner.ts or scaffold.ts, verify fix. +### Task 9: Fix edge cases from integration testing -- [ ] **Step 2: Run full test suite** +Debug and fix failures. Common issues: +1. **Yarn Berry PnP** — `.yarnrc.yml` with `nodeLinker: node-modules` already added in scaffold +2. **pnpm transitive deps** — `createRequire` + workspace dep walking should handle this; if not, debug the resolution chain +3. **Bun workspaces** — uses `package.json` workspaces, should work -Run: `pnpm test:lib` -Expected: All tests pass - -- [ ] **Step 3: Commit fixes** - -```bash -git add -A -git commit -m "fix: address integration test edge cases" -``` +- [ ] **Step 1: Fix failures, run `pnpm test:lib && pnpm test:integration`** +- [ ] **Step 2: Commit fixes** --- ## Chunk 5: Final Verification -### Task 9: End-to-end verification against real monorepo +### Task 10: End-to-end against real monorepo -- [ ] **Step 1: Build the CLI** +- [ ] **Step 1: Build CLI** -Run: `pnpm run build` +```bash +pnpm run build +``` -- [ ] **Step 2: Test from the monorepo root (the new workspace scanning)** +- [ ] **Step 2: Test from monorepo root** ```bash cd /Users/kylemathews/programs/darix/.worktrees/ts-darix-runtime node /Users/kylemathews/programs/intent/packages/intent/dist/cli.mjs list ``` -Expected: Should find `@tanstack/db` with 6 skills (new workspace scanning discovers it through workspace packages' node_modules) +Expected: `@tanstack/db` with 6 skills (workspace scanning) -- [ ] **Step 4: Test from the workspace package subdir** +- [ ] **Step 3: Test from workspace package subdir** ```bash cd /Users/kylemathews/programs/darix/.worktrees/ts-darix-runtime/packages/ts-darix-runtime node /Users/kylemathews/programs/intent/packages/intent/dist/cli.mjs list ``` -Expected: Should find `@tanstack/db` with 6 skills (was already working after the isMain fix) +Expected: `@tanstack/db` with 6 skills (createRequire walks up to root node_modules) -- [ ] **Step 5: Run full test suite one final time** +- [ ] **Step 4: Run `pnpm test:lib && pnpm test:integration`** -Run: `pnpm test:lib` -Expected: All tests pass +Expected: All unit + integration tests pass -- [ ] **Step 6: Commit any remaining changes** +- [ ] **Step 5: Final commit** ```bash git add -A From b531999c8642f7f5d35296f49f8a96f43dc90297 Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Sat, 14 Mar 2026 10:38:08 -0600 Subject: [PATCH 03/17] =?UTF-8?q?docs:=20fix=20plan=20per=20round=202=20re?= =?UTF-8?q?view=20=E2=80=94=20keep=20global=20scanning,=20add=20tryRegiste?= =?UTF-8?q?r,=20fix=20cwd?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: 1. Keep detectGlobalNodeModules and global scanning phase (createRequire doesn't resolve global installs) 2. Add tryRegister(depDir, depName) to walkProjectDeps so direct skills deps are registered even when not found by Phase 1's scanTarget 3. Specify cd packages/intent for all pnpm/vitest commands 4. Fix file table and notes to consistently say which functions are kept Co-Authored-By: Claude Opus 4.6 (1M context) --- ...14-workspace-scanning-integration-tests.md | 67 ++++++++++++------- 1 file changed, 43 insertions(+), 24 deletions(-) diff --git a/docs/superpowers/plans/2026-03-14-workspace-scanning-integration-tests.md b/docs/superpowers/plans/2026-03-14-workspace-scanning-integration-tests.md index 21fb38c..00e536f 100644 --- a/docs/superpowers/plans/2026-03-14-workspace-scanning-integration-tests.md +++ b/docs/superpowers/plans/2026-03-14-workspace-scanning-integration-tests.md @@ -14,9 +14,9 @@ | File | Action | Responsibility | |------|--------|----------------| -| `packages/intent/src/utils.ts` | Modify | Replace `resolveDepDir` with `createRequire`-based resolution, remove `listNodeModulesPackageDirs`, `getDeps`, `detectGlobalNodeModules` | +| `packages/intent/src/utils.ts` | Modify | Replace `resolveDepDir` with `createRequire`-based resolution. Keep `listNodeModulesPackageDirs` (used by Phase 1 + workspace scan), `getDeps` (used to extract dep names), `detectGlobalNodeModules` (global install support) | | `packages/intent/src/setup.ts` | Modify | Export `resolveWorkspacePackages` | -| `packages/intent/src/scanner.ts` | Modify | Use new `resolveDepDir`, add workspace scanning phase, simplify by removing multi-phase scanning | +| `packages/intent/src/scanner.ts` | Modify | Use new `resolveDepDir` (2-arg), add workspace scanning phase, add `tryRegister` to `walkProjectDeps`. Keep existing Phase 1 (`scanTarget`), global scanning, and `resolutionRoots` for `listNodeModulesPackageDirs` | | `packages/intent/tests/scanner.test.ts` | Modify | Add unit tests for workspace scanning | | `packages/intent/tests/fixtures/integration/skills-leaf/package.json` | Create | Fixture: package with skills | | `packages/intent/tests/fixtures/integration/skills-leaf/skills/core/SKILL.md` | Create | Fixture: skill file | @@ -80,9 +80,11 @@ it('finds hoisted deps when scanning from a workspace package subdir', async () }) ``` -Run: `pnpm vitest run tests/scanner.test.ts -t "finds hoisted deps"` +Run: `cd packages/intent && pnpm vitest run tests/scanner.test.ts -t "finds hoisted deps"` Expected: FAIL — current `resolveDepDir` only checks explicit `resolutionRoots`, not upward walk. +> **Note:** All `pnpm vitest` and `pnpm test:*` commands in this plan should be run from `packages/intent/`, not the repo root. + - [ ] **Step 2: Replace `resolveDepDir` in utils.ts** Replace the existing `resolveDepDir` function (lines 146-199 of `utils.ts`) with: @@ -112,12 +114,11 @@ export function resolveDepDir( } ``` -Also remove these functions that are no longer needed: -- `listNodeModulesPackageDirs` (scanner will scan via workspace resolution + dep walking instead) -- `detectGlobalNodeModules` (no longer used — `createRequire` finds global installs naturally) - -Keep `getDeps` — still needed to extract dep names from package.json. -Keep `findSkillFiles`, `parseFrontmatter`. +Keep all other exported functions — they are still used: +- `listNodeModulesPackageDirs` — used by Phase 1 scan and workspace node_modules scan +- `getDeps` — used to extract dep names from package.json +- `detectGlobalNodeModules` — used for `INTENT_GLOBAL_NODE_MODULES` and global install discovery (`createRequire` does NOT resolve global installs) +- `findSkillFiles`, `parseFrontmatter` - [ ] **Step 3: Update scanner.ts call sites** @@ -140,17 +141,35 @@ const depDir = resolveDepDir(depName, projectRoot, depName, resolutionRoots) const depDir = resolveDepDir(depName, projectRoot) ``` -Remove the `resolutionRoots` array and all code that builds/manages it. Remove `scanTarget`, `ensureGlobalNodeModules`, and the `nodeModules.global` scanning phases. The scanner simplifies to: +Keep all existing scanner phases — Phase 1 (`scanTarget`), Phase 2 (`walkKnownPackages`), Phase 3 (`walkProjectDeps`), and global scanning. The only changes are: + +1. `resolveDepDir` calls go from 4 args to 2 +2. `walkProjectDeps` gets a `tryRegister` call (see Step 3b) +3. A new workspace scanning phase is added (Task 4) + +- [ ] **Step 3b: Add `tryRegister` to `walkProjectDeps`** + +In `walkProjectDeps`, the current code calls `walkDeps(depDir, depName)` but never `tryRegister(depDir, depName)`. This means a direct skills-package dependency of the project is only discovered through Phase 1's `scanTarget`. When Phase 1 can't find it (e.g., hoisted layout from workspace subdir), it's never registered. + +In `scanner.ts`, find the `walkProjectDeps` function and change: -1. Scan `node_modules` at project root for packages with `skills/` -2. Walk project deps -3. Walk known packages' deps -4. (New) Workspace scanning +```typescript +// Before (scanner.ts ~line 535): +if (depDir && !walkVisited.has(depDir)) { + walkDeps(depDir, depName) +} + +// After: +if (depDir && !walkVisited.has(depDir)) { + tryRegister(depDir, depName) + walkDeps(depDir, depName) +} +``` - [ ] **Step 4: Run all tests** -Run: `pnpm vitest run tests/scanner.test.ts` -Expected: Most tests pass. The global node_modules tests will need updating since we removed that feature. If any tests relied on `listNodeModulesPackageDirs` or the old `resolveDepDir` signature, update them. +Run: `cd packages/intent && pnpm vitest run` +Expected: All existing tests pass (no behavioral change to global scanning, Phase 1, etc.). The new hoisted-deps test from Step 1 now passes. - [ ] **Step 5: Commit** @@ -308,7 +327,7 @@ it('discovers skills using package.json workspaces', async () => { - [ ] **Step 2: Run the tests to verify they fail** -Run: `pnpm vitest run tests/scanner.test.ts -t "discovers skills in workspace"` +Run: `cd packages/intent && pnpm vitest run tests/scanner.test.ts -t "discovers skills in workspace"` Expected: FAIL — scanner doesn't scan workspace packages' node_modules yet. ### Task 4: Add workspace scanning phase to scanner.ts @@ -362,16 +381,16 @@ After the existing Phase 1 (`scanTarget`), and after the `walkDeps`/`walkKnownPa } ``` -Note: keep `listNodeModulesPackageDirs` for the top-level scan (Phase 1) and workspace node_modules scan — it's still the right tool for "scan everything in this directory." The `createRequire` change is for `resolveDepDir` (resolving a specific dep by name from a parent). +**Important:** All existing scanner phases are preserved — Phase 1 (`scanTarget` with `listNodeModulesPackageDirs`), Phase 2/3 (`walkKnownPackages`/`walkProjectDeps`), and global scanning (`ensureGlobalNodeModules`). The only changes to the scanner are: (a) `resolveDepDir` calls use 2 args instead of 4, (b) `tryRegister` added to `walkProjectDeps` (Task 1 Step 3b), and (c) this new workspace phase. - [ ] **Step 3: Run workspace tests** -Run: `pnpm vitest run tests/scanner.test.ts -t "workspace\|hoisted"` +Run: `cd packages/intent && pnpm vitest run tests/scanner.test.ts -t "workspace\|hoisted"` Expected: PASS - [ ] **Step 4: Run all scanner tests** -Run: `pnpm vitest run tests/scanner.test.ts` +Run: `cd packages/intent && pnpm vitest run tests/scanner.test.ts` Expected: All pass - [ ] **Step 5: Commit** @@ -400,7 +419,7 @@ cd packages/intent && pnpm remove @npmcli/arborist - [ ] **Step 2: Run all tests** -Run: `pnpm test:lib` +Run: `cd packages/intent && pnpm test:lib` Expected: All pass - [ ] **Step 3: Commit** @@ -844,7 +863,7 @@ describe('symlink invocation', () => { ```bash pnpm run build -pnpm test:integration +cd packages/intent && pnpm test:integration ``` Expected: 4 PMs × 3 structures × 4 depths = 48 tests + 1 symlink test = 49 total. Debug failures as they arise (Task 9). @@ -863,7 +882,7 @@ Debug and fix failures. Common issues: 2. **pnpm transitive deps** — `createRequire` + workspace dep walking should handle this; if not, debug the resolution chain 3. **Bun workspaces** — uses `package.json` workspaces, should work -- [ ] **Step 1: Fix failures, run `pnpm test:lib && pnpm test:integration`** +- [ ] **Step 1: Fix failures, run `cd packages/intent && pnpm test:lib && pnpm test:integration`** - [ ] **Step 2: Commit fixes** --- @@ -896,7 +915,7 @@ node /Users/kylemathews/programs/intent/packages/intent/dist/cli.mjs list Expected: `@tanstack/db` with 6 skills (createRequire walks up to root node_modules) -- [ ] **Step 4: Run `pnpm test:lib && pnpm test:integration`** +- [ ] **Step 4: Run `cd packages/intent && pnpm test:lib && pnpm test:integration`** Expected: All unit + integration tests pass From fd02ab6ab1947fa7c9422b6ba25675ce43b07790 Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Sat, 14 Mar 2026 11:43:00 -0600 Subject: [PATCH 04/17] feat: replace resolveDepDir with createRequire-based resolution Use Node's built-in createRequire for dependency resolution instead of the hand-rolled 3-layer strategy. This naturally handles hoisted deps in monorepo workspace packages by walking up the directory tree, which the old approach missed. Also adds tryRegister in walkProjectDeps so direct skills-package dependencies are found, and removes the now-unused resolutionRoots array. Co-Authored-By: Claude Opus 4.6 (1M context) --- packages/intent/src/scanner.ts | 20 ++------- packages/intent/src/utils.ts | 58 ++++++--------------------- packages/intent/tests/scanner.test.ts | 41 ++++++++++++++++++- 3 files changed, 54 insertions(+), 65 deletions(-) diff --git a/packages/intent/src/scanner.ts b/packages/intent/src/scanner.ts index 64070c3..5fd398b 100644 --- a/packages/intent/src/scanner.ts +++ b/packages/intent/src/scanner.ts @@ -337,8 +337,6 @@ export async function scanForIntents(root?: string): Promise { : undefined, }, } - const resolutionRoots = [nodeModulesDir] - // Track registered package names to avoid duplicates across phases const packageIndexes = new Map() const packageJsonCache = new Map | null>() @@ -370,14 +368,6 @@ export async function scanForIntents(root?: string): Promise { : false } - if ( - nodeModules.global.exists && - nodeModules.global.path && - nodeModules.global.path !== nodeModulesDir && - !resolutionRoots.includes(nodeModules.global.path) - ) { - resolutionRoots.push(nodeModules.global.path) - } } function readPkgJson(dirPath: string): Record | null { @@ -490,7 +480,7 @@ export async function scanForIntents(root?: string): Promise { } for (const depName of getDeps(pkgJson)) { - const depDir = resolveDepDir(depName, pkgDir, pkgName, resolutionRoots) + const depDir = resolveDepDir(depName, pkgDir) if (!depDir || walkVisited.has(depDir)) continue tryRegister(depDir, depName) @@ -526,13 +516,9 @@ export async function scanForIntents(root?: string): Promise { if (!projectPkg) return for (const depName of getDeps(projectPkg, true)) { - const depDir = resolveDepDir( - depName, - projectRoot, - depName, - resolutionRoots, - ) + const depDir = resolveDepDir(depName, projectRoot) if (depDir && !walkVisited.has(depDir)) { + tryRegister(depDir, depName) walkDeps(depDir, depName) } } diff --git a/packages/intent/src/utils.ts b/packages/intent/src/utils.ts index d727ddd..6006793 100644 --- a/packages/intent/src/utils.ts +++ b/packages/intent/src/utils.ts @@ -3,9 +3,9 @@ import { existsSync, readFileSync, readdirSync, - realpathSync, type Dirent, } from 'node:fs' +import { createRequire } from 'node:module' import { dirname, join } from 'node:path' import { parse as parseYaml } from 'yaml' @@ -144,58 +144,24 @@ export function detectGlobalNodeModules(packageManager: string): { } /** - * Resolve the directory of a dependency by name. First checks the top-level - * node_modules (hoisted layout — npm, yarn, bun), then resolves through the - * parent package's real path to handle pnpm's virtual store layout where - * transitive deps are siblings in the .pnpm virtual store node_modules. + * Resolve the directory of a dependency by name. Uses Node's built-in + * module resolution via createRequire, which handles: + * - Hoisted layouts (npm, yarn, bun) — walks up directory tree + * - pnpm symlinked virtual store — follows symlinks + * - Workspace packages — finds deps at workspace root + * - Nested node_modules — standard Node resolution */ export function resolveDepDir( depName: string, parentDir: string, - parentName: string, - nodeModulesDirs: string | Array, ): string | null { - if (!parentName) return null - - const roots = Array.isArray(nodeModulesDirs) - ? nodeModulesDirs - : [nodeModulesDirs] - - // 1. Top-level (hoisted) - for (const nodeModulesDir of roots) { - const topLevel = join(nodeModulesDir, depName) - if (existsSync(join(topLevel, 'package.json'))) return topLevel - } - - // 2. Resolve nested installs under the parent package (npm/pnpm/bun) - const nestedNodeModules = join(parentDir, 'node_modules', depName) - if (existsSync(join(nestedNodeModules, 'package.json'))) { - return nestedNodeModules - } - - // 3. Resolve through parent's real path (pnpm virtual store) try { - const realParent = realpathSync(parentDir) - const segments = parentName.split('/').length - let nmDir = realParent - for (let i = 0; i < segments; i++) { - nmDir = dirname(nmDir) - } - const nested = join(nmDir, depName) - if (existsSync(join(nested, 'package.json'))) return nested - } catch (err: unknown) { - const code = - err && typeof err === 'object' && 'code' in err - ? (err as NodeJS.ErrnoException).code - : undefined - if (code !== 'ENOENT' && code !== 'ENOTDIR') { - console.warn( - `Warning: could not resolve ${depName} from ${parentDir}: ${err instanceof Error ? err.message : String(err)}`, - ) - } + const require = createRequire(join(parentDir, 'package.json')) + const pkgJsonPath = require.resolve(join(depName, 'package.json')) + return dirname(pkgJsonPath) + } catch { + return null } - - return null } /** diff --git a/packages/intent/tests/scanner.test.ts b/packages/intent/tests/scanner.test.ts index 1be71c3..e54a924 100644 --- a/packages/intent/tests/scanner.test.ts +++ b/packages/intent/tests/scanner.test.ts @@ -1,6 +1,7 @@ import { mkdirSync, mkdtempSync, + realpathSync, rmSync, symlinkSync, writeFileSync, @@ -39,8 +40,8 @@ let globalRoot: string let previousGlobalNodeModules: string | undefined beforeEach(() => { - root = mkdtempSync(join(tmpdir(), 'intent-test-')) - globalRoot = mkdtempSync(join(tmpdir(), 'intent-global-test-')) + root = realpathSync(mkdtempSync(join(tmpdir(), 'intent-test-'))) + globalRoot = realpathSync(mkdtempSync(join(tmpdir(), 'intent-global-test-'))) previousGlobalNodeModules = process.env.INTENT_GLOBAL_NODE_MODULES delete process.env.INTENT_GLOBAL_NODE_MODULES }) @@ -480,6 +481,42 @@ describe('scanForIntents', () => { expect(result.packages[0]!.packageRoot).toBe(stableDir) }) + it('finds hoisted deps when scanning from a workspace package subdir', async () => { + // Simulate npm/yarn/bun monorepo: deps hoisted to root node_modules + writeJson(join(root, 'package.json'), { + name: 'monorepo', + private: true, + workspaces: ['packages/*'], + }) + + const appDir = join(root, 'packages', 'app') + createDir(root, 'packages', 'app') + writeJson(join(appDir, 'package.json'), { + name: '@monorepo/app', + version: '1.0.0', + dependencies: { '@tanstack/db': '0.5.0' }, + }) + + // Dep is hoisted to root, NOT in app's node_modules + createDir(root, 'node_modules', '@tanstack', 'db') + createDir(root, 'node_modules', '@tanstack', 'db', 'skills', 'db-core') + const dbDir = join(root, 'node_modules', '@tanstack', 'db') + writeJson(join(dbDir, 'package.json'), { + name: '@tanstack/db', + version: '0.5.0', + intent: { version: 1, repo: 'TanStack/db', docs: 'https://db.tanstack.com' }, + }) + writeSkillMd(join(dbDir, 'skills', 'db-core'), { + name: 'db-core', + description: 'Core database concepts', + }) + + // Scan from the workspace package subdir (not root) + const result = await scanForIntents(appDir) + expect(result.packages).toHaveLength(1) + expect(result.packages[0]!.name).toBe('@tanstack/db') + }) + it('prefers valid semver versions over invalid ones at the same depth', async () => { writeJson(join(root, 'package.json'), { name: 'app', From 33d75ed2b15067c7bb7c9d30cb37ec17983cab12 Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Sat, 14 Mar 2026 11:44:47 -0600 Subject: [PATCH 05/17] refactor: export resolveWorkspacePackages from setup.ts --- packages/intent/src/setup.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/intent/src/setup.ts b/packages/intent/src/setup.ts index dd99431..256895e 100644 --- a/packages/intent/src/setup.ts +++ b/packages/intent/src/setup.ts @@ -480,7 +480,7 @@ export function readWorkspacePatterns(root: string): Array | null { * Handles simple patterns like "packages/*" and "packages/**". * Each resolved directory must contain a package.json. */ -function resolveWorkspacePackages( +export function resolveWorkspacePackages( root: string, patterns: Array, ): Array { From 0477d9995a9602120a69bb93ce83964ba750f660 Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Sat, 14 Mar 2026 11:47:21 -0600 Subject: [PATCH 06/17] feat: add workspace scanning phase to discover skills in monorepo packages Adds Phase 1b to scanForIntents that reads workspace patterns (from pnpm-workspace.yaml or package.json#workspaces), resolves workspace package directories, and scans each package's node_modules and dependency tree for skills packages. This handles pnpm monorepos where each workspace package has its own node_modules with symlinks, as well as transitive skills discovered through workspace deps. Includes 3 new tests: pnpm-style workspace, transitive workspace deps, and package.json workspaces. Co-Authored-By: Claude Opus 4.6 (1M context) --- packages/intent/src/scanner.ts | 34 ++++++++ packages/intent/tests/scanner.test.ts | 118 ++++++++++++++++++++++++++ 2 files changed, 152 insertions(+) diff --git a/packages/intent/src/scanner.ts b/packages/intent/src/scanner.ts index 5fd398b..2b104aa 100644 --- a/packages/intent/src/scanner.ts +++ b/packages/intent/src/scanner.ts @@ -7,6 +7,10 @@ import { parseFrontmatter, resolveDepDir, } from './utils.js' +import { + readWorkspacePatterns, + resolveWorkspacePackages, +} from './setup.js' import type { InstalledVariant, IntentConfig, @@ -524,6 +528,36 @@ export async function scanForIntents(root?: string): Promise { } } + // Phase 1b: In monorepos, discover workspace packages and walk their deps. + // This handles pnpm monorepos (workspace-specific node_modules) and ensures + // transitive skills packages are found through workspace package dependencies. + const workspacePatterns = readWorkspacePatterns(projectRoot) + if (workspacePatterns) { + for (const wsDir of resolveWorkspacePackages(projectRoot, workspacePatterns)) { + // Scan workspace package's own node_modules for skills + const wsNodeModules = join(wsDir, 'node_modules') + if (existsSync(wsNodeModules)) { + for (const dirPath of listNodeModulesPackageDirs(wsNodeModules)) { + tryRegister(dirPath, 'unknown') + } + } + + // Walk workspace package's deps to find transitive skills packages. + // createRequire-based resolveDepDir walks up from wsDir, so it finds + // deps hoisted to the monorepo root too. + const wsPkg = readPkgJson(wsDir) + if (wsPkg) { + for (const depName of getDeps(wsPkg, true)) { + const depDir = resolveDepDir(depName, wsDir) + if (depDir && !walkVisited.has(depDir)) { + tryRegister(depDir, depName) + walkDeps(depDir, depName) + } + } + } + } + } + walkKnownPackages() walkProjectDeps() diff --git a/packages/intent/tests/scanner.test.ts b/packages/intent/tests/scanner.test.ts index e54a924..bde3918 100644 --- a/packages/intent/tests/scanner.test.ts +++ b/packages/intent/tests/scanner.test.ts @@ -517,6 +517,124 @@ describe('scanForIntents', () => { expect(result.packages[0]!.name).toBe('@tanstack/db') }) + it('discovers skills in workspace package dependencies from monorepo root', async () => { + writeFileSync( + join(root, 'pnpm-workspace.yaml'), + 'packages:\n - packages/*\n', + ) + writeJson(join(root, 'package.json'), { + name: 'monorepo', + private: true, + }) + + const appDir = join(root, 'packages', 'app') + createDir(root, 'packages', 'app') + writeJson(join(appDir, 'package.json'), { + name: '@monorepo/app', + version: '1.0.0', + dependencies: { '@tanstack/db': '0.5.0' }, + }) + + createDir(appDir, 'node_modules', '@tanstack', 'db') + createDir(appDir, 'node_modules', '@tanstack', 'db', 'skills', 'db-core') + const dbDir = join(appDir, 'node_modules', '@tanstack', 'db') + writeJson(join(dbDir, 'package.json'), { + name: '@tanstack/db', + version: '0.5.0', + intent: { version: 1, repo: 'TanStack/db', docs: 'https://db.tanstack.com' }, + }) + writeSkillMd(join(dbDir, 'skills', 'db-core'), { + name: 'db-core', + description: 'Core database concepts', + }) + + createDir(root, 'node_modules') + + const result = await scanForIntents(root) + expect(result.packages).toHaveLength(1) + expect(result.packages[0]!.name).toBe('@tanstack/db') + expect(result.packages[0]!.skills).toHaveLength(1) + }) + + it('discovers transitive skills through workspace package deps', async () => { + writeFileSync( + join(root, 'pnpm-workspace.yaml'), + 'packages:\n - packages/*\n', + ) + writeJson(join(root, 'package.json'), { + name: 'monorepo', + private: true, + }) + + const appDir = join(root, 'packages', 'app') + createDir(root, 'packages', 'app') + writeJson(join(appDir, 'package.json'), { + name: '@monorepo/app', + version: '1.0.0', + dependencies: { 'wrapper': '1.0.0' }, + }) + + // wrapper has no skills, but depends on skills-pkg + createDir(appDir, 'node_modules', 'wrapper') + writeJson(join(appDir, 'node_modules', 'wrapper', 'package.json'), { + name: 'wrapper', + version: '1.0.0', + dependencies: { 'skills-pkg': '1.0.0' }, + }) + + // skills-pkg is a transitive dep (sibling in node_modules) + createDir(appDir, 'node_modules', 'skills-pkg') + createDir(appDir, 'node_modules', 'skills-pkg', 'skills', 'core') + writeJson(join(appDir, 'node_modules', 'skills-pkg', 'package.json'), { + name: 'skills-pkg', + version: '1.0.0', + intent: { version: 1, repo: 'test/skills', docs: 'https://example.com' }, + }) + writeSkillMd(join(appDir, 'node_modules', 'skills-pkg', 'skills', 'core'), { + name: 'core', + description: 'Core skill', + }) + + createDir(root, 'node_modules') + + const result = await scanForIntents(root) + expect(result.packages).toHaveLength(1) + expect(result.packages[0]!.name).toBe('skills-pkg') + }) + + it('discovers skills using package.json workspaces', async () => { + writeJson(join(root, 'package.json'), { + name: 'monorepo', + private: true, + workspaces: ['packages/*'], + }) + + const appDir = join(root, 'packages', 'app') + createDir(root, 'packages', 'app') + writeJson(join(appDir, 'package.json'), { + name: '@monorepo/app', + version: '1.0.0', + dependencies: { '@tanstack/db': '0.5.0' }, + }) + + createDir(root, 'node_modules', '@tanstack', 'db') + createDir(root, 'node_modules', '@tanstack', 'db', 'skills', 'db-core') + const dbDir = join(root, 'node_modules', '@tanstack', 'db') + writeJson(join(dbDir, 'package.json'), { + name: '@tanstack/db', + version: '0.5.0', + intent: { version: 1, repo: 'TanStack/db', docs: 'https://db.tanstack.com' }, + }) + writeSkillMd(join(dbDir, 'skills', 'db-core'), { + name: 'db-core', + description: 'Core database concepts', + }) + + const result = await scanForIntents(root) + expect(result.packages).toHaveLength(1) + expect(result.packages[0]!.name).toBe('@tanstack/db') + }) + it('prefers valid semver versions over invalid ones at the same depth', async () => { writeJson(join(root, 'package.json'), { name: 'app', From d45901f1882cb264b617fe4a5be41b58b1ff1081 Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Sat, 14 Mar 2026 11:49:41 -0600 Subject: [PATCH 07/17] test: add integration test fixture packages --- .../fixtures/integration/skills-leaf/package.json | 10 ++++++++++ .../integration/skills-leaf/skills/core/SKILL.md | 9 +++++++++ .../tests/fixtures/integration/wrapper-1/package.json | 7 +++++++ .../tests/fixtures/integration/wrapper-2/package.json | 7 +++++++ .../tests/fixtures/integration/wrapper-3/package.json | 7 +++++++ 5 files changed, 40 insertions(+) create mode 100644 packages/intent/tests/fixtures/integration/skills-leaf/package.json create mode 100644 packages/intent/tests/fixtures/integration/skills-leaf/skills/core/SKILL.md create mode 100644 packages/intent/tests/fixtures/integration/wrapper-1/package.json create mode 100644 packages/intent/tests/fixtures/integration/wrapper-2/package.json create mode 100644 packages/intent/tests/fixtures/integration/wrapper-3/package.json diff --git a/packages/intent/tests/fixtures/integration/skills-leaf/package.json b/packages/intent/tests/fixtures/integration/skills-leaf/package.json new file mode 100644 index 0000000..b4128e9 --- /dev/null +++ b/packages/intent/tests/fixtures/integration/skills-leaf/package.json @@ -0,0 +1,10 @@ +{ + "name": "@test-intent/skills-leaf", + "version": "1.0.0", + "intent": { + "version": 1, + "repo": "test/skills-leaf", + "docs": "https://example.com/docs" + }, + "files": ["skills"] +} diff --git a/packages/intent/tests/fixtures/integration/skills-leaf/skills/core/SKILL.md b/packages/intent/tests/fixtures/integration/skills-leaf/skills/core/SKILL.md new file mode 100644 index 0000000..786b6d5 --- /dev/null +++ b/packages/intent/tests/fixtures/integration/skills-leaf/skills/core/SKILL.md @@ -0,0 +1,9 @@ +--- +name: core +description: "Core skill for integration testing" +type: core +--- + +# Core Skill + +This is a test skill used by integration tests. diff --git a/packages/intent/tests/fixtures/integration/wrapper-1/package.json b/packages/intent/tests/fixtures/integration/wrapper-1/package.json new file mode 100644 index 0000000..22a0837 --- /dev/null +++ b/packages/intent/tests/fixtures/integration/wrapper-1/package.json @@ -0,0 +1,7 @@ +{ + "name": "@test-intent/wrapper-1", + "version": "1.0.0", + "dependencies": { + "@test-intent/skills-leaf": "1.0.0" + } +} diff --git a/packages/intent/tests/fixtures/integration/wrapper-2/package.json b/packages/intent/tests/fixtures/integration/wrapper-2/package.json new file mode 100644 index 0000000..5835ba0 --- /dev/null +++ b/packages/intent/tests/fixtures/integration/wrapper-2/package.json @@ -0,0 +1,7 @@ +{ + "name": "@test-intent/wrapper-2", + "version": "1.0.0", + "dependencies": { + "@test-intent/wrapper-1": "1.0.0" + } +} diff --git a/packages/intent/tests/fixtures/integration/wrapper-3/package.json b/packages/intent/tests/fixtures/integration/wrapper-3/package.json new file mode 100644 index 0000000..52742a4 --- /dev/null +++ b/packages/intent/tests/fixtures/integration/wrapper-3/package.json @@ -0,0 +1,7 @@ +{ + "name": "@test-intent/wrapper-3", + "version": "1.0.0", + "dependencies": { + "@test-intent/wrapper-2": "1.0.0" + } +} From 2cadfd19bf6658d3520dd83089cb0625de155d95 Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Sat, 14 Mar 2026 11:51:43 -0600 Subject: [PATCH 08/17] test: add Verdaccio-based integration test infrastructure Co-Authored-By: Claude Opus 4.6 (1M context) --- packages/intent/package.json | 7 +- packages/intent/tests/integration/scaffold.ts | 219 ++ pnpm-lock.yaml | 3071 ++++++++++++++++- 3 files changed, 3289 insertions(+), 8 deletions(-) create mode 100644 packages/intent/tests/integration/scaffold.ts diff --git a/packages/intent/package.json b/packages/intent/package.json index 240c4a4..e24faf4 100644 --- a/packages/intent/package.json +++ b/packages/intent/package.json @@ -30,12 +30,15 @@ "yaml": "^2.7.0" }, "devDependencies": { - "tsdown": "^0.19.0" + "@verdaccio/node-api": "6.0.0-6-next.76", + "tsdown": "^0.19.0", + "verdaccio": "^6.3.2" }, "scripts": { "prepack": "npm run build", "build": "tsdown src/index.ts src/cli.ts src/setup.ts src/intent-library.ts src/library-scanner.ts --format esm --dts", - "test:lib": "vitest run", + "test:lib": "vitest run --exclude tests/integration/**", + "test:integration": "vitest run tests/integration/", "test:types": "tsc --noEmit" } } diff --git a/packages/intent/tests/integration/scaffold.ts b/packages/intent/tests/integration/scaffold.ts new file mode 100644 index 0000000..814ec4f --- /dev/null +++ b/packages/intent/tests/integration/scaffold.ts @@ -0,0 +1,219 @@ +import { execSync, execFileSync } from 'node:child_process' +import { + mkdirSync, + mkdtempSync, + realpathSync, + rmSync, + symlinkSync, + writeFileSync, +} from 'node:fs' +import { tmpdir } from 'node:os' +import { dirname, join } from 'node:path' +import { fileURLToPath } from 'node:url' + +const thisDir = dirname(fileURLToPath(import.meta.url)) +const fixturesDir = join(thisDir, '..', 'fixtures', 'integration') +const cliPath = join(thisDir, '..', '..', 'dist', 'cli.mjs') +const realTmpdir = realpathSync(tmpdir()) + +// --------------------------------------------------------------------------- +// Verdaccio lifecycle +// --------------------------------------------------------------------------- + +export interface Registry { + url: string + stop: () => void +} + +export async function startRegistry(): Promise { + const { runServer } = await import('@verdaccio/node-api') + + const storageDir = mkdtempSync(join(realTmpdir, 'verdaccio-storage-')) + const port = 6000 + Math.floor(Math.random() * 4000) + const configPath = join(storageDir, 'config.yaml') + + writeFileSync( + configPath, + [ + `storage: ${storageDir}`, + 'uplinks:', + ' npmjs:', + ' url: https://registry.npmjs.org/', + 'packages:', + " '@test-intent/*':", + ' access: $all', + ' publish: $all', + " '**':", + ' access: $all', + ' proxy: npmjs', + 'log: { type: stdout, format: pretty, level: fatal }', + ].join('\n'), + ) + + const app = await runServer(configPath) + + return new Promise((resolve, reject) => { + const server = app.listen(port, () => { + resolve({ + url: `http://localhost:${port}`, + stop: () => { + server.close() + rmSync(storageDir, { recursive: true, force: true }) + }, + }) + }) + server.on('error', reject) + }) +} + +// --------------------------------------------------------------------------- +// Publishing fixtures +// --------------------------------------------------------------------------- + +export function publishFixtures(registryUrl: string): void { + // Order matters: leaf first, then wrappers that depend on it + for (const pkg of ['skills-leaf', 'wrapper-1', 'wrapper-2', 'wrapper-3']) { + execSync(`npm publish --registry ${registryUrl} --access public`, { + cwd: join(fixturesDir, pkg), + stdio: 'ignore', + }) + } +} + +// --------------------------------------------------------------------------- +// Project scaffolding +// --------------------------------------------------------------------------- + +export type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun' +export type ProjectStructure = 'single' | 'monorepo-root' | 'monorepo-workspace' + +interface ScaffoldResult { + root: string + cwd: string +} + +export function scaffoldProject(opts: { + pm: PackageManager + structure: ProjectStructure + dependency: string + registryUrl: string +}): ScaffoldResult { + const root = mkdtempSync(join(realTmpdir, `intent-integ-${opts.pm}-`)) + + // Lockfile marker so detectPackageManager works + const lockfiles: Record = { + npm: 'package-lock.json', + pnpm: 'pnpm-lock.yaml', + yarn: 'yarn.lock', + bun: 'bun.lock', + } + writeFileSync(join(root, lockfiles[opts.pm]), '') + + if (opts.structure === 'single') { + writeJson(join(root, 'package.json'), { + name: 'test-project', + private: true, + dependencies: { [opts.dependency]: '1.0.0' }, + }) + install(root, opts.pm, opts.registryUrl) + return { root, cwd: root } + } + + // Monorepo + writeJson(join(root, 'package.json'), { + name: 'test-monorepo', + private: true, + ...(opts.pm !== 'pnpm' ? { workspaces: ['packages/*'] } : {}), + }) + if (opts.pm === 'pnpm') { + writeFileSync(join(root, 'pnpm-workspace.yaml'), 'packages:\n - packages/*\n') + } + if (opts.pm === 'yarn') { + writeFileSync(join(root, '.yarnrc.yml'), 'nodeLinker: node-modules\n') + } + + const appDir = join(root, 'packages', 'app') + mkdirSync(appDir, { recursive: true }) + writeJson(join(appDir, 'package.json'), { + name: '@test/app', + version: '1.0.0', + dependencies: { [opts.dependency]: '1.0.0' }, + }) + + install(root, opts.pm, opts.registryUrl) + + return { + root, + cwd: opts.structure === 'monorepo-root' ? root : appDir, + } +} + +function install(dir: string, pm: PackageManager, registryUrl: string): void { + const env = { ...process.env, npm_config_registry: registryUrl } + const reg = `--registry=${registryUrl}` + + switch (pm) { + case 'npm': + execSync(`npm install ${reg}`, { cwd: dir, stdio: 'ignore', env }) + break + case 'pnpm': + execSync(`pnpm install ${reg} --no-frozen-lockfile`, { cwd: dir, stdio: 'ignore', env }) + break + case 'yarn': + execSync(`yarn install ${reg}`, { cwd: dir, stdio: 'ignore', env }) + break + case 'bun': + execSync(`bun install ${reg}`, { cwd: dir, stdio: 'ignore', env }) + break + } +} + +// --------------------------------------------------------------------------- +// CLI invocation +// --------------------------------------------------------------------------- + +export interface CliResult { + stdout: string + stderr: string + exitCode: number + parsed: any +} + +export function runScanner( + cwd: string, + method: 'direct' | 'symlink' = 'direct', +): CliResult { + let binPath = cliPath + + if (method === 'symlink') { + const linkDir = mkdtempSync(join(realTmpdir, 'intent-link-')) + const linkPath = join(linkDir, 'intent-cli.mjs') + symlinkSync(cliPath, linkPath) + binPath = linkPath + } + + try { + const stdout = execFileSync('node', [binPath, 'list', '--json'], { + cwd, + encoding: 'utf8', + stdio: ['ignore', 'pipe', 'pipe'], + }) + return { stdout, stderr: '', exitCode: 0, parsed: JSON.parse(stdout) } + } catch (err: any) { + return { + stdout: err.stdout ?? '', + stderr: err.stderr ?? '', + exitCode: err.status ?? 1, + parsed: null, + } + } +} + +// --------------------------------------------------------------------------- +// Helpers +// --------------------------------------------------------------------------- + +function writeJson(filePath: string, data: unknown): void { + mkdirSync(dirname(filePath), { recursive: true }) + writeFileSync(filePath, JSON.stringify(data, null, 2)) +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bef2a76..e95ad1b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -73,9 +73,15 @@ importers: specifier: ^2.7.0 version: 2.8.2 devDependencies: + '@verdaccio/node-api': + specifier: 6.0.0-6-next.76 + version: 6.0.0-6-next.76 tsdown: specifier: ^0.19.0 version: 0.19.0(oxc-resolver@11.16.3)(typescript@5.9.3) + verdaccio: + specifier: ^6.3.2 + version: 6.3.2(typanion@3.14.0) packages: @@ -162,6 +168,10 @@ packages: '@changesets/write@0.4.0': resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==} + '@cypress/request@3.0.10': + resolution: {integrity: sha512-hauBrOdvu08vOsagkZ/Aju5XuiZx6ldsLfByg1htFeldhex+PeMrYauANzFsMJeAA0+dyPLbDoX2OYuvVoLDkQ==} + engines: {node: '>= 6'} + '@emnapi/core@1.8.1': resolution: {integrity: sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==} @@ -378,6 +388,18 @@ packages: resolution: {integrity: sha512-rTXwAsIxpCqzUnZvrxVh3L0QA0NzToqWBLAhV+zDV3MIIwiQhAZHMdPCIaj5n/yADu/tyk12wIPgL6YHGXJP+g==} engines: {node: ^20.19.0 || ^22.13.0 || ^23.5.0 || >=24.0.0, npm: '>=10'} + '@fastify/ajv-compiler@3.6.0': + resolution: {integrity: sha512-LwdXQJjmMD+GwLOkP7TVC68qa+pSSogeWWmznRJ/coyTcfe9qA05AHFSe1eZFwK6q+xVRpChnvFUkf1iYaSZsQ==} + + '@fastify/error@3.4.1': + resolution: {integrity: sha512-wWSvph+29GR783IhmvdwWnN4bUxTD01Vm5Xad4i7i1VuAOItLvbPAb69sb0IQ2N57yprvhNIwAP5B6xfKTmjmQ==} + + '@fastify/fast-json-stringify-compiler@4.3.0': + resolution: {integrity: sha512-aZAXGYo6m22Fk1zZzEUKBvut/CIIQe/BapEORnxiD5Qr0kPHqqI69NtEMCme74h+at72sPhbkb4ZrLd1W3KRLA==} + + '@fastify/merge-json-schemas@0.1.1': + resolution: {integrity: sha512-fERDVz7topgNjtXsJTTW1JKLy0rhuLRcquYqNR9rF7OcVpCa2OVW49ZPDIhaRRCaUuvVxI+N416xUoF76HNSXA==} + '@gerrit0/mini-shiki@3.23.0': resolution: {integrity: sha512-bEMORlG0cqdjVyCEuU0cDQbORWX+kYCeo0kV1lbxF5bt4r7SID2l9bqsxJEM0zndaxpOUT7riCyIVEuqq/Ynxg==} @@ -625,6 +647,9 @@ packages: cpu: [x64] os: [win32] + '@pinojs/redact@0.4.0': + resolution: {integrity: sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==} + '@quansync/fs@1.0.0': resolution: {integrity: sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==} @@ -931,6 +956,10 @@ packages: '@sinclair/typebox@0.34.47': resolution: {integrity: sha512-ZGIBQ+XDvO5JQku9wmwtabcVTHJsgSWAHYtVuM9pBNNR5E88v6Jcj/llpmsjivig5X8A8HHOb4/mbEKPS5EvAw==} + '@sindresorhus/is@4.6.0': + resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} + engines: {node: '>=10'} + '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} @@ -949,6 +978,10 @@ packages: resolution: {integrity: sha512-08eKiDAjj4zLug1taXSIJ0kGL5cawjVCyJkBb6EWSg5fEPX6L+Wtr0CH2If4j5KYylz85iaZiFlUItvgJvll5g==} engines: {node: ^14.13.1 || ^16.0.0 || >=18} + '@szmarczak/http-timer@4.0.6': + resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} + engines: {node: '>=10'} + '@tanstack/eslint-config@0.4.0': resolution: {integrity: sha512-V+Cd81W/f65dqKJKpytbwTGx9R+IwxKAHsG/uJ3nSLYEh36hlAr54lRpstUhggQB8nf/cP733cIw8DuD2dzQUg==} engines: {node: '>=18'} @@ -980,6 +1013,9 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + '@types/lodash@4.17.24': + resolution: {integrity: sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==} + '@types/node@12.20.55': resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} @@ -989,6 +1025,9 @@ packages: '@types/node@25.0.9': resolution: {integrity: sha512-/rpCXHlCWeqClNBwUhDcusJxXYDjZTyE8v5oTO7WbL8eij2nKhUeU89/6xgjU7N4/Vh3He0BtyhJdQbDyhiXAw==} + '@types/responselike@1.0.0': + resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} + '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} @@ -1156,6 +1195,173 @@ packages: cpu: [x64] os: [win32] + '@verdaccio/api@6.0.0-6-next.59': + resolution: {integrity: sha512-Cl/7h4tHgxAc0fv3vNzceY1zBGu2eJoGQYCYqrrItKE1co+H+vJZVR5Hmj6vKsTpa7BfIeulFsaTw5dt+QJ9JA==} + engines: {node: '>=14', npm: '>=6'} + + '@verdaccio/auth@6.0.0-6-next.55': + resolution: {integrity: sha512-UCjP4xsz8tmX6w/VPlwBi8rvZOjKS5Uxq4OhcmTBbxepBj6lIK2lfa2w8szM7fDRZPwxGL4YlAy88tUjhAw8Bw==} + engines: {node: '>=14', npm: '>=6'} + + '@verdaccio/auth@8.0.0-next-8.33': + resolution: {integrity: sha512-HRIqEj9J7t95ZG3pCVpaCJoXCNVPB0R2DpkEXfG19TXsapf/mv5vMnBYG6O1C/ShNagHMA7z+Z6NwFZXHUzm9g==} + engines: {node: '>=18'} + + '@verdaccio/config@6.0.0-6-next.76': + resolution: {integrity: sha512-iWmmi+8pDedpwbRw43K19+Ky+DBYwcQ3L9hQNkG4KrhGdJsy7it6bpcjmxrh4xX39jQ00bqyq6Hb4cCGl7zlRQ==} + engines: {node: '>=12'} + + '@verdaccio/config@8.0.0-next-8.33': + resolution: {integrity: sha512-6/n/qcVMbNTK8oFY8l6vlJMeG6zor/aOFcR2Wd6yCoKcehITigmLn8MFziZPriYivzxYJJRjlaKO9+HuuQSKCA==} + engines: {node: '>=18'} + + '@verdaccio/core@6.0.0-6-next.76': + resolution: {integrity: sha512-1Jr4Ft61GWAKRlv8joGNa9e/zyaqm7FTP8qkKNl84LEjpmUomn5UrXYbiq4d1DESd7SVVQEfpRmYp1wnPniSHQ==} + engines: {node: '>=12'} + + '@verdaccio/core@8.0.0-next-8.21': + resolution: {integrity: sha512-n3Y8cqf84cwXxUUdTTfEJc8fV55PONPKijCt2YaC0jilb5qp1ieB3d4brqTOdCdXuwkmnG2uLCiGpUd/RuSW0Q==} + engines: {node: '>=18'} + + '@verdaccio/core@8.0.0-next-8.33': + resolution: {integrity: sha512-ndPAfZVyN677y/EZX+USkL0/aOcU5rvnzS99nRCIHarZB44WMno9jl6FdX5Ax3b3exGo9GsxhEdbYHgOYaRlLQ==} + engines: {node: '>=18'} + + '@verdaccio/file-locking@10.3.1': + resolution: {integrity: sha512-oqYLfv3Yg3mAgw9qhASBpjD50osj2AX4IwbkUtyuhhKGyoFU9eZdrbeW6tpnqUnj6yBMtAPm2eGD4BwQuX400g==} + engines: {node: '>=12'} + + '@verdaccio/file-locking@11.0.0-6-next.7': + resolution: {integrity: sha512-S0GNoe2oBOgB7fKJN2vZqnl5qDEvdnTfKAfa47InXweJROeul6kjlE2/NlbNbK3zZID01VR1HFrFehMQO0Jyfw==} + engines: {node: '>=12'} + + '@verdaccio/file-locking@13.0.0-next-8.6': + resolution: {integrity: sha512-F6xQWvsZnEyGjugrYfe+D/ChSVudXmBFWi8xuTIX6PAdp7dk9x9biOGQFW8O3GSAK8UhJ6WlRisQKJeYRa6vWQ==} + engines: {node: '>=18'} + + '@verdaccio/hooks@6.0.0-6-next.46': + resolution: {integrity: sha512-C7a1c5wac2gqhW1eM/da32fZY4DpWaOcu/Gv/O3G1FddjeOKAg7TqYhN94+6c4i3D5dUTYFU5mVzq98qp6238Q==} + engines: {node: '>=12'} + + '@verdaccio/hooks@8.0.0-next-8.33': + resolution: {integrity: sha512-8xP6kVOCufjaZWriFtaxP3HEmvYTIBhcxWldui4eCG7dzBdZzPlCkRbYKWP8LMnOEIxbJNbeFkokOaI1nho1jg==} + engines: {node: '>=18'} + + '@verdaccio/loaders@6.0.0-6-next.45': + resolution: {integrity: sha512-OtNuekG0cIWDZcQKWdCFzw9yPxKhhoVEuroTUh/Yu7Yehw+XcbNRIclUjauMU5UdZGx4ryzyX8QDcBwrJO7Dmg==} + engines: {node: '>=12'} + + '@verdaccio/loaders@8.0.0-next-8.23': + resolution: {integrity: sha512-UruK7pFz7aRKkR41/Hg/cPFSqX5Oxbx9rKGWK5ql3mvg2+xaWleRwknmnNjbVod7QK6cWsYA6cKnttRBTQuPkQ==} + engines: {node: '>=18'} + + '@verdaccio/local-storage-legacy@11.1.1': + resolution: {integrity: sha512-P6ahH2W6/KqfJFKP+Eid7P134FHDLNvHa+i8KVgRVBeo2/IXb6FEANpM1mCVNvPANu0LCAmNJBOXweoUKViaoA==} + engines: {node: '>=18'} + + '@verdaccio/local-storage@11.0.0-6-next.46': + resolution: {integrity: sha512-RAKTLf977l23LSa+68weMU26/qx3U8xSQWKcYKHDjla2v6igu8+Wj9I12bW+lQUE1d5GRmn/8ex5IgGKSEJcEw==} + engines: {node: '>=14', npm: '>=7'} + + '@verdaccio/logger-commons@6.0.0-6-next.44': + resolution: {integrity: sha512-we0Ad6ShuyXRxY2u/FaOGPF5nj9Uk41iqMYrtBmnPRHNeAf9Okl4jnPZ5kbzMpXL8rOeHYR/v/x4EXQ8qayueA==} + engines: {node: '>=12'} + + '@verdaccio/logger-commons@8.0.0-next-8.33': + resolution: {integrity: sha512-WmMq/6HyRliKWus3sQR9Pgodopzbp84dl/h/E0tnxuOmzc/eDwYCEiQMfFhIBaOlpVJdsdLYqNAM9+YkoSDK0g==} + engines: {node: '>=18'} + + '@verdaccio/logger-prettify@6.0.0-6-next.10': + resolution: {integrity: sha512-G9woGojHXoRg3W4fE2ZlNy2c25f5faqLWHxVdnDFbgbH6dieG+GzlyNwiOcrRC4LEkh7dWcgwuNMx1NZFojqhg==} + engines: {node: '>=12'} + + '@verdaccio/logger-prettify@8.0.0-next-8.4': + resolution: {integrity: sha512-gjI/JW29fyalutn/X1PQ0iNuGvzeVWKXRmnLa7gXVKhdi4p37l/j7YZ7n44XVbbiLIKAK0pbavEg9Yr66QrYaA==} + engines: {node: '>=18'} + + '@verdaccio/logger@6.0.0-6-next.44': + resolution: {integrity: sha512-jbzSUmfsDc8mh6BdvlHqRSUmf6qOLbvzJwaEvkR5N2aQMiIUvRCyCCjyztUXjgudXvQDErEHanxdlxXs/H8dnQ==} + engines: {node: '>=12'} + + '@verdaccio/logger@8.0.0-next-8.33': + resolution: {integrity: sha512-8nR3hreOcINIbMIOohhxZNUL3l0uvgGYQecl8WJvR4XizYTp1vPHv4qz1CPyuaI5bKj1QFRqHkKvvtEnD1A0rw==} + engines: {node: '>=18'} + + '@verdaccio/middleware@6.0.0-6-next.55': + resolution: {integrity: sha512-oovGO30FtZyaVj1b8APkIoCSy6ndwy+wEZt0Ac7RdAwF/dCFPWU80rR93Ha248IbUias6Quu+pgOdccedJhfRg==} + engines: {node: '>=12'} + + '@verdaccio/middleware@8.0.0-next-8.33': + resolution: {integrity: sha512-iMzE3stUp/qocHzFX2+xkzUe6L89vWZ/J4a4v7IxPu6KqBH39XCg4gI8Qu0xXRIFeYSTpZNzRUO+FTkeZRhJ1A==} + engines: {node: '>=18'} + + '@verdaccio/node-api@6.0.0-6-next.76': + resolution: {integrity: sha512-n5/d665tGtYSZeijH1tv+MFaJ2Pd/0AwCIfEhIwaoqa/z7UefOfv0fj4vyjc+K6Q+3zxPvcyUzyMT9iV50krtw==} + engines: {node: '>=14', npm: '>=6'} + + '@verdaccio/proxy@6.0.0-6-next.54': + resolution: {integrity: sha512-BZOHXkuhyZgX0f8YYqjt9Q2m7itprZFm+r/0c5ycl3wCwLAd06YJ2yf+aQj+PWxqQL414/Z2FEHwi+8nxvCMmg==} + engines: {node: '>=12'} + + '@verdaccio/search-indexer@8.0.0-next-8.5': + resolution: {integrity: sha512-0GC2tJKstbPg/W2PZl2yE+hoAxffD2ZWilEnEYSEo2e9UQpNIy2zg7KE/uMUq2P72Vf5EVfVzb8jdaH4KV4QeA==} + engines: {node: '>=18'} + + '@verdaccio/server-fastify@6.0.0-6-next.57': + resolution: {integrity: sha512-L/dZl4mnvdV0jVByquRcnR/4Vr//jOLJrXp+OfZwpxfEzHvXb1fVKd5/7UzlZWAOjX2OI2/3L3NSUDRHeH2jRw==} + engines: {node: '>=14', npm: '>=6'} + + '@verdaccio/server@6.0.0-6-next.65': + resolution: {integrity: sha512-zfsfKjbmrErafyI0dfNRA2VMia/fAb+d0LfVLYhmf6XlTh6eBanH8PU2m70onQxFKi5EJ+WhdG+bCqsYrojIvA==} + engines: {node: '>=14', npm: '>=6'} + + '@verdaccio/signature@6.0.0-6-next.2': + resolution: {integrity: sha512-aFvMbxxHzJCpPmqSgVuQYvYN2RP11CoSEcTXikkyb1zF4Uf3cOy53zUZ1Y7iOKCRYTgWrmet9KP7+24e44GHxg==} + engines: {node: '>=12'} + + '@verdaccio/signature@8.0.0-next-8.25': + resolution: {integrity: sha512-3qMHZ9uXgNmRQDw7Bz3coCbXJAfI3q+bWRXQ0/fKg03LgSV6pbMD0HinGKcIBn0Kni+e8IsXxBfrs5ga4FF+Rg==} + engines: {node: '>=18'} + + '@verdaccio/store@6.0.0-6-next.56': + resolution: {integrity: sha512-2x+ZEj6UNjXLP99QhFss4ZTvA0pM2wI2AMkmK3TAEgWFTZK/KPWmq3ypRI91wLyq5e1J7+k6ij8P7SsVJfl6AA==} + engines: {node: '>=16', npm: '>=6'} + + '@verdaccio/streams@10.2.1': + resolution: {integrity: sha512-OojIG/f7UYKxC4dYX8x5ax8QhRx1b8OYUAMz82rUottCuzrssX/4nn5QE7Ank0DUSX3C9l/HPthc4d9uKRJqJQ==} + engines: {node: '>=12', npm: '>=5'} + + '@verdaccio/tarball@11.0.0-6-next.45': + resolution: {integrity: sha512-RpQLWYuP/P/FK6OhvIilN9g3Fo287+dml9jo7CTjFSLZ8zRiE/8nZr+Su3VghXJhHDB6uhQxYXPGzmi/2XjggA==} + engines: {node: '>=12'} + + '@verdaccio/tarball@13.0.0-next-8.33': + resolution: {integrity: sha512-VQZ8I5Fs6INxO1cY6Lpk4Wx3sD0Uy7YIzTY9qWrZNRPGDxGcZu2fyFMUfoNc1+ygJP0r5TTqdVAY74z0iQnsWg==} + engines: {node: '>=18'} + + '@verdaccio/ui-theme@8.0.0-next-8.30': + resolution: {integrity: sha512-MSvFnYeocTWp6hqtIqtwp7Zm920UNhO3zQkKTPT6qGNjarkhxCCWRcSOAz7oJZhpbyLXc85zuxOLkTezCl4KUg==} + + '@verdaccio/url@11.0.0-6-next.42': + resolution: {integrity: sha512-qEzlYck53hUd86uRBW6/oPeASJK3yZH7QJ+Wwhbc/946Pt6NQFxI1LsV0Nj3G404O7UjbLtZDS4osD9H3M6hkg==} + engines: {node: '>=12'} + + '@verdaccio/url@13.0.0-next-8.33': + resolution: {integrity: sha512-26LzQTCuUFFcNasAdzayBqsYWBheQy+D4tSWnVtmj4kKQnVhufBvHLjpEjK1gqphOMx6/Mju0IQe0LsjRc1zdg==} + engines: {node: '>=18'} + + '@verdaccio/utils@6.0.0-6-next.44': + resolution: {integrity: sha512-fSuxes9lfQO8mBXfV8lAnfeWgM4iUbB4LFv8KgSSd7T3QP453MpS09zZmbJTdxgy8CyWeGvACIQvSXxkYoNxBA==} + engines: {node: '>=12'} + + '@verdaccio/utils@8.1.0-next-8.33': + resolution: {integrity: sha512-WLE8qTBgzuZPa+gq/nKPWtF4MTMayaeOD3Qy6yfChxNvFXY+6yPFkS0QocXL7CdB2A+w+ylgTOOzKr0tWvyTpQ==} + engines: {node: '>=18'} + + '@verdaccio/web@6.0.0-6-next.63': + resolution: {integrity: sha512-YkHxHFm3SrCS0MaptlX18C2a+4kTQRD3QtRwAmPs/xUVoeZ59tPAh94XOFafpY6KBK2Eyd8MDgj+akxglolsnQ==} + engines: {node: '>=14', npm: '>=6'} + '@vitest/expect@4.0.17': resolution: {integrity: sha512-mEoqP3RqhKlbmUmntNDDCJeTDavDR+fVYkSOw8qRwJFaW/0/5zA9zFeTrHqNtcmwh6j26yMmwx2PqUDPzt5ZAQ==} @@ -1196,6 +1402,24 @@ packages: resolution: {integrity: sha512-nrUSn7hzt7J6JWgWGz78ZYI8wj+gdIJdk0Ynjpp8l+trkn58Uqsf6RYrYkEK+3X18EX+TNdtJI0WxAtc+L84SQ==} hasBin: true + JSONStream@1.3.5: + resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} + hasBin: true + + abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + + abortcontroller-polyfill@1.7.5: + resolution: {integrity: sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ==} + + abstract-logging@2.0.1: + resolution: {integrity: sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==} + + accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -1206,9 +1430,38 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + + ajv-formats@2.1.1: + resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv-formats@3.0.1: + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ajv@8.12.0: + resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==} + + ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + + ajv@8.18.0: + resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} + ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} @@ -1229,6 +1482,10 @@ packages: resolution: {integrity: sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==} engines: {node: '>=14'} + apache-md5@1.1.8: + resolution: {integrity: sha512-FCAJojipPn0bXjuEpjOOOMN8FZDkxfWWp4JGN9mifU2IhxvKyXZYqpzPHdnTSUpmPDy+tsslB6Z1g+Vg6nVbYA==} + engines: {node: '>=8'} + argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} @@ -1239,10 +1496,20 @@ packages: resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} engines: {node: '>= 0.4'} + array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} + asn1@0.2.6: + resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} + + assert-plus@1.0.0: + resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} + engines: {node: '>=0.8'} + assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} @@ -1251,9 +1518,25 @@ packages: resolution: {integrity: sha512-m1Q/RaVOnTp9JxPX+F+Zn7IcLYMzM8kZofDImfsKZd8MbR+ikdOzTeztStWqfrqIxZnYWryyI9ePm3NGjnZgGw==} engines: {node: '>=20.19.0'} + async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + atomic-sleep@1.0.0: + resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} + engines: {node: '>=8.0.0'} + + avvio@8.4.0: + resolution: {integrity: sha512-CDSwaxINFy59iNwhYnkvALBwZiTydGkOecZyPkqBpABYR1KqGEsET0VOOYDwtleZSUIdeY36DC2bSZ24CO1igA==} + + aws-sign2@0.7.0: + resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} + + aws4@1.13.2: + resolution: {integrity: sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==} + axios@1.13.2: resolution: {integrity: sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==} @@ -1261,6 +1544,14 @@ packages: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} + b4a@1.8.0: + resolution: {integrity: sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg==} + peerDependencies: + react-native-b4a: '*' + peerDependenciesMeta: + react-native-b4a: + optional: true + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -1268,9 +1559,23 @@ packages: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} + bare-events@2.8.2: + resolution: {integrity: sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==} + peerDependencies: + bare-abort-controller: '*' + peerDependenciesMeta: + bare-abort-controller: + optional: true + base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + bcrypt-pbkdf@1.0.2: + resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} + + bcryptjs@2.4.3: + resolution: {integrity: sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==} + better-path-resolve@1.0.0: resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} engines: {node: '>=4'} @@ -1281,6 +1586,18 @@ packages: bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + body-parser@1.20.1: + resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + body-parser@1.20.2: + resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + body-parser@1.20.4: + resolution: {integrity: sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} @@ -1298,21 +1615,56 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} + browserify-zlib@0.1.4: + resolution: {integrity: sha512-19OEpq7vWgsH6WkvkBJQDFvJS1uPcbFOQ4v9CU839dO+ZZXUZO6XpE6hNCqvlIIj+4fZvRiJ6DsAQ382GwiyTQ==} + + buffer-equal-constant-time@1.0.1: + resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + bytes@3.0.0: + resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==} + engines: {node: '>= 0.8'} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + cac@6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} + cacheable-lookup@6.1.0: + resolution: {integrity: sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww==} + engines: {node: '>=10.6.0'} + + cacheable-request@7.0.2: + resolution: {integrity: sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==} + engines: {node: '>=8'} + call-bind-apply-helpers@1.0.2: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} + caseless@0.12.0: + resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} + chai@6.2.2: resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} engines: {node: '>=18'} @@ -1343,10 +1695,18 @@ packages: resolution: {integrity: sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==} engines: {node: '>=6'} + clipanion@4.0.0-rc.4: + resolution: {integrity: sha512-CXkMQxU6s9GklO/1f714dkKBMu1lopS1WFF0B8o4AxPykR1hpozxSiUZ5ZUeBjfPgCWqbcNOtZVFhB8Lkfp1+Q==} + peerDependencies: + typanion: '*' + cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} + clone-response@1.0.3: + resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==} + clone@1.0.4: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} @@ -1362,6 +1722,9 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} @@ -1370,9 +1733,64 @@ packages: resolution: {integrity: sha512-0D6qSQ5IkeRrGJFHRClzaMOenMeT0gErz3zIw3AprKMqhRN6LNU2jQOdkPG/FZ+8bCgXE1VidrgSzlBBDZRr8A==} engines: {node: '>= 12.0.0'} + compressible@2.0.18: + resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} + engines: {node: '>= 0.6'} + + compression@1.7.4: + resolution: {integrity: sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==} + engines: {node: '>= 0.8.0'} + + compression@1.8.1: + resolution: {integrity: sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==} + engines: {node: '>= 0.8.0'} + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + cookie-signature@1.0.6: + resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + + cookie-signature@1.0.7: + resolution: {integrity: sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==} + + cookie@0.5.0: + resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} + engines: {node: '>= 0.6'} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + + cookies@0.8.0: + resolution: {integrity: sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow==} + engines: {node: '>= 0.8'} + + core-js@3.30.2: + resolution: {integrity: sha512-uBJiDmwqsbJCWHAwjrx3cvjbMXP7xD72Dmsn5LOJpiRmE3WbBbN5rCqQ2Qh6Ek6/eOrjlWngEynBWo4VxerQhg==} + + core-util-is@1.0.2: + resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + cors@2.8.5: + resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} + engines: {node: '>= 0.10'} + + cors@2.8.6: + resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} + engines: {node: '>= 0.10'} + cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} @@ -1384,9 +1802,45 @@ packages: resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} engines: {node: '>= 6'} + dashdash@1.14.1: + resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} + engines: {node: '>=0.10'} + dataloader@1.4.0: resolution: {integrity: sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==} + dayjs@1.11.13: + resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + + dayjs@1.11.7: + resolution: {integrity: sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.1: + resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} @@ -1396,12 +1850,20 @@ packages: supports-color: optional: true + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} defaults@1.0.4: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + defer-to-connect@2.0.1: + resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} + engines: {node: '>=10'} + define-lazy-prop@2.0.0: resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} engines: {node: '>=8'} @@ -1413,6 +1875,14 @@ packages: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + detect-indent@6.1.0: resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} engines: {node: '>=8'} @@ -1462,6 +1932,18 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} + duplexify@3.7.1: + resolution: {integrity: sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==} + + ecc-jsbn@0.1.2: + resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} + + ecdsa-sig-formatter@1.0.11: + resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -1469,6 +1951,14 @@ packages: resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==} engines: {node: '>=14'} + encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + encoding-sniffer@0.2.1: resolution: {integrity: sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==} @@ -1495,6 +1985,11 @@ packages: resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} engines: {node: '>=0.12'} + envinfo@7.21.0: + resolution: {integrity: sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow==} + engines: {node: '>=4'} + hasBin: true + es-define-property@1.0.1: resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} engines: {node: '>= 0.4'} @@ -1523,6 +2018,9 @@ packages: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + escape-string-regexp@1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} @@ -1644,16 +2142,58 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + + events-universal@1.0.1: + resolution: {integrity: sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + expect-type@1.3.0: resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} engines: {node: '>=12.0.0'} + express-rate-limit@5.5.1: + resolution: {integrity: sha512-MTjE2eIbHv5DyfuFz4zLYWxpqVhEhkTiwFGuB74Q9CSou2WHO52nlE5y3Zlg6SIsiYUIPj6ifFxnkPz6O3sIUg==} + + express@4.18.2: + resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==} + engines: {node: '>= 0.10.0'} + + express@4.22.1: + resolution: {integrity: sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==} + engines: {node: '>= 0.10.0'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + extendable-error@0.1.7: resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} + extsprintf@1.3.0: + resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} + engines: {'0': node >=0.6.0} + + fast-content-type-parse@1.1.0: + resolution: {integrity: sha512-fBHHqSTFLVnR61C+gltJuE5GkVQMV0S2nqUO8TJ+5Z3qAKG8vAx4FKai1s5jq/inV1+sREynIWSuQ6HgoSXpDQ==} + + fast-decode-uri-component@1.0.1: + resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-fifo@1.3.2: + resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + fast-glob@3.3.3: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} @@ -1661,9 +2201,31 @@ packages: fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + fast-json-stringify@5.16.1: + resolution: {integrity: sha512-KAdnLvy1yu/XrRtP+LJnxbBGrhN+xXu+gt3EUvZhYGKCr3lFHq/7UFJHHFgmJKoqlh6B40bZLEv7w46B0mqn1g==} + fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + fast-querystring@1.1.2: + resolution: {integrity: sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==} + + fast-redact@3.5.0: + resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} + engines: {node: '>=6'} + + fast-uri@2.4.0: + resolution: {integrity: sha512-ypuAmmMKInk5q7XcepxlnUWDLWv4GFtaJqAzWKqn62IpQ3pejtr5dTVbt3vwqVaMKmkNR55sTT+CqUKIaT21BA==} + + fast-uri@3.1.0: + resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + + fastify-plugin@4.4.0: + resolution: {integrity: sha512-ovwFQG2qNy3jcCROiWpr94Hs0le+c7N/3t7m9aVwbFhkxcR/esp2xu25dP8e617HpQdmeDv+gFX4zagdUhDByw==} + + fastify@4.17.0: + resolution: {integrity: sha512-tzuY1tgWJo2Y6qEKwmLhFvACUmr68Io2pqP/sDKU71KRM6A6R3DrCDqLGqANbeLZcKUfdfY58ut35CGqemcTgg==} + fastq@1.20.1: resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} @@ -1691,6 +2253,18 @@ packages: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} + finalhandler@1.2.0: + resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} + engines: {node: '>= 0.8'} + + finalhandler@1.3.2: + resolution: {integrity: sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==} + engines: {node: '>= 0.8'} + + find-my-way@7.7.0: + resolution: {integrity: sha512-+SrHpvQ52Q6W9f3wJoJBbAQULJuNEEQwBvlvYwACDhBTLOTMiQ0HYWh4+vC3OivGP2ENcTI1oKlFA2OepJNjhQ==} + engines: {node: '>=14'} + find-up@4.1.0: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} engines: {node: '>=8'} @@ -1719,6 +2293,12 @@ packages: debug: optional: true + forever-agent@0.6.1: + resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} + + form-data-encoder@1.7.2: + resolution: {integrity: sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==} + form-data@4.0.5: resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} engines: {node: '>= 6'} @@ -1728,6 +2308,14 @@ packages: engines: {node: '>=18.3.0'} hasBin: true + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + front-matter@4.0.2: resolution: {integrity: sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==} @@ -1762,9 +2350,20 @@ packages: resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} engines: {node: '>= 0.4'} + get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + get-tsconfig@4.13.0: resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} + getpass@0.1.7: + resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -1796,10 +2395,28 @@ packages: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} + got-cjs@12.5.4: + resolution: {integrity: sha512-Uas6lAsP8bRCt5WXGMhjFf/qEHTrm4v4qxGR02rLG2kdG9qedctvlkdwXVcDJ7Cs84X+r4dPU7vdwGjCaspXug==} + engines: {node: '>=12'} + graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - happy-dom@20.3.1: + gunzip-maybe@1.4.2: + resolution: {integrity: sha512-4haO1M4mLO91PW57BMsDFf75UmwoRX0GkdD+Faw+Lr+r/OZrOCS0pIBwOL1xCKQqnQzbNFGgK2V2CpBUPeFNTw==} + hasBin: true + + handlebars@4.7.7: + resolution: {integrity: sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==} + engines: {node: '>=0.4.7'} + hasBin: true + + handlebars@4.7.8: + resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} + engines: {node: '>=0.4.7'} + hasBin: true + + happy-dom@20.3.1: resolution: {integrity: sha512-tLvsizNno05Hij0PoB0QN/S8xf0YU2AGvO11/JlJDw5McA/gzyn0Ni1RwbTI1/zteUbOekJH0t6q8HFvjbxsGg==} engines: {node: '>=20.0.0'} @@ -1822,16 +2439,53 @@ packages: hookable@6.0.1: resolution: {integrity: sha512-uKGyY8BuzN/a5gvzvA+3FVWo0+wUjgtfSdnmjtrOVwQCZPHpHDH2WRO3VZSOeluYrHoDCiXFffZXs8Dj1ULWtw==} + hpagent@1.2.0: + resolution: {integrity: sha512-A91dYTeIB6NoXG+PxTQpCCDDnfHsW9kc06Lvpu1TEe9gnd6ZFeiBoRO9JvzEv6xK7EX97/dUE8g/vBMTqTS3CA==} + engines: {node: '>=14'} + html-link-extractor@1.0.5: resolution: {integrity: sha512-ADd49pudM157uWHwHQPUSX4ssMsvR/yHIswOR5CUfBdK9g9ZYGMhVSE6KZVHJ6kCkR0gH4htsfzU6zECDNVwyw==} htmlparser2@10.0.0: resolution: {integrity: sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==} + http-cache-semantics@4.2.0: + resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} + + http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + + http-signature@1.4.0: + resolution: {integrity: sha512-G5akfn7eKbpDN+8nPS/cb57YeA1jLTVxjpCj7tmm3QKPdyDy7T+qSC40e9ptydSWvkwjSXw1VbkpyEm39ukeAg==} + engines: {node: '>=0.10'} + + http-status-codes@2.2.0: + resolution: {integrity: sha512-feERVo9iWxvnejp3SEfm/+oNG517npqL2/PIA8ORjyOZjGC7TwCRQsZylciLS64i6pJ0wRYz3rkXLRwbtFa8Ng==} + + http-status-codes@2.3.0: + resolution: {integrity: sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA==} + + http2-wrapper@2.2.1: + resolution: {integrity: sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==} + engines: {node: '>=10.19.0'} + + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + human-id@4.1.3: resolution: {integrity: sha512-tsYlhAYpjCKa//8rXZ9DqKEawhPoSytweBC2eNvcaDK+57RZLHGqNs3PZTQO6yekLFSuvA6AlnAfrw1uBvtb+Q==} hasBin: true + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + iconv-lite@0.6.3: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} @@ -1866,6 +2520,13 @@ packages: inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + is-deflate@1.0.0: + resolution: {integrity: sha512-YDoFpuZWu1VRXlsnlYMzKyVRITXj7Ej/V9gXQ2/pAe7X1J7M/RNOqaIYi6qUn+B7nGyB9pDXrv02dsB58d2ZAQ==} + is-docker@2.2.1: resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} engines: {node: '>=8'} @@ -1883,6 +2544,10 @@ packages: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} + is-gzip@1.0.0: + resolution: {integrity: sha512-rcfALRIb1YewtnksfRIHGcIY93QnK8BIQ/2c9yDYcG/Y6+vRoJuTWBmmSEbyLLYtXm7q35pHOHbZFQBaLrhlWQ==} + engines: {node: '>=0.10.0'} + is-interactive@1.0.0: resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} engines: {node: '>=8'} @@ -1891,6 +2556,9 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + is-promise@2.2.2: + resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==} + is-reference@3.0.3: resolution: {integrity: sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==} @@ -1898,6 +2566,9 @@ packages: resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} engines: {node: '>=4'} + is-typedarray@1.0.0: + resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} + is-unicode-supported@0.1.0: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} @@ -1910,9 +2581,15 @@ packages: resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} engines: {node: '>=8'} + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + isstream@0.1.2: + resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} + jest-diff@30.2.0: resolution: {integrity: sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -1925,10 +2602,17 @@ packages: resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} hasBin: true + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + js-yaml@4.1.1: resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true + jsbn@0.1.1: + resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} + jsesc@3.1.0: resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} engines: {node: '>=6'} @@ -1937,12 +2621,24 @@ packages: json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + json-schema-ref-resolver@1.0.1: + resolution: {integrity: sha512-EJAj1pgHc1hxF6vo2Z3s69fMjO1INq6eGHXZ8Z6wCQeldCuwxGK9Sxf4/cScGn3FZubCVUehfWtcDM/PLteCQw==} + json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-schema@0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} @@ -1954,6 +2650,38 @@ packages: jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + jsonparse@1.3.1: + resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} + engines: {'0': node >= 0.2.0} + + jsonwebtoken@9.0.0: + resolution: {integrity: sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==} + engines: {node: '>=12', npm: '>=6'} + + jsonwebtoken@9.0.3: + resolution: {integrity: sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==} + engines: {node: '>=12', npm: '>=6'} + + jsprim@2.0.2: + resolution: {integrity: sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==} + engines: {'0': node >=0.6.0} + + jwa@1.4.2: + resolution: {integrity: sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==} + + jwa@2.0.1: + resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==} + + jws@3.2.3: + resolution: {integrity: sha512-byiJ0FLRdLdSVSReO/U4E7RoEyOCKnEnEPMjq3HxWtvzLsV08/i5RQKsFVNkCldrCaPr2vDNAOMsfs8T/Hze7g==} + + jws@4.0.1: + resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==} + + keygrip@1.1.0: + resolution: {integrity: sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==} + engines: {node: '>= 0.6'} + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -1969,6 +2697,9 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} + light-my-request@5.14.0: + resolution: {integrity: sha512-aORPWntbpH5esaYpGOOmri0OHDOe3wC5M2MQxZ9dvMLZm6DnaAn0kJlcbU9hwsQgLzmZyReKwFwwPkR+nHu5kA==} + lines-and-columns@2.0.3: resolution: {integrity: sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -1987,16 +2718,65 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} + lockfile@1.0.4: + resolution: {integrity: sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA==} + + lodash-es@4.17.23: + resolution: {integrity: sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==} + + lodash.includes@4.3.0: + resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} + + lodash.isboolean@3.0.3: + resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} + + lodash.isinteger@4.0.4: + resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==} + + lodash.isnumber@3.0.3: + resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==} + + lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + + lodash.isstring@4.0.1: + resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} + lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + lodash.once@4.1.1: + resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} + lodash.startcase@4.4.0: resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + lodash@4.17.23: + resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==} + log-symbols@4.1.0: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} + lowdb@1.0.0: + resolution: {integrity: sha512-2+x8esE/Wb9SQ1F9IHaYWfsC9FIecLOPrK4g17FGEayjUWH172H6nwicRovGvSE2CPZouc2MCIqCI7h9d+GftQ==} + engines: {node: '>=4'} + + lowercase-keys@2.0.0: + resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} + engines: {node: '>=8'} + + lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + + lru-cache@7.18.3: + resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} + engines: {node: '>=12'} + lunr@2.3.9: resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} @@ -2022,10 +2802,24 @@ packages: mdurl@2.0.0: resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + + merge-descriptors@1.0.1: + resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} + + merge-descriptors@1.0.3: + resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} + merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} + methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} @@ -2038,10 +2832,33 @@ packages: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + mime@2.6.0: + resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} + engines: {node: '>=4.0.0'} + hasBin: true + + mime@3.0.0: + resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} + engines: {node: '>=10.0.0'} + hasBin: true + mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} + mimic-response@1.0.1: + resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} + engines: {node: '>=4'} + + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + minimatch@10.1.1: resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} engines: {node: 20 || >=22} @@ -2053,6 +2870,14 @@ packages: minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + minimatch@7.4.6: + resolution: {integrity: sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==} + engines: {node: '>=10'} + + minimatch@7.4.9: + resolution: {integrity: sha512-Brg/fp/iAVDOQoHxkuN5bEYhyQlZhxddI78yWsCbeEwTHXQjlNLtiJDUsp1GIptVqMI7/gkJMz4vVAc01mpoBw==} + engines: {node: '>=10'} + minimatch@9.0.3: resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} engines: {node: '>=16 || 14 >=14.17'} @@ -2064,13 +2889,27 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + nanoclone@0.2.1: + resolution: {integrity: sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==} + nanoid@3.3.11: resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -2084,6 +2923,26 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + negotiator@0.6.4: + resolution: {integrity: sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==} + engines: {node: '>= 0.6'} + + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + + node-fetch@2.6.7: + resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} engines: {node: 4.x || >=6.0.0} @@ -2096,6 +2955,10 @@ packages: node-machine-id@1.1.12: resolution: {integrity: sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==} + normalize-url@6.1.0: + resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} + engines: {node: '>=10'} + npm-run-path@4.0.1: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} @@ -2115,9 +2978,33 @@ packages: '@swc/core': optional: true + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + obug@2.1.1: resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + on-exit-leak-free@2.1.2: + resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} + engines: {node: '>=14.0.0'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + on-headers@1.0.2: + resolution: {integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==} + engines: {node: '>= 0.8'} + + on-headers@1.1.0: + resolution: {integrity: sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==} + engines: {node: '>= 0.8'} + once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} @@ -2143,6 +3030,10 @@ packages: oxc-resolver@11.16.3: resolution: {integrity: sha512-goLOJH3x69VouGWGp5CgCIHyksmOZzXr36lsRmQz1APg3SPFORrvV2q7nsUHMzLVa6ZJgNwkgUSJFsbCpAWkCA==} + p-cancelable@2.1.1: + resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} + engines: {node: '>=8'} + p-filter@2.1.0: resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} engines: {node: '>=8'} @@ -2174,6 +3065,9 @@ packages: package-manager-detector@0.2.11: resolution: {integrity: sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==} + pako@0.2.9: + resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -2187,6 +3081,10 @@ packages: parse5@7.3.0: resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -2195,6 +3093,12 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} + path-to-regexp@0.1.12: + resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} + + path-to-regexp@0.1.7: + resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} + path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -2202,6 +3106,12 @@ packages: pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + peek-stream@1.1.3: + resolution: {integrity: sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA==} + + performance-now@2.1.0: + resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -2213,10 +3123,41 @@ packages: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} + pify@3.0.0: + resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} + engines: {node: '>=4'} + pify@4.0.1: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} engines: {node: '>=6'} + pino-abstract-transport@1.0.0: + resolution: {integrity: sha512-c7vo5OpW4wIS42hUVcT5REsL8ZljsUfBjqV/e2sFxmFEFZiq1XLUp5EYLtuDH6PEHq9W1egWqRbnLUP5FuZmOA==} + + pino-abstract-transport@1.2.0: + resolution: {integrity: sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==} + + pino-abstract-transport@2.0.0: + resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==} + + pino-std-serializers@6.2.2: + resolution: {integrity: sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==} + + pino-std-serializers@7.1.0: + resolution: {integrity: sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw==} + + pino@8.14.1: + resolution: {integrity: sha512-8LYNv7BKWXSfS+k6oEc6occy5La+q2sPwU3q2ljTX5AZk7v+5kND2o5W794FyRaqha6DJajmkNRsWtPpFyMUdw==} + hasBin: true + + pino@8.21.0: + resolution: {integrity: sha512-ip4qdzjkAyDDZklUaZkcRFb2iA118H9SgRh8yzTkSQK8HilsOJF7rSY8HoW5+I0M46AZgX/pxbprf2vvzQCE0Q==} + hasBin: true + + pino@9.14.0: + resolution: {integrity: sha512-8OEwKp5juEvb/MjpIc4hjqfgCNysrS94RIOMXYvpYCdm/jglrKEiAYmiumbmGhCvs+IcInsphYDFwqrjr7398w==} + hasBin: true + postcss@8.5.6: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} @@ -2245,9 +3186,44 @@ packages: resolution: {integrity: sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + process-warning@1.0.0: + resolution: {integrity: sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==} + + process-warning@2.3.2: + resolution: {integrity: sha512-n9wh8tvBe5sFmsqlg+XQhaQLumwpqoAUruLwjCopgTmUBjJ/fjtBsJzKleCaIGBOMXYEhp1YfKl4d7rJ5ZKJGA==} + + process-warning@3.0.0: + resolution: {integrity: sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==} + + process-warning@5.0.0: + resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==} + + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + + property-expr@2.0.6: + resolution: {integrity: sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + pump@2.0.1: + resolution: {integrity: sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==} + + pump@3.0.4: + resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} + + pumpify@1.5.1: + resolution: {integrity: sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==} + punycode.js@2.3.1: resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} engines: {node: '>=6'} @@ -2256,6 +3232,14 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + qs@6.11.0: + resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} + engines: {node: '>=0.6'} + + qs@6.14.2: + resolution: {integrity: sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==} + engines: {node: '>=0.6'} + quansync@0.2.11: resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} @@ -2265,6 +3249,29 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + quick-format-unescaped@4.0.4: + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + + quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@2.5.1: + resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} + engines: {node: '>= 0.8'} + + raw-body@2.5.2: + resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} + engines: {node: '>= 0.8'} + + raw-body@2.5.3: + resolution: {integrity: sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==} + engines: {node: '>= 0.8'} + react-is@18.3.1: resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} @@ -2272,14 +3279,32 @@ packages: resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} engines: {node: '>=6'} + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} + readable-stream@4.7.0: + resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + real-require@0.2.0: + resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} + engines: {node: '>= 12.13.0'} + require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + resolve-alpn@1.2.1: + resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} + resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -2295,14 +3320,24 @@ packages: resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==} engines: {node: '>=10'} + responselike@2.0.1: + resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} + restore-cursor@3.1.0: resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} engines: {node: '>=8'} + ret@0.2.2: + resolution: {integrity: sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==} + engines: {node: '>=4'} + reusify@1.1.0: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + rolldown-plugin-dts@0.20.0: resolution: {integrity: sha512-cLAY1kN2ilTYMfZcFlGWbXnu6Nb+8uwUBsi+Mjbh4uIx7IN8uMOmJ7RxrrRgPsO4H7eSz3E+JwGoL1gyugiyUA==} engines: {node: '>=20.19.0'} @@ -2340,17 +3375,70 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + safe-regex2@2.0.0: + resolution: {integrity: sha512-PaUSFsUaNNuKwkBijoAPHAK6/eM6VirvyPWlZ7BAQy4D+hCvh4B6lIG+nPdhbFfIbP+gTGBcrdsOaUs0F+ZBOQ==} + + safe-stable-stringify@2.5.0: + resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} + engines: {node: '>=10'} + safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + sanitize-filename@1.6.3: + resolution: {integrity: sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==} + + secure-json-parse@2.7.0: + resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} + + semver@7.5.4: + resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + engines: {node: '>=10'} + hasBin: true + + semver@7.7.2: + resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} + engines: {node: '>=10'} + hasBin: true + semver@7.7.3: resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} engines: {node: '>=10'} hasBin: true + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + + send@0.18.0: + resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} + engines: {node: '>= 0.8.0'} + + send@0.19.2: + resolution: {integrity: sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==} + engines: {node: '>= 0.8.0'} + + serve-static@1.15.0: + resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} + engines: {node: '>= 0.8.0'} + + serve-static@1.16.3: + resolution: {integrity: sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==} + engines: {node: '>= 0.8.0'} + + set-cookie-parser@2.7.2: + resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -2403,6 +3491,22 @@ packages: resolution: {integrity: sha512-DHg6+Pj7ORhYyC+CaSAr8DeRxqf9GXB90yqLmUILPtY7WhZuJatMir3id2MNjuF5I/1313SbrTTItIDu//G4jg==} hasBin: true + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} @@ -2421,16 +3525,38 @@ packages: resolution: {integrity: sha512-4zemZi0HvTnYwLfrpk/CF9LOd9Lt87kAt50GnqhMpyF9U3poDAP2+iukq2bZsO/ufegbYehBkqINbsWxj4l4cw==} engines: {node: '>= 18'} + sonic-boom@3.3.0: + resolution: {integrity: sha512-LYxp34KlZ1a2Jb8ZQgFCK3niIHzibdwtwNUWKg0qQRzsDoJ3Gfgkf8KdBTFU3SkejDEIlWwnSnpVdOZIhFMl/g==} + + sonic-boom@3.8.1: + resolution: {integrity: sha512-y4Z8LCDBuum+PBP3lSV7RHrXscqksve/bi0as7mhwVnBW+/wUqKT/2Kb7um8yqcFy0duYbbPxzt89Zy2nOCaxg==} + + sonic-boom@4.2.1: + resolution: {integrity: sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q==} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + spawndamnit@3.0.1: resolution: {integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==} + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + sshpk@1.18.0: + resolution: {integrity: sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==} + engines: {node: '>=0.10.0'} + hasBin: true + stable-hash-x@0.2.0: resolution: {integrity: sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==} engines: {node: '>=12.0.0'} @@ -2438,13 +3564,33 @@ packages: stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + std-env@3.10.0: resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + steno@0.4.4: + resolution: {integrity: sha512-EEHMVYHNXFHfGtgjNITnka0aHhiAlo93F7z2/Pwd+g0teG9CnM3JIINM7hVVB5/rhw9voufD7Wukwgtw2uqh6w==} + + stream-shift@1.0.3: + resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} + + streamx@2.23.0: + resolution: {integrity: sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==} + string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} @@ -2480,10 +3626,32 @@ packages: resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} engines: {node: '>=6'} + tar-stream@3.1.7: + resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} + term-size@2.2.1: resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} engines: {node: '>=8'} + text-decoder@1.2.7: + resolution: {integrity: sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==} + + thread-stream@2.7.0: + resolution: {integrity: sha512-qQiRWsU/wvNolI6tbbCKd9iKaTnCXsTwVxhhKM6nctPdujTyztjlbUkUTUymidWcMnZ5pWR0ej4a0tjsW021vw==} + + thread-stream@3.1.0: + resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} + + through2@2.0.5: + resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} + + through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + + tiny-lru@11.4.7: + resolution: {integrity: sha512-w/Te7uMUVeH0CR8vZIjr+XiN41V+30lkDdK+NRIDCUYKKuL9VcmaUEmaPISuwGhLlrTGh5yu18lENtR9axSxYw==} + engines: {node: '>=12'} + tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} @@ -2499,6 +3667,13 @@ packages: resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} engines: {node: '>=14.0.0'} + tldts-core@6.1.86: + resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==} + + tldts@6.1.86: + resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} + hasBin: true + tmp@0.2.5: resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} engines: {node: '>=14.14'} @@ -2507,6 +3682,17 @@ packages: 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'} + + toposort@2.0.2: + resolution: {integrity: sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==} + + tough-cookie@5.1.2: + resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==} + engines: {node: '>=16'} + tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} @@ -2514,6 +3700,9 @@ packages: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true + truncate-utf8-bytes@1.0.2: + resolution: {integrity: sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==} + ts-api-utils@2.4.0: resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==} engines: {node: '>=18.12'} @@ -2557,10 +3746,27 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsscmp@1.0.6: + resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==} + engines: {node: '>=0.6.x'} + + tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + + tweetnacl@0.14.5: + resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} + + typanion@3.14.0: + resolution: {integrity: sha512-ZW/lVMRabETuYCd9O9ZvMhAh8GslSqaUjxmK/JLPCh6l73CvLBiuXswj/+7LdnWOgYsQ130FqLzFz5aGT4I3Ug==} + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} + type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + typedoc-plugin-frontmatter@1.3.0: resolution: {integrity: sha512-xYQFMAecMlsRUjmf9oM/Sq2FVz4zlgcbIeVFNLdO118CHTN06gIKJNSlyExh9+Xl8sK0YhIvoQwViUURxritWA==} peerDependencies: @@ -2594,6 +3800,11 @@ packages: uc.micro@2.1.0: resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + uglify-js@3.19.3: + resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} + engines: {node: '>=0.8.0'} + hasBin: true + unconfig-core@7.5.0: resolution: {integrity: sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w==} @@ -2611,8 +3822,15 @@ packages: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} - unrs-resolver@1.11.1: - resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} + unix-crypt-td-js@1.1.4: + resolution: {integrity: sha512-8rMeVYWSIyccIJscb9NdCfZKSRBKYTeVnwmiRYT2ulE3qd1RaDQ0xQDP+rI3ccIWbhu/zuo5cgN8z73belNZgw==} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + unrs-resolver@1.11.1: + resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} unrun@0.2.27: resolution: {integrity: sha512-Mmur1UJpIbfxasLOhPRvox/QS4xBiDii71hMP7smfRthGcwFL2OAmYRgduLANOAU4LUkvVamuP+02U+c90jlrw==} @@ -2627,9 +3845,57 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + utf8-byte-length@1.0.5: + resolution: {integrity: sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==} + util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + + validator@13.15.26: + resolution: {integrity: sha512-spH26xU080ydGggxRyR1Yhcbgx+j3y5jbNXk/8L+iRvdIEQ4uTRH2Sgf2dokud6Q4oAtsbNvJ1Ft+9xmm6IZcA==} + engines: {node: '>= 0.10'} + + validator@13.9.0: + resolution: {integrity: sha512-B+dGG8U3fdtM0/aNK4/X8CXq/EcxU2WPrPEkJGslb47qyHsxmbggTWK0yEA4qnYVNF+nxNlN88o14hIcPmSIEA==} + engines: {node: '>= 0.10'} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + verdaccio-audit@11.0.0-6-next.39: + resolution: {integrity: sha512-5RF06RwTsKo+Lg6j89+SAeS+0zPAYefubmJ3zuaJgO5KvS0KGEXdFbBRTj1sB0Ob4hGLMg/9O26BfAraz95k6g==} + engines: {node: '>=12'} + + verdaccio-audit@13.0.0-next-8.33: + resolution: {integrity: sha512-qBMN0b4cbSbo6RbOke0QtVy/HuSzmxgRXIjnXM3C86ZhjN6DlhdeAoQYcZUfbXM8BklRXtObAnMoTlgeJ7BJLA==} + engines: {node: '>=18'} + + verdaccio-htpasswd@11.0.0-6-next.46: + resolution: {integrity: sha512-44yatMvnfmDrYzSvlnaTrk9kzuK+25QEUwfAeu5WPcNUOd5z7UbdccuiXa3wUfClSuppx0nYlERnIptW3C4oNw==} + engines: {node: '>=14', npm: '>=6'} + + verdaccio-htpasswd@13.0.0-next-8.33: + resolution: {integrity: sha512-ZYqvF/EuA4W4idfv2O1ZN8YhSI2xreFbGdrcWgOd+QBedDin7NzMhgypbafutm9mPhkI6Xv/+3syee1u1cEL8g==} + engines: {node: '>=18'} + + verdaccio@6.3.2: + resolution: {integrity: sha512-9BmfrGlakdAW1QNBrD2GgO8hOhwIp6ogbAhaaDgtDsK3/94qXwS6n2PM1/gG2V/zFC5JH1rWbLia390i0xbodA==} + engines: {node: '>=18'} + hasBin: true + + verror@1.10.0: + resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} + engines: {'0': node >=0.6.0} + vite@7.3.1: resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2750,6 +4016,9 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} + wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -2769,10 +4038,17 @@ packages: utf-8-validate: optional: true + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + yaml@2.8.2: resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} engines: {node: '>= 14.6'} @@ -2790,6 +4066,10 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + yup@0.32.11: + resolution: {integrity: sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==} + engines: {node: '>=10'} + zimmerframe@1.1.4: resolution: {integrity: sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==} @@ -2972,6 +4252,27 @@ snapshots: human-id: 4.1.3 prettier: 2.8.8 + '@cypress/request@3.0.10': + dependencies: + aws-sign2: 0.7.0 + aws4: 1.13.2 + caseless: 0.12.0 + combined-stream: 1.0.8 + extend: 3.0.2 + forever-agent: 0.6.1 + form-data: 4.0.5 + http-signature: 1.4.0 + is-typedarray: 1.0.0 + isstream: 0.1.2 + json-stringify-safe: 5.0.1 + mime-types: 2.1.35 + performance-now: 2.1.0 + qs: 6.14.2 + safe-buffer: 5.2.1 + tough-cookie: 5.1.2 + tunnel-agent: 0.6.0 + uuid: 8.3.2 + '@emnapi/core@1.8.1': dependencies: '@emnapi/wasi-threads': 1.1.0 @@ -3115,6 +4416,22 @@ snapshots: '@faker-js/faker@10.2.0': {} + '@fastify/ajv-compiler@3.6.0': + dependencies: + ajv: 8.18.0 + ajv-formats: 2.1.1(ajv@8.18.0) + fast-uri: 2.4.0 + + '@fastify/error@3.4.1': {} + + '@fastify/fast-json-stringify-compiler@4.3.0': + dependencies: + fast-json-stringify: 5.16.1 + + '@fastify/merge-json-schemas@0.1.1': + dependencies: + fast-deep-equal: 3.1.3 + '@gerrit0/mini-shiki@3.23.0': dependencies: '@shikijs/engine-oniguruma': 3.23.0 @@ -3318,6 +4635,8 @@ snapshots: '@oxc-resolver/binding-win32-x64-msvc@11.16.3': optional: true + '@pinojs/redact@0.4.0': {} + '@quansync/fs@1.0.0': dependencies: quansync: 1.0.0 @@ -3505,6 +4824,8 @@ snapshots: '@sinclair/typebox@0.34.47': {} + '@sindresorhus/is@4.6.0': {} + '@standard-schema/spec@1.1.0': {} '@stylistic/eslint-plugin@5.10.0(eslint@9.39.2(jiti@2.6.1))': @@ -3528,6 +4849,10 @@ snapshots: transitivePeerDependencies: - encoding + '@szmarczak/http-timer@4.0.6': + dependencies: + defer-to-connect: 2.0.1 + '@tanstack/eslint-config@0.4.0(@typescript-eslint/utils@8.56.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint/js': 10.0.1(eslint@9.39.2(jiti@2.6.1)) @@ -3576,6 +4901,8 @@ snapshots: '@types/json-schema@7.0.15': {} + '@types/lodash@4.17.24': {} + '@types/node@12.20.55': {} '@types/node@20.19.30': @@ -3586,6 +4913,10 @@ snapshots: dependencies: undici-types: 7.16.0 + '@types/responselike@1.0.0': + dependencies: + '@types/node': 25.0.9 + '@types/unist@3.0.3': {} '@types/whatwg-mimetype@3.0.2': {} @@ -3746,6 +5077,435 @@ snapshots: '@unrs/resolver-binding-win32-x64-msvc@1.11.1': optional: true + '@verdaccio/api@6.0.0-6-next.59': + dependencies: + '@verdaccio/auth': 6.0.0-6-next.55 + '@verdaccio/config': 6.0.0-6-next.76 + '@verdaccio/core': 6.0.0-6-next.76 + '@verdaccio/logger': 6.0.0-6-next.44 + '@verdaccio/middleware': 6.0.0-6-next.55 + '@verdaccio/store': 6.0.0-6-next.56 + '@verdaccio/utils': 6.0.0-6-next.44 + abortcontroller-polyfill: 1.7.5 + body-parser: 1.20.2 + cookies: 0.8.0 + debug: 4.3.4 + express: 4.18.2 + lodash: 4.17.21 + mime: 2.6.0 + semver: 7.5.4 + transitivePeerDependencies: + - supports-color + + '@verdaccio/auth@6.0.0-6-next.55': + dependencies: + '@verdaccio/config': 6.0.0-6-next.76 + '@verdaccio/core': 6.0.0-6-next.76 + '@verdaccio/loaders': 6.0.0-6-next.45 + '@verdaccio/logger': 6.0.0-6-next.44 + '@verdaccio/signature': 6.0.0-6-next.2 + '@verdaccio/utils': 6.0.0-6-next.44 + debug: 4.3.4 + express: 4.18.2 + lodash: 4.17.21 + verdaccio-htpasswd: 11.0.0-6-next.46 + transitivePeerDependencies: + - supports-color + + '@verdaccio/auth@8.0.0-next-8.33': + dependencies: + '@verdaccio/config': 8.0.0-next-8.33 + '@verdaccio/core': 8.0.0-next-8.33 + '@verdaccio/loaders': 8.0.0-next-8.23 + '@verdaccio/signature': 8.0.0-next-8.25 + debug: 4.4.3 + lodash: 4.17.23 + verdaccio-htpasswd: 13.0.0-next-8.33 + transitivePeerDependencies: + - supports-color + + '@verdaccio/config@6.0.0-6-next.76': + dependencies: + '@verdaccio/core': 6.0.0-6-next.76 + '@verdaccio/utils': 6.0.0-6-next.44 + debug: 4.3.4 + js-yaml: 4.1.0 + lodash: 4.17.21 + minimatch: 3.1.2 + yup: 0.32.11 + transitivePeerDependencies: + - supports-color + + '@verdaccio/config@8.0.0-next-8.33': + dependencies: + '@verdaccio/core': 8.0.0-next-8.33 + debug: 4.4.3 + js-yaml: 4.1.1 + lodash: 4.17.23 + transitivePeerDependencies: + - supports-color + + '@verdaccio/core@6.0.0-6-next.76': + dependencies: + ajv: 8.12.0 + core-js: 3.30.2 + http-errors: 2.0.0 + http-status-codes: 2.2.0 + process-warning: 1.0.0 + semver: 7.5.4 + + '@verdaccio/core@8.0.0-next-8.21': + dependencies: + ajv: 8.17.1 + http-errors: 2.0.0 + http-status-codes: 2.3.0 + minimatch: 7.4.6 + process-warning: 1.0.0 + semver: 7.7.2 + + '@verdaccio/core@8.0.0-next-8.33': + dependencies: + ajv: 8.18.0 + http-errors: 2.0.1 + http-status-codes: 2.3.0 + minimatch: 7.4.9 + process-warning: 1.0.0 + semver: 7.7.4 + + '@verdaccio/file-locking@10.3.1': + dependencies: + lockfile: 1.0.4 + + '@verdaccio/file-locking@11.0.0-6-next.7': + dependencies: + lockfile: 1.0.4 + + '@verdaccio/file-locking@13.0.0-next-8.6': + dependencies: + lockfile: 1.0.4 + + '@verdaccio/hooks@6.0.0-6-next.46': + dependencies: + '@verdaccio/core': 6.0.0-6-next.76 + '@verdaccio/logger': 6.0.0-6-next.44 + core-js: 3.30.2 + debug: 4.3.4 + got-cjs: 12.5.4 + handlebars: 4.7.7 + transitivePeerDependencies: + - supports-color + + '@verdaccio/hooks@8.0.0-next-8.33': + dependencies: + '@verdaccio/core': 8.0.0-next-8.33 + '@verdaccio/logger': 8.0.0-next-8.33 + debug: 4.4.3 + got-cjs: 12.5.4 + handlebars: 4.7.8 + transitivePeerDependencies: + - supports-color + + '@verdaccio/loaders@6.0.0-6-next.45': + dependencies: + '@verdaccio/logger': 6.0.0-6-next.44 + debug: 4.3.4 + lodash: 4.17.21 + transitivePeerDependencies: + - supports-color + + '@verdaccio/loaders@8.0.0-next-8.23': + dependencies: + '@verdaccio/core': 8.0.0-next-8.33 + debug: 4.4.3 + lodash: 4.17.23 + transitivePeerDependencies: + - supports-color + + '@verdaccio/local-storage-legacy@11.1.1': + dependencies: + '@verdaccio/core': 8.0.0-next-8.21 + '@verdaccio/file-locking': 10.3.1 + '@verdaccio/streams': 10.2.1 + async: 3.2.6 + debug: 4.4.1 + lodash: 4.17.21 + lowdb: 1.0.0 + mkdirp: 1.0.4 + transitivePeerDependencies: + - supports-color + + '@verdaccio/local-storage@11.0.0-6-next.46': + dependencies: + '@verdaccio/core': 6.0.0-6-next.76 + '@verdaccio/file-locking': 11.0.0-6-next.7 + '@verdaccio/utils': 6.0.0-6-next.44 + core-js: 3.30.2 + debug: 4.3.4 + globby: 11.1.0 + lockfile: 1.0.4 + lodash: 4.17.21 + lowdb: 1.0.0 + lru-cache: 7.18.3 + sanitize-filename: 1.6.3 + transitivePeerDependencies: + - supports-color + + '@verdaccio/logger-commons@6.0.0-6-next.44': + dependencies: + '@verdaccio/core': 6.0.0-6-next.76 + '@verdaccio/logger-prettify': 6.0.0-6-next.10 + colorette: 2.0.20 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + + '@verdaccio/logger-commons@8.0.0-next-8.33': + dependencies: + '@verdaccio/core': 8.0.0-next-8.33 + '@verdaccio/logger-prettify': 8.0.0-next-8.4 + colorette: 2.0.20 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@verdaccio/logger-prettify@6.0.0-6-next.10': + dependencies: + colorette: 2.0.20 + dayjs: 1.11.7 + lodash: 4.17.21 + pino-abstract-transport: 1.0.0 + sonic-boom: 3.3.0 + + '@verdaccio/logger-prettify@8.0.0-next-8.4': + dependencies: + colorette: 2.0.20 + dayjs: 1.11.13 + lodash: 4.17.21 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 1.2.0 + sonic-boom: 3.8.1 + + '@verdaccio/logger@6.0.0-6-next.44': + dependencies: + '@verdaccio/logger-commons': 6.0.0-6-next.44 + pino: 8.14.1 + transitivePeerDependencies: + - supports-color + + '@verdaccio/logger@8.0.0-next-8.33': + dependencies: + '@verdaccio/logger-commons': 8.0.0-next-8.33 + pino: 9.14.0 + transitivePeerDependencies: + - supports-color + + '@verdaccio/middleware@6.0.0-6-next.55': + dependencies: + '@verdaccio/config': 6.0.0-6-next.76 + '@verdaccio/core': 6.0.0-6-next.76 + '@verdaccio/url': 11.0.0-6-next.42 + '@verdaccio/utils': 6.0.0-6-next.44 + debug: 4.3.4 + express: 4.18.2 + express-rate-limit: 5.5.1 + lodash: 4.17.21 + lru-cache: 7.18.3 + mime: 2.6.0 + transitivePeerDependencies: + - supports-color + + '@verdaccio/middleware@8.0.0-next-8.33': + dependencies: + '@verdaccio/config': 8.0.0-next-8.33 + '@verdaccio/core': 8.0.0-next-8.33 + '@verdaccio/url': 13.0.0-next-8.33 + debug: 4.4.3 + express: 4.22.1 + express-rate-limit: 5.5.1 + lodash: 4.17.23 + lru-cache: 7.18.3 + transitivePeerDependencies: + - supports-color + + '@verdaccio/node-api@6.0.0-6-next.76': + dependencies: + '@verdaccio/config': 6.0.0-6-next.76 + '@verdaccio/core': 6.0.0-6-next.76 + '@verdaccio/logger': 6.0.0-6-next.44 + '@verdaccio/server': 6.0.0-6-next.65 + '@verdaccio/server-fastify': 6.0.0-6-next.57 + core-js: 3.30.2 + debug: 4.3.4 + lodash: 4.17.21 + transitivePeerDependencies: + - encoding + - supports-color + + '@verdaccio/proxy@6.0.0-6-next.54': + dependencies: + '@verdaccio/config': 6.0.0-6-next.76 + '@verdaccio/core': 6.0.0-6-next.76 + '@verdaccio/utils': 6.0.0-6-next.44 + JSONStream: 1.3.5 + debug: 4.3.4 + got-cjs: 12.5.4 + hpagent: 1.2.0 + lodash: 4.17.21 + transitivePeerDependencies: + - supports-color + + '@verdaccio/search-indexer@8.0.0-next-8.5': {} + + '@verdaccio/server-fastify@6.0.0-6-next.57': + dependencies: + '@verdaccio/auth': 6.0.0-6-next.55 + '@verdaccio/config': 6.0.0-6-next.76 + '@verdaccio/core': 6.0.0-6-next.76 + '@verdaccio/logger': 6.0.0-6-next.44 + '@verdaccio/store': 6.0.0-6-next.56 + '@verdaccio/tarball': 11.0.0-6-next.45 + '@verdaccio/utils': 6.0.0-6-next.44 + core-js: 3.30.2 + debug: 4.3.4 + fastify: 4.17.0 + fastify-plugin: 4.4.0 + lodash: 4.17.21 + transitivePeerDependencies: + - supports-color + + '@verdaccio/server@6.0.0-6-next.65': + dependencies: + '@verdaccio/api': 6.0.0-6-next.59 + '@verdaccio/auth': 6.0.0-6-next.55 + '@verdaccio/config': 6.0.0-6-next.76 + '@verdaccio/core': 6.0.0-6-next.76 + '@verdaccio/loaders': 6.0.0-6-next.45 + '@verdaccio/logger': 6.0.0-6-next.44 + '@verdaccio/middleware': 6.0.0-6-next.55 + '@verdaccio/store': 6.0.0-6-next.56 + '@verdaccio/utils': 6.0.0-6-next.44 + '@verdaccio/web': 6.0.0-6-next.63 + compression: 1.7.4 + cors: 2.8.5 + debug: 4.3.4 + express: 4.18.2 + lodash: 4.17.21 + verdaccio-audit: 11.0.0-6-next.39 + transitivePeerDependencies: + - encoding + - supports-color + + '@verdaccio/signature@6.0.0-6-next.2': + dependencies: + debug: 4.3.4 + jsonwebtoken: 9.0.0 + lodash: 4.17.21 + transitivePeerDependencies: + - supports-color + + '@verdaccio/signature@8.0.0-next-8.25': + dependencies: + '@verdaccio/config': 8.0.0-next-8.33 + '@verdaccio/core': 8.0.0-next-8.33 + debug: 4.4.3 + jsonwebtoken: 9.0.3 + transitivePeerDependencies: + - supports-color + + '@verdaccio/store@6.0.0-6-next.56': + dependencies: + '@verdaccio/config': 6.0.0-6-next.76 + '@verdaccio/core': 6.0.0-6-next.76 + '@verdaccio/hooks': 6.0.0-6-next.46 + '@verdaccio/loaders': 6.0.0-6-next.45 + '@verdaccio/local-storage': 11.0.0-6-next.46 + '@verdaccio/logger': 6.0.0-6-next.44 + '@verdaccio/proxy': 6.0.0-6-next.54 + '@verdaccio/tarball': 11.0.0-6-next.45 + '@verdaccio/url': 11.0.0-6-next.42 + '@verdaccio/utils': 6.0.0-6-next.44 + JSONStream: 1.3.5 + debug: 4.3.4 + lodash: 4.17.21 + merge2: 1.4.1 + semver: 7.5.4 + transitivePeerDependencies: + - supports-color + + '@verdaccio/streams@10.2.1': {} + + '@verdaccio/tarball@11.0.0-6-next.45': + dependencies: + '@verdaccio/core': 6.0.0-6-next.76 + '@verdaccio/url': 11.0.0-6-next.42 + '@verdaccio/utils': 6.0.0-6-next.44 + debug: 4.3.4 + lodash: 4.17.21 + transitivePeerDependencies: + - supports-color + + '@verdaccio/tarball@13.0.0-next-8.33': + dependencies: + '@verdaccio/core': 8.0.0-next-8.33 + '@verdaccio/url': 13.0.0-next-8.33 + debug: 4.4.3 + gunzip-maybe: 1.4.2 + tar-stream: 3.1.7 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + - supports-color + + '@verdaccio/ui-theme@8.0.0-next-8.30': {} + + '@verdaccio/url@11.0.0-6-next.42': + dependencies: + '@verdaccio/core': 6.0.0-6-next.76 + debug: 4.3.4 + lodash: 4.17.21 + validator: 13.9.0 + transitivePeerDependencies: + - supports-color + + '@verdaccio/url@13.0.0-next-8.33': + dependencies: + '@verdaccio/core': 8.0.0-next-8.33 + debug: 4.4.3 + validator: 13.15.26 + transitivePeerDependencies: + - supports-color + + '@verdaccio/utils@6.0.0-6-next.44': + dependencies: + '@verdaccio/core': 6.0.0-6-next.76 + lodash: 4.17.21 + minimatch: 3.1.2 + semver: 7.5.4 + + '@verdaccio/utils@8.1.0-next-8.33': + dependencies: + '@verdaccio/core': 8.0.0-next-8.33 + lodash: 4.17.23 + minimatch: 7.4.9 + + '@verdaccio/web@6.0.0-6-next.63': + dependencies: + '@verdaccio/auth': 6.0.0-6-next.55 + '@verdaccio/config': 6.0.0-6-next.76 + '@verdaccio/core': 6.0.0-6-next.76 + '@verdaccio/loaders': 6.0.0-6-next.45 + '@verdaccio/logger': 6.0.0-6-next.44 + '@verdaccio/middleware': 6.0.0-6-next.55 + '@verdaccio/store': 6.0.0-6-next.56 + '@verdaccio/tarball': 11.0.0-6-next.45 + '@verdaccio/url': 11.0.0-6-next.42 + '@verdaccio/utils': 6.0.0-6-next.44 + debug: 4.3.4 + express: 4.18.2 + lodash: 4.17.21 + transitivePeerDependencies: + - supports-color + '@vitest/expect@4.0.17': dependencies: '@standard-schema/spec': 1.1.0 @@ -3796,12 +5556,44 @@ snapshots: dependencies: argparse: 2.0.1 + JSONStream@1.3.5: + dependencies: + jsonparse: 1.3.1 + through: 2.3.8 + + abort-controller@3.0.0: + dependencies: + event-target-shim: 5.0.1 + + abortcontroller-polyfill@1.7.5: {} + + abstract-logging@2.0.1: {} + + accepts@1.3.8: + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + acorn-jsx@5.3.2(acorn@8.15.0): dependencies: acorn: 8.15.0 acorn@8.15.0: {} + agent-base@6.0.2: + dependencies: + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + ajv-formats@2.1.1(ajv@8.18.0): + optionalDependencies: + ajv: 8.18.0 + + ajv-formats@3.0.1(ajv@8.18.0): + optionalDependencies: + ajv: 8.18.0 + ajv@6.12.6: dependencies: fast-deep-equal: 3.1.3 @@ -3809,6 +5601,27 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 + ajv@8.12.0: + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js: 4.4.1 + + ajv@8.17.1: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.0 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + ajv@8.18.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.0 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + ansi-colors@4.1.3: {} ansi-regex@5.0.1: {} @@ -3821,6 +5634,8 @@ snapshots: ansis@4.2.0: {} + apache-md5@1.1.8: {} + argparse@1.0.10: dependencies: sprintf-js: 1.0.3 @@ -3829,8 +5644,16 @@ snapshots: aria-query@5.3.2: {} + array-flatten@1.1.1: {} + array-union@2.1.0: {} + asn1@0.2.6: + dependencies: + safer-buffer: 2.1.2 + + assert-plus@1.0.0: {} + assertion-error@2.0.1: {} ast-kit@2.2.0: @@ -3838,8 +5661,21 @@ snapshots: '@babel/parser': 7.29.0 pathe: 2.0.3 + async@3.2.6: {} + asynckit@0.4.0: {} + atomic-sleep@1.0.0: {} + + avvio@8.4.0: + dependencies: + '@fastify/error': 3.4.1 + fastq: 1.20.1 + + aws-sign2@0.7.0: {} + + aws4@1.13.2: {} + axios@1.13.2: dependencies: follow-redirects: 1.15.11 @@ -3850,12 +5686,22 @@ snapshots: axobject-query@4.1.0: {} + b4a@1.8.0: {} + balanced-match@1.0.2: {} balanced-match@4.0.4: {} + bare-events@2.8.2: {} + base64-js@1.5.1: {} + bcrypt-pbkdf@1.0.2: + dependencies: + tweetnacl: 0.14.5 + + bcryptjs@2.4.3: {} + better-path-resolve@1.0.0: dependencies: is-windows: 1.0.2 @@ -3868,6 +5714,57 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 + body-parser@1.20.1: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.11.0 + raw-body: 2.5.1 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + body-parser@1.20.2: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.11.0 + raw-body: 2.5.2 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + body-parser@1.20.4: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.1 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.14.2 + raw-body: 2.5.3 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + boolbase@1.0.0: {} brace-expansion@1.1.12: @@ -3887,20 +5784,56 @@ snapshots: dependencies: fill-range: 7.1.1 + browserify-zlib@0.1.4: + dependencies: + pako: 0.2.9 + + buffer-equal-constant-time@1.0.1: {} + + buffer-from@1.1.2: {} + buffer@5.7.1: dependencies: base64-js: 1.5.1 ieee754: 1.2.1 + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + bytes@3.0.0: {} + + bytes@3.1.2: {} + cac@6.7.14: {} + cacheable-lookup@6.1.0: {} + + cacheable-request@7.0.2: + dependencies: + clone-response: 1.0.3 + get-stream: 5.2.0 + http-cache-semantics: 4.2.0 + keyv: 4.5.4 + lowercase-keys: 2.0.0 + normalize-url: 6.1.0 + responselike: 2.0.1 + call-bind-apply-helpers@1.0.2: dependencies: es-errors: 1.3.0 function-bind: 1.1.2 + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + callsites@3.1.0: {} + caseless@0.12.0: {} + chai@6.2.2: {} chalk@4.1.2: @@ -3941,12 +5874,20 @@ snapshots: cli-spinners@2.6.1: {} + clipanion@4.0.0-rc.4(typanion@3.14.0): + dependencies: + typanion: 3.14.0 + cliui@8.0.1: dependencies: string-width: 4.2.3 strip-ansi: 6.0.1 wrap-ansi: 7.0.0 + clone-response@1.0.3: + dependencies: + mimic-response: 1.0.1 + clone@1.0.4: {} clsx@2.1.1: {} @@ -3957,14 +5898,79 @@ snapshots: color-name@1.1.4: {} + colorette@2.0.20: {} + combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 comment-parser@1.4.4: {} + compressible@2.0.18: + dependencies: + mime-db: 1.52.0 + + compression@1.7.4: + dependencies: + accepts: 1.3.8 + bytes: 3.0.0 + compressible: 2.0.18 + debug: 2.6.9 + on-headers: 1.0.2 + safe-buffer: 5.1.2 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + compression@1.8.1: + dependencies: + bytes: 3.1.2 + compressible: 2.0.18 + debug: 2.6.9 + negotiator: 0.6.4 + on-headers: 1.1.0 + safe-buffer: 5.2.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + concat-map@0.0.1: {} + content-disposition@0.5.4: + dependencies: + safe-buffer: 5.2.1 + + content-type@1.0.5: {} + + cookie-signature@1.0.6: {} + + cookie-signature@1.0.7: {} + + cookie@0.5.0: {} + + cookie@0.7.2: {} + + cookies@0.8.0: + dependencies: + depd: 2.0.0 + keygrip: 1.1.0 + + core-js@3.30.2: {} + + core-util-is@1.0.2: {} + + core-util-is@1.0.3: {} + + cors@2.8.5: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + + cors@2.8.6: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 @@ -3981,24 +5987,54 @@ snapshots: css-what@6.2.2: {} + dashdash@1.14.1: + dependencies: + assert-plus: 1.0.0 + dataloader@1.4.0: {} + dayjs@1.11.13: {} + + dayjs@1.11.7: {} + + debug@2.6.9: + dependencies: + ms: 2.0.0 + + debug@4.3.4: + dependencies: + ms: 2.1.2 + + debug@4.4.1: + dependencies: + ms: 2.1.3 + debug@4.4.3: dependencies: ms: 2.1.3 + decompress-response@6.0.0: + dependencies: + mimic-response: 3.1.0 + deep-is@0.1.4: {} defaults@1.0.4: dependencies: clone: 1.0.4 + defer-to-connect@2.0.1: {} + define-lazy-prop@2.0.0: {} defu@6.1.4: {} delayed-stream@1.0.0: {} + depd@2.0.0: {} + + destroy@1.2.0: {} + detect-indent@6.1.0: {} devalue@5.6.2: {} @@ -4043,10 +6079,32 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 + duplexify@3.7.1: + dependencies: + end-of-stream: 1.4.5 + inherits: 2.0.4 + readable-stream: 2.3.8 + stream-shift: 1.0.3 + + ecc-jsbn@0.1.2: + dependencies: + jsbn: 0.1.1 + safer-buffer: 2.1.2 + + ecdsa-sig-formatter@1.0.11: + dependencies: + safe-buffer: 5.2.1 + + ee-first@1.1.1: {} + emoji-regex@8.0.0: {} empathic@2.0.0: {} + encodeurl@1.0.2: {} + + encodeurl@2.0.0: {} + encoding-sniffer@0.2.1: dependencies: iconv-lite: 0.6.3 @@ -4074,6 +6132,8 @@ snapshots: entities@6.0.1: {} + envinfo@7.21.0: {} + es-define-property@1.0.1: {} es-errors@1.3.0: {} @@ -4122,6 +6182,8 @@ snapshots: escalade@3.2.0: {} + escape-html@1.0.3: {} + escape-string-regexp@1.0.5: {} escape-string-regexp@4.0.0: {} @@ -4271,12 +6333,108 @@ snapshots: esutils@2.0.3: {} + etag@1.8.1: {} + + event-target-shim@5.0.1: {} + + events-universal@1.0.1: + dependencies: + bare-events: 2.8.2 + transitivePeerDependencies: + - bare-abort-controller + + events@3.3.0: {} + expect-type@1.3.0: {} + express-rate-limit@5.5.1: {} + + express@4.18.2: + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.1 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.5.0 + cookie-signature: 1.0.6 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.2.0 + fresh: 0.5.2 + http-errors: 2.0.0 + merge-descriptors: 1.0.1 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.7 + proxy-addr: 2.0.7 + qs: 6.11.0 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.18.0 + serve-static: 1.15.0 + setprototypeof: 1.2.0 + statuses: 2.0.1 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + express@4.22.1: + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.4 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.0.7 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.3.2 + fresh: 0.5.2 + http-errors: 2.0.1 + merge-descriptors: 1.0.3 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.12 + proxy-addr: 2.0.7 + qs: 6.14.2 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.19.2 + serve-static: 1.16.3 + setprototypeof: 1.2.0 + statuses: 2.0.2 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + extend@3.0.2: {} + extendable-error@0.1.7: {} + extsprintf@1.3.0: {} + + fast-content-type-parse@1.1.0: {} + + fast-decode-uri-component@1.0.1: {} + fast-deep-equal@3.1.3: {} + fast-fifo@1.3.2: {} + fast-glob@3.3.3: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -4287,8 +6445,49 @@ snapshots: fast-json-stable-stringify@2.1.0: {} + fast-json-stringify@5.16.1: + dependencies: + '@fastify/merge-json-schemas': 0.1.1 + ajv: 8.18.0 + ajv-formats: 3.0.1(ajv@8.18.0) + fast-deep-equal: 3.1.3 + fast-uri: 2.4.0 + json-schema-ref-resolver: 1.0.1 + rfdc: 1.4.1 + fast-levenshtein@2.0.6: {} + fast-querystring@1.1.2: + dependencies: + fast-decode-uri-component: 1.0.1 + + fast-redact@3.5.0: {} + + fast-uri@2.4.0: {} + + fast-uri@3.1.0: {} + + fastify-plugin@4.4.0: {} + + fastify@4.17.0: + dependencies: + '@fastify/ajv-compiler': 3.6.0 + '@fastify/error': 3.4.1 + '@fastify/fast-json-stringify-compiler': 4.3.0 + abstract-logging: 2.0.1 + avvio: 8.4.0 + fast-content-type-parse: 1.1.0 + fast-json-stringify: 5.16.1 + find-my-way: 7.7.0 + light-my-request: 5.14.0 + pino: 8.21.0 + process-warning: 2.3.2 + proxy-addr: 2.0.7 + rfdc: 1.4.1 + secure-json-parse: 2.7.0 + semver: 7.7.3 + tiny-lru: 11.4.7 + fastq@1.20.1: dependencies: reusify: 1.1.0 @@ -4313,6 +6512,36 @@ snapshots: dependencies: to-regex-range: 5.0.1 + finalhandler@1.2.0: + dependencies: + debug: 2.6.9 + encodeurl: 1.0.2 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.1 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + finalhandler@1.3.2: + dependencies: + debug: 2.6.9 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.2 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + find-my-way@7.7.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-querystring: 1.1.2 + safe-regex2: 2.0.0 + find-up@4.1.0: dependencies: locate-path: 5.0.0 @@ -4334,6 +6563,10 @@ snapshots: follow-redirects@1.15.11: {} + forever-agent@0.6.1: {} + + form-data-encoder@1.7.2: {} + form-data@4.0.5: dependencies: asynckit: 0.4.0 @@ -4346,6 +6579,10 @@ snapshots: dependencies: fd-package-json: 2.0.0 + forwarded@0.2.0: {} + + fresh@0.5.2: {} + front-matter@4.0.2: dependencies: js-yaml: 3.14.2 @@ -4389,10 +6626,20 @@ snapshots: dunder-proto: 1.0.1 es-object-atoms: 1.1.1 + get-stream@5.2.0: + dependencies: + pump: 3.0.4 + + get-stream@6.0.1: {} + get-tsconfig@4.13.0: dependencies: resolve-pkg-maps: 1.0.0 + getpass@0.1.7: + dependencies: + assert-plus: 1.0.0 + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -4420,8 +6667,50 @@ snapshots: gopd@1.2.0: {} + got-cjs@12.5.4: + dependencies: + '@sindresorhus/is': 4.6.0 + '@szmarczak/http-timer': 4.0.6 + '@types/responselike': 1.0.0 + cacheable-lookup: 6.1.0 + cacheable-request: 7.0.2 + decompress-response: 6.0.0 + form-data-encoder: 1.7.2 + get-stream: 6.0.1 + http2-wrapper: 2.2.1 + lowercase-keys: 2.0.0 + p-cancelable: 2.1.1 + responselike: 2.0.1 + graceful-fs@4.2.11: {} + gunzip-maybe@1.4.2: + dependencies: + browserify-zlib: 0.1.4 + is-deflate: 1.0.0 + is-gzip: 1.0.0 + peek-stream: 1.1.3 + pumpify: 1.5.1 + through2: 2.0.5 + + handlebars@4.7.7: + dependencies: + minimist: 1.2.8 + neo-async: 2.6.2 + source-map: 0.6.1 + wordwrap: 1.0.0 + optionalDependencies: + uglify-js: 3.19.3 + + handlebars@4.7.8: + dependencies: + minimist: 1.2.8 + neo-async: 2.6.2 + source-map: 0.6.1 + wordwrap: 1.0.0 + optionalDependencies: + uglify-js: 3.19.3 + happy-dom@20.3.1: dependencies: '@types/node': 20.19.30 @@ -4447,6 +6736,8 @@ snapshots: hookable@6.0.1: {} + hpagent@1.2.0: {} + html-link-extractor@1.0.5: dependencies: cheerio: 1.1.2 @@ -4458,8 +6749,52 @@ snapshots: domutils: 3.2.2 entities: 6.0.1 + http-cache-semantics@4.2.0: {} + + http-errors@2.0.0: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + + http-signature@1.4.0: + dependencies: + assert-plus: 1.0.0 + jsprim: 2.0.2 + sshpk: 1.18.0 + + http-status-codes@2.2.0: {} + + http-status-codes@2.3.0: {} + + http2-wrapper@2.2.1: + dependencies: + quick-lru: 5.1.1 + resolve-alpn: 1.2.1 + + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + human-id@4.1.3: {} + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + iconv-lite@0.6.3: dependencies: safer-buffer: 2.1.2 @@ -4485,6 +6820,10 @@ snapshots: inherits@2.0.4: {} + ipaddr.js@1.9.1: {} + + is-deflate@1.0.0: {} + is-docker@2.2.1: {} is-extglob@2.1.1: {} @@ -4495,10 +6834,14 @@ snapshots: dependencies: is-extglob: 2.1.1 + is-gzip@1.0.0: {} + is-interactive@1.0.0: {} is-number@7.0.0: {} + is-promise@2.2.2: {} + is-reference@3.0.3: dependencies: '@types/estree': 1.0.8 @@ -4507,6 +6850,8 @@ snapshots: dependencies: better-path-resolve: 1.0.0 + is-typedarray@1.0.0: {} + is-unicode-supported@0.1.0: {} is-windows@1.0.2: {} @@ -4515,8 +6860,12 @@ snapshots: dependencies: is-docker: 2.2.1 + isarray@1.0.0: {} + isexe@2.0.0: {} + isstream@0.1.2: {} + jest-diff@30.2.0: dependencies: '@jest/diff-sequences': 30.0.1 @@ -4531,18 +6880,34 @@ snapshots: argparse: 1.0.10 esprima: 4.0.1 + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + js-yaml@4.1.1: dependencies: argparse: 2.0.1 + jsbn@0.1.1: {} + jsesc@3.1.0: {} json-buffer@3.0.1: {} + json-schema-ref-resolver@1.0.1: + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse@0.4.1: {} + json-schema-traverse@1.0.0: {} + + json-schema@0.4.0: {} + json-stable-stringify-without-jsonify@1.0.1: {} + json-stringify-safe@5.0.1: {} + json5@2.2.3: {} jsonc-parser@3.2.0: {} @@ -4551,6 +6916,61 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 + jsonparse@1.3.1: {} + + jsonwebtoken@9.0.0: + dependencies: + jws: 3.2.3 + lodash: 4.17.21 + ms: 2.1.3 + semver: 7.7.3 + + jsonwebtoken@9.0.3: + dependencies: + jws: 4.0.1 + lodash.includes: 4.3.0 + lodash.isboolean: 3.0.3 + lodash.isinteger: 4.0.4 + lodash.isnumber: 3.0.3 + lodash.isplainobject: 4.0.6 + lodash.isstring: 4.0.1 + lodash.once: 4.1.1 + ms: 2.1.3 + semver: 7.7.4 + + jsprim@2.0.2: + dependencies: + assert-plus: 1.0.0 + extsprintf: 1.3.0 + json-schema: 0.4.0 + verror: 1.10.0 + + jwa@1.4.2: + dependencies: + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: 5.2.1 + + jwa@2.0.1: + dependencies: + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: 5.2.1 + + jws@3.2.3: + dependencies: + jwa: 1.4.2 + safe-buffer: 5.2.1 + + jws@4.0.1: + dependencies: + jwa: 2.0.1 + safe-buffer: 5.2.1 + + keygrip@1.1.0: + dependencies: + tsscmp: 1.0.6 + keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -4577,6 +6997,12 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 + light-my-request@5.14.0: + dependencies: + cookie: 0.7.2 + process-warning: 3.0.0 + set-cookie-parser: 2.7.2 + lines-and-columns@2.0.3: {} linkify-it@5.0.0: @@ -4589,19 +7015,59 @@ snapshots: dependencies: p-locate: 4.1.0 - locate-path@6.0.0: - dependencies: - p-locate: 5.0.0 + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lockfile@1.0.4: + dependencies: + signal-exit: 3.0.7 + + lodash-es@4.17.23: {} + + lodash.includes@4.3.0: {} + + lodash.isboolean@3.0.3: {} + + lodash.isinteger@4.0.4: {} + + lodash.isnumber@3.0.3: {} + + lodash.isplainobject@4.0.6: {} + + lodash.isstring@4.0.1: {} lodash.merge@4.6.2: {} + lodash.once@4.1.1: {} + lodash.startcase@4.4.0: {} + lodash@4.17.21: {} + + lodash@4.17.23: {} + log-symbols@4.1.0: dependencies: chalk: 4.1.2 is-unicode-supported: 0.1.0 + lowdb@1.0.0: + dependencies: + graceful-fs: 4.2.11 + is-promise: 2.2.2 + lodash: 4.17.23 + pify: 3.0.0 + steno: 0.4.4 + + lowercase-keys@2.0.0: {} + + lru-cache@6.0.0: + dependencies: + yallist: 4.0.0 + + lru-cache@7.18.3: {} + lunr@2.3.9: {} magic-string@0.30.21: @@ -4628,8 +7094,16 @@ snapshots: mdurl@2.0.0: {} + media-typer@0.3.0: {} + + merge-descriptors@1.0.1: {} + + merge-descriptors@1.0.3: {} + merge2@1.4.1: {} + methods@1.1.2: {} + micromatch@4.0.8: dependencies: braces: 3.0.3 @@ -4641,8 +7115,18 @@ snapshots: dependencies: mime-db: 1.52.0 + mime@1.6.0: {} + + mime@2.6.0: {} + + mime@3.0.0: {} + mimic-fn@2.1.0: {} + mimic-response@1.0.1: {} + + mimic-response@3.1.0: {} + minimatch@10.1.1: dependencies: '@isaacs/brace-expansion': 5.0.0 @@ -4655,6 +7139,14 @@ snapshots: dependencies: brace-expansion: 1.1.12 + minimatch@7.4.6: + dependencies: + brace-expansion: 2.0.2 + + minimatch@7.4.9: + dependencies: + brace-expansion: 2.0.2 + minimatch@9.0.3: dependencies: brace-expansion: 2.0.2 @@ -4665,22 +7157,42 @@ snapshots: minimist@1.2.8: {} + mkdirp@1.0.4: {} + mri@1.2.0: {} + ms@2.0.0: {} + + ms@2.1.2: {} + ms@2.1.3: {} + nanoclone@0.2.1: {} + nanoid@3.3.11: {} napi-postinstall@0.3.4: {} natural-compare@1.4.0: {} + negotiator@0.6.3: {} + + negotiator@0.6.4: {} + + neo-async@2.6.2: {} + + node-fetch@2.6.7: + dependencies: + whatwg-url: 5.0.0 + node-fetch@2.7.0: dependencies: whatwg-url: 5.0.0 node-machine-id@1.1.12: {} + normalize-url@6.1.0: {} + npm-run-path@4.0.1: dependencies: path-key: 3.1.1 @@ -4740,8 +7252,22 @@ snapshots: transitivePeerDependencies: - debug + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + obug@2.1.1: {} + on-exit-leak-free@2.1.2: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + on-headers@1.0.2: {} + + on-headers@1.1.0: {} + once@1.4.0: dependencies: wrappy: 1.0.2 @@ -4801,6 +7327,8 @@ snapshots: '@oxc-resolver/binding-win32-ia32-msvc': 11.16.3 '@oxc-resolver/binding-win32-x64-msvc': 11.16.3 + p-cancelable@2.1.1: {} + p-filter@2.1.0: dependencies: p-map: 2.1.0 @@ -4829,6 +7357,8 @@ snapshots: dependencies: quansync: 0.2.11 + pako@0.2.9: {} + parent-module@1.0.1: dependencies: callsites: 3.1.0 @@ -4846,22 +7376,98 @@ snapshots: dependencies: entities: 6.0.1 + parseurl@1.3.3: {} + path-exists@4.0.0: {} path-key@3.1.1: {} + path-to-regexp@0.1.12: {} + + path-to-regexp@0.1.7: {} + path-type@4.0.0: {} pathe@2.0.3: {} + peek-stream@1.1.3: + dependencies: + buffer-from: 1.1.2 + duplexify: 3.7.1 + through2: 2.0.5 + + performance-now@2.1.0: {} + picocolors@1.1.1: {} picomatch@2.3.1: {} picomatch@4.0.3: {} + pify@3.0.0: {} + pify@4.0.1: {} + pino-abstract-transport@1.0.0: + dependencies: + readable-stream: 4.7.0 + split2: 4.2.0 + + pino-abstract-transport@1.2.0: + dependencies: + readable-stream: 4.7.0 + split2: 4.2.0 + + pino-abstract-transport@2.0.0: + dependencies: + split2: 4.2.0 + + pino-std-serializers@6.2.2: {} + + pino-std-serializers@7.1.0: {} + + pino@8.14.1: + dependencies: + atomic-sleep: 1.0.0 + fast-redact: 3.5.0 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 1.0.0 + pino-std-serializers: 6.2.2 + process-warning: 2.3.2 + quick-format-unescaped: 4.0.4 + real-require: 0.2.0 + safe-stable-stringify: 2.5.0 + sonic-boom: 3.8.1 + thread-stream: 2.7.0 + + pino@8.21.0: + dependencies: + atomic-sleep: 1.0.0 + fast-redact: 3.5.0 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 1.2.0 + pino-std-serializers: 6.2.2 + process-warning: 3.0.0 + quick-format-unescaped: 4.0.4 + real-require: 0.2.0 + safe-stable-stringify: 2.5.0 + sonic-boom: 3.8.1 + thread-stream: 2.7.0 + + pino@9.14.0: + dependencies: + '@pinojs/redact': 0.4.0 + atomic-sleep: 1.0.0 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 2.0.0 + pino-std-serializers: 7.1.0 + process-warning: 5.0.0 + quick-format-unescaped: 4.0.4 + real-require: 0.2.0 + safe-stable-stringify: 2.5.0 + sonic-boom: 4.2.1 + thread-stream: 3.1.0 + postcss@8.5.6: dependencies: nanoid: 3.3.11 @@ -4885,18 +7491,88 @@ snapshots: ansi-styles: 5.2.0 react-is: 18.3.1 + process-nextick-args@2.0.1: {} + + process-warning@1.0.0: {} + + process-warning@2.3.2: {} + + process-warning@3.0.0: {} + + process-warning@5.0.0: {} + + process@0.11.10: {} + + property-expr@2.0.6: {} + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + proxy-from-env@1.1.0: {} + pump@2.0.1: + dependencies: + end-of-stream: 1.4.5 + once: 1.4.0 + + pump@3.0.4: + dependencies: + end-of-stream: 1.4.5 + once: 1.4.0 + + pumpify@1.5.1: + dependencies: + duplexify: 3.7.1 + inherits: 2.0.4 + pump: 2.0.1 + punycode.js@2.3.1: {} punycode@2.3.1: {} + qs@6.11.0: + dependencies: + side-channel: 1.1.0 + + qs@6.14.2: + dependencies: + side-channel: 1.1.0 + quansync@0.2.11: {} quansync@1.0.0: {} queue-microtask@1.2.3: {} + quick-format-unescaped@4.0.4: {} + + quick-lru@5.1.1: {} + + range-parser@1.2.1: {} + + raw-body@2.5.1: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + raw-body@2.5.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + raw-body@2.5.3: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + react-is@18.3.1: {} read-yaml-file@1.1.0: @@ -4906,14 +7582,38 @@ snapshots: pify: 4.0.1 strip-bom: 3.0.0 + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + readable-stream@3.6.2: dependencies: inherits: 2.0.4 string_decoder: 1.3.0 util-deprecate: 1.0.2 + readable-stream@4.7.0: + dependencies: + abort-controller: 3.0.0 + buffer: 6.0.3 + events: 3.3.0 + process: 0.11.10 + string_decoder: 1.3.0 + + real-require@0.2.0: {} + require-directory@2.1.1: {} + require-from-string@2.0.2: {} + + resolve-alpn@1.2.1: {} + resolve-from@4.0.0: {} resolve-from@5.0.0: {} @@ -4922,13 +7622,21 @@ snapshots: resolve.exports@2.0.3: {} + responselike@2.0.1: + dependencies: + lowercase-keys: 2.0.0 + restore-cursor@3.1.0: dependencies: onetime: 5.1.2 signal-exit: 3.0.7 + ret@0.2.2: {} + reusify@1.1.0: {} + rfdc@1.4.1: {} + rolldown-plugin-dts@0.20.0(oxc-resolver@11.16.3)(rolldown@1.0.0-beta.59)(typescript@5.9.3): dependencies: '@babel/generator': 7.29.1 @@ -5018,12 +7726,92 @@ snapshots: dependencies: queue-microtask: 1.2.3 + safe-buffer@5.1.2: {} + safe-buffer@5.2.1: {} + safe-regex2@2.0.0: + dependencies: + ret: 0.2.2 + + safe-stable-stringify@2.5.0: {} + safer-buffer@2.1.2: {} + sanitize-filename@1.6.3: + dependencies: + truncate-utf8-bytes: 1.0.2 + + secure-json-parse@2.7.0: {} + + semver@7.5.4: + dependencies: + lru-cache: 6.0.0 + + semver@7.7.2: {} + semver@7.7.3: {} + semver@7.7.4: {} + + send@0.18.0: + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.0 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + + send@0.19.2: + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.1 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + serve-static@1.15.0: + dependencies: + encodeurl: 1.0.2 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.18.0 + transitivePeerDependencies: + - supports-color + + serve-static@1.16.3: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.19.2 + transitivePeerDependencies: + - supports-color + + set-cookie-parser@2.7.2: {} + + setprototypeof@1.2.0: {} + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -5065,6 +7853,34 @@ snapshots: sherif-windows-arm64: 1.10.0 sherif-windows-x64: 1.10.0 + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + siginfo@2.0.0: {} signal-exit@3.0.7: {} @@ -5075,27 +7891,78 @@ snapshots: smol-toml@1.6.0: {} + sonic-boom@3.3.0: + dependencies: + atomic-sleep: 1.0.0 + + sonic-boom@3.8.1: + dependencies: + atomic-sleep: 1.0.0 + + sonic-boom@4.2.1: + dependencies: + atomic-sleep: 1.0.0 + source-map-js@1.2.1: {} + source-map@0.6.1: {} + spawndamnit@3.0.1: dependencies: cross-spawn: 7.0.6 signal-exit: 4.1.0 + split2@4.2.0: {} + sprintf-js@1.0.3: {} + sshpk@1.18.0: + dependencies: + asn1: 0.2.6 + assert-plus: 1.0.0 + bcrypt-pbkdf: 1.0.2 + dashdash: 1.14.1 + ecc-jsbn: 0.1.2 + getpass: 0.1.7 + jsbn: 0.1.1 + safer-buffer: 2.1.2 + tweetnacl: 0.14.5 + stable-hash-x@0.2.0: {} stackback@0.0.2: {} + statuses@2.0.1: {} + + statuses@2.0.2: {} + std-env@3.10.0: {} + steno@0.4.4: + dependencies: + graceful-fs: 4.2.11 + + stream-shift@1.0.3: {} + + streamx@2.23.0: + dependencies: + events-universal: 1.0.1 + fast-fifo: 1.3.2 + text-decoder: 1.2.7 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + string_decoder@1.3.0: dependencies: safe-buffer: 5.2.1 @@ -5142,8 +8009,40 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 + tar-stream@3.1.7: + dependencies: + b4a: 1.8.0 + fast-fifo: 1.3.2 + streamx: 2.23.0 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + term-size@2.2.1: {} + text-decoder@1.2.7: + dependencies: + b4a: 1.8.0 + transitivePeerDependencies: + - react-native-b4a + + thread-stream@2.7.0: + dependencies: + real-require: 0.2.0 + + thread-stream@3.1.0: + dependencies: + real-require: 0.2.0 + + through2@2.0.5: + dependencies: + readable-stream: 2.3.8 + xtend: 4.0.2 + + through@2.3.8: {} + + tiny-lru@11.4.7: {} + tinybench@2.9.0: {} tinyexec@1.0.2: {} @@ -5155,16 +8054,34 @@ snapshots: tinyrainbow@3.0.3: {} + tldts-core@6.1.86: {} + + tldts@6.1.86: + dependencies: + tldts-core: 6.1.86 + tmp@0.2.5: {} to-regex-range@5.0.1: dependencies: is-number: 7.0.0 + toidentifier@1.0.1: {} + + toposort@2.0.2: {} + + tough-cookie@5.1.2: + dependencies: + tldts: 6.1.86 + tr46@0.0.3: {} tree-kill@1.2.2: {} + truncate-utf8-bytes@1.0.2: + dependencies: + utf8-byte-length: 1.0.5 + ts-api-utils@2.4.0(typescript@5.9.3): dependencies: typescript: 5.9.3 @@ -5209,10 +8126,25 @@ snapshots: tslib@2.8.1: {} + tsscmp@1.0.6: {} + + tunnel-agent@0.6.0: + dependencies: + safe-buffer: 5.2.1 + + tweetnacl@0.14.5: {} + + typanion@3.14.0: {} + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 + type-is@1.6.18: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + typedoc-plugin-frontmatter@1.3.0(typedoc-plugin-markdown@4.9.0(typedoc@0.28.14(typescript@5.9.3))): dependencies: typedoc-plugin-markdown: 4.9.0(typedoc@0.28.14(typescript@5.9.3)) @@ -5246,6 +8178,9 @@ snapshots: uc.micro@2.1.0: {} + uglify-js@3.19.3: + optional: true + unconfig-core@7.5.0: dependencies: '@quansync/fs': 1.0.0 @@ -5259,6 +8194,10 @@ snapshots: universalify@0.1.2: {} + unix-crypt-td-js@1.1.4: {} + + unpipe@1.0.0: {} + unrs-resolver@1.11.1: dependencies: napi-postinstall: 0.3.4 @@ -5291,8 +8230,112 @@ snapshots: dependencies: punycode: 2.3.1 + utf8-byte-length@1.0.5: {} + util-deprecate@1.0.2: {} + utils-merge@1.0.1: {} + + uuid@8.3.2: {} + + validator@13.15.26: {} + + validator@13.9.0: {} + + vary@1.1.2: {} + + verdaccio-audit@11.0.0-6-next.39: + dependencies: + '@verdaccio/config': 6.0.0-6-next.76 + '@verdaccio/core': 6.0.0-6-next.76 + express: 4.18.2 + https-proxy-agent: 5.0.1 + node-fetch: 2.6.7 + transitivePeerDependencies: + - encoding + - supports-color + + verdaccio-audit@13.0.0-next-8.33: + dependencies: + '@verdaccio/config': 8.0.0-next-8.33 + '@verdaccio/core': 8.0.0-next-8.33 + express: 4.22.1 + https-proxy-agent: 5.0.1 + node-fetch: 2.6.7 + transitivePeerDependencies: + - encoding + - supports-color + + verdaccio-htpasswd@11.0.0-6-next.46: + dependencies: + '@verdaccio/core': 6.0.0-6-next.76 + '@verdaccio/file-locking': 11.0.0-6-next.7 + apache-md5: 1.1.8 + bcryptjs: 2.4.3 + core-js: 3.30.2 + debug: 4.3.4 + http-errors: 2.0.0 + unix-crypt-td-js: 1.1.4 + transitivePeerDependencies: + - supports-color + + verdaccio-htpasswd@13.0.0-next-8.33: + dependencies: + '@verdaccio/core': 8.0.0-next-8.33 + '@verdaccio/file-locking': 13.0.0-next-8.6 + apache-md5: 1.1.8 + bcryptjs: 2.4.3 + debug: 4.4.3 + http-errors: 2.0.1 + unix-crypt-td-js: 1.1.4 + transitivePeerDependencies: + - supports-color + + verdaccio@6.3.2(typanion@3.14.0): + dependencies: + '@cypress/request': 3.0.10 + '@verdaccio/auth': 8.0.0-next-8.33 + '@verdaccio/config': 8.0.0-next-8.33 + '@verdaccio/core': 8.0.0-next-8.33 + '@verdaccio/hooks': 8.0.0-next-8.33 + '@verdaccio/loaders': 8.0.0-next-8.23 + '@verdaccio/local-storage-legacy': 11.1.1 + '@verdaccio/logger': 8.0.0-next-8.33 + '@verdaccio/middleware': 8.0.0-next-8.33 + '@verdaccio/search-indexer': 8.0.0-next-8.5 + '@verdaccio/signature': 8.0.0-next-8.25 + '@verdaccio/streams': 10.2.1 + '@verdaccio/tarball': 13.0.0-next-8.33 + '@verdaccio/ui-theme': 8.0.0-next-8.30 + '@verdaccio/url': 13.0.0-next-8.33 + '@verdaccio/utils': 8.1.0-next-8.33 + JSONStream: 1.3.5 + async: 3.2.6 + clipanion: 4.0.0-rc.4(typanion@3.14.0) + compression: 1.8.1 + cors: 2.8.6 + debug: 4.4.3 + envinfo: 7.21.0 + express: 4.22.1 + lodash: 4.17.23 + lru-cache: 7.18.3 + mime: 3.0.0 + semver: 7.7.4 + verdaccio-audit: 13.0.0-next-8.33 + verdaccio-htpasswd: 13.0.0-next-8.33 + transitivePeerDependencies: + - bare-abort-controller + - encoding + - react-native-b4a + - supports-color + - typanion + + verror@1.10.0: + dependencies: + assert-plus: 1.0.0 + core-util-is: 1.0.2 + extsprintf: 1.3.0 + vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(yaml@2.8.2): dependencies: esbuild: 0.27.2 @@ -5389,6 +8432,8 @@ snapshots: word-wrap@1.2.5: {} + wordwrap@1.0.0: {} + wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 @@ -5399,8 +8444,12 @@ snapshots: ws@8.19.0: {} + xtend@4.0.2: {} + y18n@5.0.8: {} + yallist@4.0.0: {} + yaml@2.8.2: {} yargs-parser@21.1.1: {} @@ -5417,6 +8466,16 @@ snapshots: yocto-queue@0.1.0: {} + yup@0.32.11: + dependencies: + '@babel/runtime': 7.28.6 + '@types/lodash': 4.17.24 + lodash: 4.17.21 + lodash-es: 4.17.23 + nanoclone: 0.2.1 + property-expr: 2.0.6 + toposort: 2.0.2 + zimmerframe@1.1.4: {} zod@4.3.5: {} From a87c4b4f2442a36261efec855ac2b03c272efa29 Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Sat, 14 Mar 2026 12:03:42 -0600 Subject: [PATCH 09/17] test: add 49-test integration grid for scanner across PM/structure/depth combos Create scanner-integration.test.ts with a 4x3x4 test matrix covering all package managers (npm, pnpm, yarn, bun), project structures (single, monorepo-root, monorepo-workspace), and dependency chain depths (direct through transitive+3), plus a symlink invocation test. Fix scaffold.ts to use Verdaccio CLI process instead of broken programmatic API, add htpasswd auth config, and handle npm publish authentication via temporary .npmrc files. Co-Authored-By: Claude Opus 4.6 (1M context) --- packages/intent/tests/integration/scaffold.ts | 88 +++++++++++++++---- .../integration/scanner-integration.test.ts | 87 ++++++++++++++++++ 2 files changed, 157 insertions(+), 18 deletions(-) create mode 100644 packages/intent/tests/integration/scanner-integration.test.ts diff --git a/packages/intent/tests/integration/scaffold.ts b/packages/intent/tests/integration/scaffold.ts index 814ec4f..bebbcaa 100644 --- a/packages/intent/tests/integration/scaffold.ts +++ b/packages/intent/tests/integration/scaffold.ts @@ -1,4 +1,4 @@ -import { execSync, execFileSync } from 'node:child_process' +import { execSync, execFileSync, spawn } from 'node:child_process' import { mkdirSync, mkdtempSync, @@ -26,16 +26,22 @@ export interface Registry { } export async function startRegistry(): Promise { - const { runServer } = await import('@verdaccio/node-api') - const storageDir = mkdtempSync(join(realTmpdir, 'verdaccio-storage-')) const port = 6000 + Math.floor(Math.random() * 4000) const configPath = join(storageDir, 'config.yaml') + const htpasswdPath = join(storageDir, 'htpasswd') + writeFileSync(htpasswdPath, '') + writeFileSync( configPath, [ `storage: ${storageDir}`, + `listen: 0.0.0.0:${port}`, + 'auth:', + ' htpasswd:', + ` file: ${htpasswdPath}`, + ' max_users: 100', 'uplinks:', ' npmjs:', ' url: https://registry.npmjs.org/', @@ -46,23 +52,57 @@ export async function startRegistry(): Promise { " '**':", ' access: $all', ' proxy: npmjs', - 'log: { type: stdout, format: pretty, level: fatal }', + 'log: { type: stdout, format: pretty, level: warn }', ].join('\n'), ) - const app = await runServer(configPath) + const verdaccioBin = join(thisDir, '..', '..', 'node_modules', '.bin', 'verdaccio') return new Promise((resolve, reject) => { - const server = app.listen(port, () => { - resolve({ - url: `http://localhost:${port}`, - stop: () => { - server.close() - rmSync(storageDir, { recursive: true, force: true }) - }, - }) + const child = spawn(verdaccioBin, ['--config', configPath, '--listen', String(port)], { + stdio: ['ignore', 'pipe', 'pipe'], + detached: false, + }) + + let started = false + const timeout = setTimeout(() => { + if (!started) { + child.kill() + reject(new Error('Verdaccio failed to start within 15s')) + } + }, 15_000) + + const onData = (chunk: Buffer) => { + const text = chunk.toString() + if (text.includes('http address') || text.includes('warn') || text.includes('---')) { + if (!started) { + started = true + clearTimeout(timeout) + resolve({ + url: `http://localhost:${port}`, + stop: () => { + child.kill('SIGTERM') + rmSync(storageDir, { recursive: true, force: true }) + }, + }) + } + } + } + + child.stdout?.on('data', onData) + child.stderr?.on('data', onData) + + child.on('error', (err) => { + clearTimeout(timeout) + reject(err) + }) + + child.on('exit', (code) => { + if (!started) { + clearTimeout(timeout) + reject(new Error(`Verdaccio exited with code ${code} before starting`)) + } }) - server.on('error', reject) }) } @@ -71,12 +111,24 @@ export async function startRegistry(): Promise { // --------------------------------------------------------------------------- export function publishFixtures(registryUrl: string): void { + // Register a user with Verdaccio so npm publish has auth + const host = new URL(registryUrl).host + const npmrc = `//${host}/:_authToken=test-token\nregistry=${registryUrl}\n` + // Order matters: leaf first, then wrappers that depend on it for (const pkg of ['skills-leaf', 'wrapper-1', 'wrapper-2', 'wrapper-3']) { - execSync(`npm publish --registry ${registryUrl} --access public`, { - cwd: join(fixturesDir, pkg), - stdio: 'ignore', - }) + const pkgDir = join(fixturesDir, pkg) + // Write a local .npmrc so npm publish can authenticate + writeFileSync(join(pkgDir, '.npmrc'), npmrc) + try { + execSync(`npm publish --registry ${registryUrl} --access public`, { + cwd: pkgDir, + stdio: 'pipe', + }) + } finally { + // Clean up the .npmrc so it doesn't pollute the fixture + rmSync(join(pkgDir, '.npmrc'), { force: true }) + } } } diff --git a/packages/intent/tests/integration/scanner-integration.test.ts b/packages/intent/tests/integration/scanner-integration.test.ts new file mode 100644 index 0000000..f7a232b --- /dev/null +++ b/packages/intent/tests/integration/scanner-integration.test.ts @@ -0,0 +1,87 @@ +import { rmSync } from 'node:fs' +import { afterAll, beforeAll, describe, expect, it } from 'vitest' +import type { PackageManager, ProjectStructure, Registry } from './scaffold.js' +import { + publishFixtures, + runScanner, + scaffoldProject, + startRegistry, +} from './scaffold.js' + +const PACKAGE_MANAGERS: Array = ['npm', 'pnpm', 'yarn', 'bun'] +const STRUCTURES: Array = [ + 'single', + 'monorepo-root', + 'monorepo-workspace', +] +const DEPENDENCY_CHAINS: Array<{ label: string; dep: string }> = [ + { label: 'direct', dep: '@test-intent/skills-leaf' }, + { label: 'transitive+1', dep: '@test-intent/wrapper-1' }, + { label: 'transitive+2', dep: '@test-intent/wrapper-2' }, + { label: 'transitive+3', dep: '@test-intent/wrapper-3' }, +] + +let registry: Registry +const tempDirs: Array = [] + +beforeAll(async () => { + registry = await startRegistry() + publishFixtures(registry.url) +}, 30_000) + +afterAll(() => { + registry?.stop() + for (const dir of tempDirs) { + rmSync(dir, { recursive: true, force: true }) + } +}) + +describe.each(PACKAGE_MANAGERS)('package manager: %s', (pm) => { + describe.each(STRUCTURES)('structure: %s', (structure) => { + describe.each(DEPENDENCY_CHAINS)('dependency: $label', ({ dep }) => { + it('discovers @test-intent/skills-leaf and its core skill', () => { + const { root, cwd } = scaffoldProject({ + pm, + structure, + dependency: dep, + registryUrl: registry.url, + }) + tempDirs.push(root) + + const result = runScanner(cwd) + + expect(result.exitCode).toBe(0) + expect(result.parsed).toBeTruthy() + expect(result.parsed.packages).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + name: '@test-intent/skills-leaf', + version: '1.0.0', + skills: expect.arrayContaining([ + expect.objectContaining({ name: 'core', type: 'core' }), + ]), + }), + ]), + ) + }, 60_000) + }) + }) +}) + +describe('symlink invocation', () => { + it('finds skills when CLI is invoked through a symlink', () => { + const { root, cwd } = scaffoldProject({ + pm: 'npm', + structure: 'single', + dependency: '@test-intent/skills-leaf', + registryUrl: registry.url, + }) + tempDirs.push(root) + + const result = runScanner(cwd, 'symlink') + + expect(result.exitCode).toBe(0) + expect(result.parsed.packages).toHaveLength(1) + expect(result.parsed.packages[0].name).toBe('@test-intent/skills-leaf') + }, 60_000) +}) From fccd8a337fab03704177f3f406b550c224e48ccb Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Sat, 14 Mar 2026 12:05:34 -0600 Subject: [PATCH 10/17] fix: add --provenance=false to npm publish, fix test:lib exclude pattern --- packages/intent/package.json | 2 +- packages/intent/tests/integration/scaffold.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/intent/package.json b/packages/intent/package.json index e24faf4..c10c621 100644 --- a/packages/intent/package.json +++ b/packages/intent/package.json @@ -37,7 +37,7 @@ "scripts": { "prepack": "npm run build", "build": "tsdown src/index.ts src/cli.ts src/setup.ts src/intent-library.ts src/library-scanner.ts --format esm --dts", - "test:lib": "vitest run --exclude tests/integration/**", + "test:lib": "vitest run --exclude 'tests/integration/**'", "test:integration": "vitest run tests/integration/", "test:types": "tsc --noEmit" } diff --git a/packages/intent/tests/integration/scaffold.ts b/packages/intent/tests/integration/scaffold.ts index bebbcaa..b6e725d 100644 --- a/packages/intent/tests/integration/scaffold.ts +++ b/packages/intent/tests/integration/scaffold.ts @@ -121,7 +121,7 @@ export function publishFixtures(registryUrl: string): void { // Write a local .npmrc so npm publish can authenticate writeFileSync(join(pkgDir, '.npmrc'), npmrc) try { - execSync(`npm publish --registry ${registryUrl} --access public`, { + execSync(`npm publish --registry ${registryUrl} --access public --provenance=false`, { cwd: pkgDir, stdio: 'pipe', }) From bf50f7dee7d34c5aff121ea99261fc8504102c70 Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Sat, 14 Mar 2026 15:07:23 -0600 Subject: [PATCH 11/17] fix: handle export maps, isolate npm cache, detect lockfiles from workspace root Three fixes from external review: 1. resolveDepDir: fall back to walking node_modules dirs when createRequire fails on packages with export maps that don't expose ./package.json 2. publishFixtures: isolate npm cache and userconfig to temp dirs to avoid EPERM on host's ~/.npm/_cacache 3. detectPackageManager: check workspace root for lockfiles when scanning from a workspace package subdir Co-Authored-By: Claude Opus 4.6 (1M context) --- packages/intent/src/scanner.ts | 17 +++++++---- packages/intent/src/utils.ts | 29 ++++++++++++------- packages/intent/tests/integration/scaffold.ts | 16 +++++----- 3 files changed, 40 insertions(+), 22 deletions(-) diff --git a/packages/intent/src/scanner.ts b/packages/intent/src/scanner.ts index 2b104aa..c6e8ac2 100644 --- a/packages/intent/src/scanner.ts +++ b/packages/intent/src/scanner.ts @@ -8,6 +8,7 @@ import { resolveDepDir, } from './utils.js' import { + findWorkspaceRoot, readWorkspacePatterns, resolveWorkspacePackages, } from './setup.js' @@ -44,11 +45,17 @@ function detectPackageManager(root: string): PackageManager { ) } - if (existsSync(join(root, 'pnpm-lock.yaml'))) return 'pnpm' - if (existsSync(join(root, 'bun.lockb')) || existsSync(join(root, 'bun.lock'))) - return 'bun' - if (existsSync(join(root, 'yarn.lock'))) return 'yarn' - if (existsSync(join(root, 'package-lock.json'))) return 'npm' + const dirsToCheck = [root] + const wsRoot = findWorkspaceRoot(root) + if (wsRoot && wsRoot !== root) dirsToCheck.push(wsRoot) + + for (const dir of dirsToCheck) { + if (existsSync(join(dir, 'pnpm-lock.yaml'))) return 'pnpm' + if (existsSync(join(dir, 'bun.lockb')) || existsSync(join(dir, 'bun.lock'))) + return 'bun' + if (existsSync(join(dir, 'yarn.lock'))) return 'yarn' + if (existsSync(join(dir, 'package-lock.json'))) return 'npm' + } return 'unknown' } diff --git a/packages/intent/src/utils.ts b/packages/intent/src/utils.ts index 6006793..663f8b6 100644 --- a/packages/intent/src/utils.ts +++ b/packages/intent/src/utils.ts @@ -144,24 +144,33 @@ export function detectGlobalNodeModules(packageManager: string): { } /** - * Resolve the directory of a dependency by name. Uses Node's built-in - * module resolution via createRequire, which handles: - * - Hoisted layouts (npm, yarn, bun) — walks up directory tree - * - pnpm symlinked virtual store — follows symlinks - * - Workspace packages — finds deps at workspace root - * - Nested node_modules — standard Node resolution + * Resolve the directory of a dependency by name. Tries createRequire first + * (handles pnpm symlinks), then falls back to walking up node_modules + * directories (handles packages with export maps that block ./package.json). */ export function resolveDepDir( depName: string, parentDir: string, ): string | null { + // Try createRequire — works for most packages including pnpm virtual store try { - const require = createRequire(join(parentDir, 'package.json')) - const pkgJsonPath = require.resolve(join(depName, 'package.json')) + const req = createRequire(join(parentDir, 'package.json')) + const pkgJsonPath = req.resolve(join(depName, 'package.json')) return dirname(pkgJsonPath) - } catch { - return null + } catch {} + + // Fallback: walk up from parentDir checking node_modules/. + // Handles packages with exports maps that don't expose ./package.json. + let dir = parentDir + while (true) { + const candidate = join(dir, 'node_modules', depName) + if (existsSync(join(candidate, 'package.json'))) return candidate + const parent = dirname(dir) + if (parent === dir) break + dir = parent } + + return null } /** diff --git a/packages/intent/tests/integration/scaffold.ts b/packages/intent/tests/integration/scaffold.ts index b6e725d..002eba6 100644 --- a/packages/intent/tests/integration/scaffold.ts +++ b/packages/intent/tests/integration/scaffold.ts @@ -111,25 +111,27 @@ export async function startRegistry(): Promise { // --------------------------------------------------------------------------- export function publishFixtures(registryUrl: string): void { - // Register a user with Verdaccio so npm publish has auth const host = new URL(registryUrl).host const npmrc = `//${host}/:_authToken=test-token\nregistry=${registryUrl}\n` + // Isolate npm cache to avoid EPERM on the host's ~/.npm/_cacache + const cacheDir = mkdtempSync(join(realTmpdir, 'intent-npm-cache-')) + // Order matters: leaf first, then wrappers that depend on it for (const pkg of ['skills-leaf', 'wrapper-1', 'wrapper-2', 'wrapper-3']) { const pkgDir = join(fixturesDir, pkg) - // Write a local .npmrc so npm publish can authenticate writeFileSync(join(pkgDir, '.npmrc'), npmrc) try { - execSync(`npm publish --registry ${registryUrl} --access public --provenance=false`, { - cwd: pkgDir, - stdio: 'pipe', - }) + execSync( + `npm publish --registry ${registryUrl} --access public --provenance=false --cache=${cacheDir} --userconfig=/dev/null`, + { cwd: pkgDir, stdio: 'pipe' }, + ) } finally { - // Clean up the .npmrc so it doesn't pollute the fixture rmSync(join(pkgDir, '.npmrc'), { force: true }) } } + + rmSync(cacheDir, { recursive: true, force: true }) } // --------------------------------------------------------------------------- From 86a520de241e52cc4845232802dd0a0bb6d0120b Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Sat, 14 Mar 2026 15:23:02 -0600 Subject: [PATCH 12/17] fix: apply code review and simplification fixes - resolveDepDir: warn on unexpected errors (not MODULE_NOT_FOUND/ERR_PACKAGE_PATH_NOT_EXPORTED) - walkDepsFromPkgJson: don't include devDeps for workspace packages (only project root) - resolveWorkspacePackages: guard readdirSync with try-catch to avoid aborting scan - Verdaccio startup: use specific port-based detection instead of broad string match - library-scanner.ts: fix 4-arg resolveDepDir call to 2-arg - scanner.ts: extract walkDepsFromPkgJson and walkWorkspacePackages helpers - scaffold.ts: clean up symlink temp dir in finally block Co-Authored-By: Claude Opus 4.6 (1M context) --- packages/intent/src/library-scanner.ts | 5 +-- packages/intent/src/scanner.ts | 43 ++++++++++--------- packages/intent/src/setup.ts | 8 +++- packages/intent/src/utils.ts | 16 ++++++- packages/intent/tests/integration/scaffold.ts | 9 +++- 5 files changed, 53 insertions(+), 28 deletions(-) diff --git a/packages/intent/src/library-scanner.ts b/packages/intent/src/library-scanner.ts index 30de370..d91d00d 100644 --- a/packages/intent/src/library-scanner.ts +++ b/packages/intent/src/library-scanner.ts @@ -91,9 +91,8 @@ function discoverSkills(skillsDir: string): Array { export async function scanLibrary( scriptPath: string, - projectRoot?: string, + _projectRoot?: string, ): Promise { - const nodeModulesDir = join(projectRoot ?? process.cwd(), 'node_modules') const packages: Array = [] const warnings: Array = [] const visited = new Set() @@ -132,7 +131,7 @@ export async function scanLibrary( }) for (const depName of getDeps(pkg)) { - const depDir = resolveDepDir(depName, dir, name, nodeModulesDir) + const depDir = resolveDepDir(depName, dir) if (!depDir) continue const depPkg = readPkgJson(depDir) if (depPkg && hasIntentBin(depPkg)) { diff --git a/packages/intent/src/scanner.ts b/packages/intent/src/scanner.ts index c6e8ac2..32e4108 100644 --- a/packages/intent/src/scanner.ts +++ b/packages/intent/src/scanner.ts @@ -1,4 +1,4 @@ -import { existsSync, readFileSync, readdirSync } from 'node:fs' +import { existsSync, readFileSync, readdirSync, type Dirent } from 'node:fs' import { join, relative, sep } from 'node:path' import { detectGlobalNodeModules, @@ -21,7 +21,6 @@ import type { SkillEntry, VersionConflict, } from './types.js' -import type { Dirent } from 'node:fs' // --------------------------------------------------------------------------- // Package manager detection @@ -378,7 +377,6 @@ export async function scanForIntents(root?: string): Promise { ? existsSync(detected.path) : false } - } function readPkgJson(dirPath: string): Record | null { @@ -525,9 +523,17 @@ export async function scanForIntents(root?: string): Promise { } if (!projectPkg) return + walkDepsFromPkgJson(projectPkg, projectRoot, true) + } - for (const depName of getDeps(projectPkg, true)) { - const depDir = resolveDepDir(depName, projectRoot) + /** Resolve and walk deps listed in a package.json. */ + function walkDepsFromPkgJson( + pkgJson: Record, + fromDir: string, + includeDevDeps = false, + ): void { + for (const depName of getDeps(pkgJson, includeDevDeps)) { + const depDir = resolveDepDir(depName, fromDir) if (depDir && !walkVisited.has(depDir)) { tryRegister(depDir, depName) walkDeps(depDir, depName) @@ -535,13 +541,16 @@ export async function scanForIntents(root?: string): Promise { } } - // Phase 1b: In monorepos, discover workspace packages and walk their deps. - // This handles pnpm monorepos (workspace-specific node_modules) and ensures - // transitive skills packages are found through workspace package dependencies. - const workspacePatterns = readWorkspacePatterns(projectRoot) - if (workspacePatterns) { + /** + * In monorepos, discover workspace packages and walk their deps. + * Handles pnpm monorepos (workspace-specific node_modules) and ensures + * transitive skills packages are found through workspace package dependencies. + */ + function walkWorkspacePackages(): void { + const workspacePatterns = readWorkspacePatterns(projectRoot) + if (!workspacePatterns) return + for (const wsDir of resolveWorkspacePackages(projectRoot, workspacePatterns)) { - // Scan workspace package's own node_modules for skills const wsNodeModules = join(wsDir, 'node_modules') if (existsSync(wsNodeModules)) { for (const dirPath of listNodeModulesPackageDirs(wsNodeModules)) { @@ -549,22 +558,14 @@ export async function scanForIntents(root?: string): Promise { } } - // Walk workspace package's deps to find transitive skills packages. - // createRequire-based resolveDepDir walks up from wsDir, so it finds - // deps hoisted to the monorepo root too. const wsPkg = readPkgJson(wsDir) if (wsPkg) { - for (const depName of getDeps(wsPkg, true)) { - const depDir = resolveDepDir(depName, wsDir) - if (depDir && !walkVisited.has(depDir)) { - tryRegister(depDir, depName) - walkDeps(depDir, depName) - } - } + walkDepsFromPkgJson(wsPkg, wsDir) } } } + walkWorkspacePackages() walkKnownPackages() walkProjectDeps() diff --git a/packages/intent/src/setup.ts b/packages/intent/src/setup.ts index 256895e..92e0004 100644 --- a/packages/intent/src/setup.ts +++ b/packages/intent/src/setup.ts @@ -497,7 +497,13 @@ export function resolveWorkspacePackages( collectPackageDirs(baseDir, dirs) } else if (pattern.endsWith('/*')) { // Single level: direct children - for (const entry of readdirSync(baseDir, { withFileTypes: true })) { + let entries: Array + try { + entries = readdirSync(baseDir, { withFileTypes: true }) + } catch { + continue + } + for (const entry of entries) { if (!entry.isDirectory()) continue const dir = join(baseDir, entry.name) if (existsSync(join(dir, 'package.json'))) { diff --git a/packages/intent/src/utils.ts b/packages/intent/src/utils.ts index 663f8b6..2998870 100644 --- a/packages/intent/src/utils.ts +++ b/packages/intent/src/utils.ts @@ -157,7 +157,21 @@ export function resolveDepDir( const req = createRequire(join(parentDir, 'package.json')) const pkgJsonPath = req.resolve(join(depName, 'package.json')) return dirname(pkgJsonPath) - } catch {} + } catch (err: unknown) { + const code = + err && typeof err === 'object' && 'code' in err + ? (err as NodeJS.ErrnoException).code + : undefined + if ( + code && + code !== 'MODULE_NOT_FOUND' && + code !== 'ERR_PACKAGE_PATH_NOT_EXPORTED' + ) { + console.warn( + `Warning: could not resolve ${depName} from ${parentDir}: ${err instanceof Error ? err.message : String(err)}`, + ) + } + } // Fallback: walk up from parentDir checking node_modules/. // Handles packages with exports maps that don't expose ./package.json. diff --git a/packages/intent/tests/integration/scaffold.ts b/packages/intent/tests/integration/scaffold.ts index 002eba6..63a15da 100644 --- a/packages/intent/tests/integration/scaffold.ts +++ b/packages/intent/tests/integration/scaffold.ts @@ -74,7 +74,7 @@ export async function startRegistry(): Promise { const onData = (chunk: Buffer) => { const text = chunk.toString() - if (text.includes('http address') || text.includes('warn') || text.includes('---')) { + if (text.includes('http address') || text.includes(`localhost:${port}`)) { if (!started) { started = true clearTimeout(timeout) @@ -238,9 +238,10 @@ export function runScanner( method: 'direct' | 'symlink' = 'direct', ): CliResult { let binPath = cliPath + let linkDir: string | undefined if (method === 'symlink') { - const linkDir = mkdtempSync(join(realTmpdir, 'intent-link-')) + linkDir = mkdtempSync(join(realTmpdir, 'intent-link-')) const linkPath = join(linkDir, 'intent-cli.mjs') symlinkSync(cliPath, linkPath) binPath = linkPath @@ -260,6 +261,10 @@ export function runScanner( exitCode: err.status ?? 1, parsed: null, } + } finally { + if (linkDir) { + rmSync(linkDir, { recursive: true, force: true }) + } } } From 2d251d5e28b5e0d724bba287814d26c0e6d22f2d Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Sat, 14 Mar 2026 15:24:07 -0600 Subject: [PATCH 13/17] chore: update changeset to cover full PR scope --- .changeset/fix-npx-symlink-silent-failure.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/fix-npx-symlink-silent-failure.md b/.changeset/fix-npx-symlink-silent-failure.md index 8ab3f1a..dd9851e 100644 --- a/.changeset/fix-npx-symlink-silent-failure.md +++ b/.changeset/fix-npx-symlink-silent-failure.md @@ -2,4 +2,4 @@ '@tanstack/intent': patch --- -Fix CLI silently doing nothing when run via `npx` due to symlink path mismatch in the `isMain` entry-point guard. Also fix 3 pre-existing test failures on macOS caused by `/var` → `/private/var` symlink divergence. +Fix CLI silently doing nothing when run via `npx` due to symlink path mismatch in the `isMain` entry-point guard. Add workspace-aware scanning so `intent list` discovers skills in monorepo workspace packages when run from the monorepo root. Replace `resolveDepDir` with `createRequire`-based resolution that handles hoisted deps, pnpm symlinks, and export maps. The `resolveDepDir` public API signature changed from 4 parameters to 2 — callers using the old signature should update to `resolveDepDir(depName, parentDir)`. From 4f5f66d7cf0b0efb233ea1f0c685adb4b6eb0b38 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Sat, 14 Mar 2026 21:33:56 +0000 Subject: [PATCH 14/17] ci: apply automated fixes --- packages/intent/src/scanner.ts | 5 ++- packages/intent/src/utils.ts | 7 +--- .../integration/skills-leaf/package.json | 4 ++- .../skills-leaf/skills/core/SKILL.md | 2 +- packages/intent/tests/integration/scaffold.ts | 32 +++++++++++++++---- packages/intent/tests/scanner.test.ts | 20 +++++++++--- 6 files changed, 50 insertions(+), 20 deletions(-) diff --git a/packages/intent/src/scanner.ts b/packages/intent/src/scanner.ts index 32e4108..d1b0a12 100644 --- a/packages/intent/src/scanner.ts +++ b/packages/intent/src/scanner.ts @@ -550,7 +550,10 @@ export async function scanForIntents(root?: string): Promise { const workspacePatterns = readWorkspacePatterns(projectRoot) if (!workspacePatterns) return - for (const wsDir of resolveWorkspacePackages(projectRoot, workspacePatterns)) { + for (const wsDir of resolveWorkspacePackages( + projectRoot, + workspacePatterns, + )) { const wsNodeModules = join(wsDir, 'node_modules') if (existsSync(wsNodeModules)) { for (const dirPath of listNodeModulesPackageDirs(wsNodeModules)) { diff --git a/packages/intent/src/utils.ts b/packages/intent/src/utils.ts index 2998870..4e68b5b 100644 --- a/packages/intent/src/utils.ts +++ b/packages/intent/src/utils.ts @@ -1,10 +1,5 @@ import { execFileSync } from 'node:child_process' -import { - existsSync, - readFileSync, - readdirSync, - type Dirent, -} from 'node:fs' +import { existsSync, readFileSync, readdirSync, type Dirent } from 'node:fs' import { createRequire } from 'node:module' import { dirname, join } from 'node:path' import { parse as parseYaml } from 'yaml' diff --git a/packages/intent/tests/fixtures/integration/skills-leaf/package.json b/packages/intent/tests/fixtures/integration/skills-leaf/package.json index b4128e9..57d9021 100644 --- a/packages/intent/tests/fixtures/integration/skills-leaf/package.json +++ b/packages/intent/tests/fixtures/integration/skills-leaf/package.json @@ -6,5 +6,7 @@ "repo": "test/skills-leaf", "docs": "https://example.com/docs" }, - "files": ["skills"] + "files": [ + "skills" + ] } diff --git a/packages/intent/tests/fixtures/integration/skills-leaf/skills/core/SKILL.md b/packages/intent/tests/fixtures/integration/skills-leaf/skills/core/SKILL.md index 786b6d5..0026a88 100644 --- a/packages/intent/tests/fixtures/integration/skills-leaf/skills/core/SKILL.md +++ b/packages/intent/tests/fixtures/integration/skills-leaf/skills/core/SKILL.md @@ -1,6 +1,6 @@ --- name: core -description: "Core skill for integration testing" +description: 'Core skill for integration testing' type: core --- diff --git a/packages/intent/tests/integration/scaffold.ts b/packages/intent/tests/integration/scaffold.ts index 63a15da..f67138a 100644 --- a/packages/intent/tests/integration/scaffold.ts +++ b/packages/intent/tests/integration/scaffold.ts @@ -56,13 +56,24 @@ export async function startRegistry(): Promise { ].join('\n'), ) - const verdaccioBin = join(thisDir, '..', '..', 'node_modules', '.bin', 'verdaccio') + const verdaccioBin = join( + thisDir, + '..', + '..', + 'node_modules', + '.bin', + 'verdaccio', + ) return new Promise((resolve, reject) => { - const child = spawn(verdaccioBin, ['--config', configPath, '--listen', String(port)], { - stdio: ['ignore', 'pipe', 'pipe'], - detached: false, - }) + const child = spawn( + verdaccioBin, + ['--config', configPath, '--listen', String(port)], + { + stdio: ['ignore', 'pipe', 'pipe'], + detached: false, + }, + ) let started = false const timeout = setTimeout(() => { @@ -180,7 +191,10 @@ export function scaffoldProject(opts: { ...(opts.pm !== 'pnpm' ? { workspaces: ['packages/*'] } : {}), }) if (opts.pm === 'pnpm') { - writeFileSync(join(root, 'pnpm-workspace.yaml'), 'packages:\n - packages/*\n') + writeFileSync( + join(root, 'pnpm-workspace.yaml'), + 'packages:\n - packages/*\n', + ) } if (opts.pm === 'yarn') { writeFileSync(join(root, '.yarnrc.yml'), 'nodeLinker: node-modules\n') @@ -211,7 +225,11 @@ function install(dir: string, pm: PackageManager, registryUrl: string): void { execSync(`npm install ${reg}`, { cwd: dir, stdio: 'ignore', env }) break case 'pnpm': - execSync(`pnpm install ${reg} --no-frozen-lockfile`, { cwd: dir, stdio: 'ignore', env }) + execSync(`pnpm install ${reg} --no-frozen-lockfile`, { + cwd: dir, + stdio: 'ignore', + env, + }) break case 'yarn': execSync(`yarn install ${reg}`, { cwd: dir, stdio: 'ignore', env }) diff --git a/packages/intent/tests/scanner.test.ts b/packages/intent/tests/scanner.test.ts index bde3918..1edf70a 100644 --- a/packages/intent/tests/scanner.test.ts +++ b/packages/intent/tests/scanner.test.ts @@ -504,7 +504,11 @@ describe('scanForIntents', () => { writeJson(join(dbDir, 'package.json'), { name: '@tanstack/db', version: '0.5.0', - intent: { version: 1, repo: 'TanStack/db', docs: 'https://db.tanstack.com' }, + intent: { + version: 1, + repo: 'TanStack/db', + docs: 'https://db.tanstack.com', + }, }) writeSkillMd(join(dbDir, 'skills', 'db-core'), { name: 'db-core', @@ -541,7 +545,11 @@ describe('scanForIntents', () => { writeJson(join(dbDir, 'package.json'), { name: '@tanstack/db', version: '0.5.0', - intent: { version: 1, repo: 'TanStack/db', docs: 'https://db.tanstack.com' }, + intent: { + version: 1, + repo: 'TanStack/db', + docs: 'https://db.tanstack.com', + }, }) writeSkillMd(join(dbDir, 'skills', 'db-core'), { name: 'db-core', @@ -571,7 +579,7 @@ describe('scanForIntents', () => { writeJson(join(appDir, 'package.json'), { name: '@monorepo/app', version: '1.0.0', - dependencies: { 'wrapper': '1.0.0' }, + dependencies: { wrapper: '1.0.0' }, }) // wrapper has no skills, but depends on skills-pkg @@ -623,7 +631,11 @@ describe('scanForIntents', () => { writeJson(join(dbDir, 'package.json'), { name: '@tanstack/db', version: '0.5.0', - intent: { version: 1, repo: 'TanStack/db', docs: 'https://db.tanstack.com' }, + intent: { + version: 1, + repo: 'TanStack/db', + docs: 'https://db.tanstack.com', + }, }) writeSkillMd(join(dbDir, 'skills', 'db-core'), { name: 'db-core', From 1fd068b3bb5c76af18a64e3b6d296fcc3a1f3728 Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Sat, 14 Mar 2026 15:34:37 -0600 Subject: [PATCH 15/17] chore: replace changeset for workspace scanning PR --- .changeset/fix-npx-symlink-silent-failure.md | 5 ----- .changeset/workspace-scanning-integration-tests.md | 5 +++++ 2 files changed, 5 insertions(+), 5 deletions(-) delete mode 100644 .changeset/fix-npx-symlink-silent-failure.md create mode 100644 .changeset/workspace-scanning-integration-tests.md diff --git a/.changeset/fix-npx-symlink-silent-failure.md b/.changeset/fix-npx-symlink-silent-failure.md deleted file mode 100644 index dd9851e..0000000 --- a/.changeset/fix-npx-symlink-silent-failure.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/intent': patch ---- - -Fix CLI silently doing nothing when run via `npx` due to symlink path mismatch in the `isMain` entry-point guard. Add workspace-aware scanning so `intent list` discovers skills in monorepo workspace packages when run from the monorepo root. Replace `resolveDepDir` with `createRequire`-based resolution that handles hoisted deps, pnpm symlinks, and export maps. The `resolveDepDir` public API signature changed from 4 parameters to 2 — callers using the old signature should update to `resolveDepDir(depName, parentDir)`. diff --git a/.changeset/workspace-scanning-integration-tests.md b/.changeset/workspace-scanning-integration-tests.md new file mode 100644 index 0000000..7f58cec --- /dev/null +++ b/.changeset/workspace-scanning-integration-tests.md @@ -0,0 +1,5 @@ +--- +'@tanstack/intent': patch +--- + +Add workspace-aware scanning so `intent list` discovers skills in monorepo workspace packages when run from the root. Replace `resolveDepDir` with `createRequire`-based resolution that handles hoisted deps, pnpm symlinks, and export maps. The `resolveDepDir` public API signature changed from 4 parameters to 2 — callers using the old signature should update to `resolveDepDir(depName, parentDir)`. `detectPackageManager` now checks workspace root for lockfiles when scanning from a subdir. From e08f77d39398206561ea4979ba44c3be9bcb19fe Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Sat, 14 Mar 2026 15:37:04 -0600 Subject: [PATCH 16/17] ci: ignore verdaccio devDependencies in knip config --- knip.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/knip.json b/knip.json index 71adfe5..b3a9b9f 100644 --- a/knip.json +++ b/knip.json @@ -14,7 +14,8 @@ "src/intent-library.ts", "src/library-scanner.ts" ], - "ignore": ["meta/**"] + "ignore": ["meta/**"], + "ignoreDependencies": ["verdaccio", "@verdaccio/node-api"] } } } From 94dfa34b692e886dbde067fbde3bf5ebd0a6e924 Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Sun, 15 Mar 2026 09:19:28 -0600 Subject: [PATCH 17/17] chore: gitignore docs/superpowers and remove from index --- .gitignore | 2 + ...14-workspace-scanning-integration-tests.md | 927 ------------------ 2 files changed, 2 insertions(+), 927 deletions(-) delete mode 100644 docs/superpowers/plans/2026-03-14-workspace-scanning-integration-tests.md diff --git a/.gitignore b/.gitignore index 3005d7b..254f72f 100644 --- a/.gitignore +++ b/.gitignore @@ -61,3 +61,5 @@ vite.config.js.timestamp-* vite.config.ts.timestamp-* .angular + +docs/superpowers diff --git a/docs/superpowers/plans/2026-03-14-workspace-scanning-integration-tests.md b/docs/superpowers/plans/2026-03-14-workspace-scanning-integration-tests.md deleted file mode 100644 index 00e536f..0000000 --- a/docs/superpowers/plans/2026-03-14-workspace-scanning-integration-tests.md +++ /dev/null @@ -1,927 +0,0 @@ -# Workspace-Aware Scanning & Integration Tests - -> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking. - -**Goal:** Make the scanner discover skills from workspace packages when run from a monorepo root, fix dep resolution for hoisted workspace layouts, and add integration tests with Verdaccio that verify scanning across all package managers (npm, pnpm, yarn, bun), project structures (single, monorepo root, monorepo workspace), and dependency depths (direct, transitive+1/+2/+3). - -**Architecture:** Three scanner changes: (1) replace `resolveDepDir` with Node's `createRequire` for dependency resolution — this naturally handles hoisted deps, pnpm symlinks, and workspace layouts because Node already walks up the directory tree; (2) add a workspace-aware phase that discovers workspace packages via `pnpm-workspace.yaml` / `package.json#workspaces` and walks their dependencies to find transitive skills packages; (3) export `resolveWorkspacePackages` from `setup.ts`. For integration tests, use Verdaccio (local npm registry) to publish fixture packages, then create real projects with each package manager, install deps, and run the scanner. Follows Knip's pattern: use workspace config to find packages, use Node's built-in module resolution for dep lookup. - -**Tech Stack:** Vitest, Verdaccio / @verdaccio/node-api (dev dependency), npm/pnpm/yarn/bun CLIs - ---- - -## File Structure - -| File | Action | Responsibility | -|------|--------|----------------| -| `packages/intent/src/utils.ts` | Modify | Replace `resolveDepDir` with `createRequire`-based resolution. Keep `listNodeModulesPackageDirs` (used by Phase 1 + workspace scan), `getDeps` (used to extract dep names), `detectGlobalNodeModules` (global install support) | -| `packages/intent/src/setup.ts` | Modify | Export `resolveWorkspacePackages` | -| `packages/intent/src/scanner.ts` | Modify | Use new `resolveDepDir` (2-arg), add workspace scanning phase, add `tryRegister` to `walkProjectDeps`. Keep existing Phase 1 (`scanTarget`), global scanning, and `resolutionRoots` for `listNodeModulesPackageDirs` | -| `packages/intent/tests/scanner.test.ts` | Modify | Add unit tests for workspace scanning | -| `packages/intent/tests/fixtures/integration/skills-leaf/package.json` | Create | Fixture: package with skills | -| `packages/intent/tests/fixtures/integration/skills-leaf/skills/core/SKILL.md` | Create | Fixture: skill file | -| `packages/intent/tests/fixtures/integration/wrapper-1/package.json` | Create | Fixture: depends on skills-leaf | -| `packages/intent/tests/fixtures/integration/wrapper-2/package.json` | Create | Fixture: depends on wrapper-1 | -| `packages/intent/tests/fixtures/integration/wrapper-3/package.json` | Create | Fixture: depends on wrapper-2 | -| `packages/intent/tests/integration/scaffold.ts` | Create | Helpers: Verdaccio lifecycle, project scaffolding, CLI invocation | -| `packages/intent/tests/integration/scanner-integration.test.ts` | Create | Integration test grid | -| `packages/intent/src/scanner-arborist.ts` | Delete | Remove spike file | - ---- - -## Chunk 1: Replace resolveDepDir with createRequire - -### Task 1: Replace `resolveDepDir` in utils.ts - -The current `resolveDepDir` has a hand-rolled 3-layer resolution strategy (hoisted check, nested check, pnpm virtual store walk-up). Node's `createRequire` handles all of these — plus upward workspace-root walks — in one call. - -**Files:** -- Modify: `packages/intent/src/utils.ts:146-199` - -- [ ] **Step 1: Write the failing test for the new behavior** - -The existing scanner tests already exercise `resolveDepDir` indirectly through `scanForIntents`. We'll verify the new resolution by adding a test that proves workspace-hoisted deps are found when scanning from a workspace package subdir. Add to `scanner.test.ts`: - -```typescript -it('finds hoisted deps when scanning from a workspace package subdir', async () => { - // Simulate npm/yarn/bun monorepo: deps hoisted to root node_modules - writeJson(join(root, 'package.json'), { - name: 'monorepo', - private: true, - workspaces: ['packages/*'], - }) - - const appDir = join(root, 'packages', 'app') - createDir(root, 'packages', 'app') - writeJson(join(appDir, 'package.json'), { - name: '@monorepo/app', - version: '1.0.0', - dependencies: { '@tanstack/db': '0.5.0' }, - }) - - // Dep is hoisted to root, NOT in app's node_modules - createDir(root, 'node_modules', '@tanstack', 'db') - createDir(root, 'node_modules', '@tanstack', 'db', 'skills', 'db-core') - const dbDir = join(root, 'node_modules', '@tanstack', 'db') - writeJson(join(dbDir, 'package.json'), { - name: '@tanstack/db', - version: '0.5.0', - intent: { version: 1, repo: 'TanStack/db', docs: 'https://db.tanstack.com' }, - }) - writeSkillMd(join(dbDir, 'skills', 'db-core'), { - name: 'db-core', - description: 'Core database concepts', - }) - - // Scan from the workspace package subdir (not root) - const result = await scanForIntents(appDir) - expect(result.packages).toHaveLength(1) - expect(result.packages[0]!.name).toBe('@tanstack/db') -}) -``` - -Run: `cd packages/intent && pnpm vitest run tests/scanner.test.ts -t "finds hoisted deps"` -Expected: FAIL — current `resolveDepDir` only checks explicit `resolutionRoots`, not upward walk. - -> **Note:** All `pnpm vitest` and `pnpm test:*` commands in this plan should be run from `packages/intent/`, not the repo root. - -- [ ] **Step 2: Replace `resolveDepDir` in utils.ts** - -Replace the existing `resolveDepDir` function (lines 146-199 of `utils.ts`) with: - -```typescript -import { createRequire } from 'node:module' - -/** - * Resolve the directory of a dependency by name. Uses Node's built-in - * module resolution via createRequire, which handles: - * - Hoisted layouts (npm, yarn, bun) — walks up directory tree - * - pnpm symlinked virtual store — follows symlinks - * - Workspace packages — finds deps at workspace root - * - Nested node_modules — standard Node resolution - */ -export function resolveDepDir( - depName: string, - parentDir: string, -): string | null { - try { - const require = createRequire(join(parentDir, 'package.json')) - const pkgJsonPath = require.resolve(join(depName, 'package.json')) - return dirname(pkgJsonPath) - } catch { - return null - } -} -``` - -Keep all other exported functions — they are still used: -- `listNodeModulesPackageDirs` — used by Phase 1 scan and workspace node_modules scan -- `getDeps` — used to extract dep names from package.json -- `detectGlobalNodeModules` — used for `INTENT_GLOBAL_NODE_MODULES` and global install discovery (`createRequire` does NOT resolve global installs) -- `findSkillFiles`, `parseFrontmatter` - -- [ ] **Step 3: Update scanner.ts call sites** - -The `resolveDepDir` signature changed from 4 args to 2. Update `walkDeps` in scanner.ts: - -```typescript -// Before: -const depDir = resolveDepDir(depName, pkgDir, pkgName, resolutionRoots) - -// After: -const depDir = resolveDepDir(depName, pkgDir) -``` - -And `walkProjectDeps`: -```typescript -// Before: -const depDir = resolveDepDir(depName, projectRoot, depName, resolutionRoots) - -// After: -const depDir = resolveDepDir(depName, projectRoot) -``` - -Keep all existing scanner phases — Phase 1 (`scanTarget`), Phase 2 (`walkKnownPackages`), Phase 3 (`walkProjectDeps`), and global scanning. The only changes are: - -1. `resolveDepDir` calls go from 4 args to 2 -2. `walkProjectDeps` gets a `tryRegister` call (see Step 3b) -3. A new workspace scanning phase is added (Task 4) - -- [ ] **Step 3b: Add `tryRegister` to `walkProjectDeps`** - -In `walkProjectDeps`, the current code calls `walkDeps(depDir, depName)` but never `tryRegister(depDir, depName)`. This means a direct skills-package dependency of the project is only discovered through Phase 1's `scanTarget`. When Phase 1 can't find it (e.g., hoisted layout from workspace subdir), it's never registered. - -In `scanner.ts`, find the `walkProjectDeps` function and change: - -```typescript -// Before (scanner.ts ~line 535): -if (depDir && !walkVisited.has(depDir)) { - walkDeps(depDir, depName) -} - -// After: -if (depDir && !walkVisited.has(depDir)) { - tryRegister(depDir, depName) - walkDeps(depDir, depName) -} -``` - -- [ ] **Step 4: Run all tests** - -Run: `cd packages/intent && pnpm vitest run` -Expected: All existing tests pass (no behavioral change to global scanning, Phase 1, etc.). The new hoisted-deps test from Step 1 now passes. - -- [ ] **Step 5: Commit** - -```bash -git add packages/intent/src/utils.ts packages/intent/src/scanner.ts packages/intent/tests/scanner.test.ts -git commit -m "refactor: replace resolveDepDir with createRequire-based resolution" -``` - ---- - -## Chunk 2: Workspace Scanning - -### Task 2: Export `resolveWorkspacePackages` from setup.ts - -**Files:** -- Modify: `packages/intent/src/setup.ts:483` - -- [ ] **Step 1: Make `resolveWorkspacePackages` exported** - -Change `function resolveWorkspacePackages(` to `export function resolveWorkspacePackages(` in setup.ts. - -- [ ] **Step 2: Commit** - -```bash -git add packages/intent/src/setup.ts -git commit -m "refactor: export resolveWorkspacePackages from setup.ts" -``` - -### Task 3: Write failing tests for workspace scanning - -**Files:** -- Modify: `packages/intent/tests/scanner.test.ts` - -- [ ] **Step 1: Write tests for pnpm-style workspace and transitive deps** - -```typescript -it('discovers skills in workspace package dependencies from monorepo root', async () => { - writeFileSync( - join(root, 'pnpm-workspace.yaml'), - 'packages:\n - packages/*\n', - ) - writeJson(join(root, 'package.json'), { - name: 'monorepo', - private: true, - }) - - const appDir = join(root, 'packages', 'app') - createDir(root, 'packages', 'app') - writeJson(join(appDir, 'package.json'), { - name: '@monorepo/app', - version: '1.0.0', - dependencies: { '@tanstack/db': '0.5.0' }, - }) - - createDir(appDir, 'node_modules', '@tanstack', 'db') - createDir(appDir, 'node_modules', '@tanstack', 'db', 'skills', 'db-core') - const dbDir = join(appDir, 'node_modules', '@tanstack', 'db') - writeJson(join(dbDir, 'package.json'), { - name: '@tanstack/db', - version: '0.5.0', - intent: { version: 1, repo: 'TanStack/db', docs: 'https://db.tanstack.com' }, - }) - writeSkillMd(join(dbDir, 'skills', 'db-core'), { - name: 'db-core', - description: 'Core database concepts', - }) - - createDir(root, 'node_modules') - - const result = await scanForIntents(root) - expect(result.packages).toHaveLength(1) - expect(result.packages[0]!.name).toBe('@tanstack/db') - expect(result.packages[0]!.skills).toHaveLength(1) -}) - -it('discovers transitive skills through workspace package deps', async () => { - writeFileSync( - join(root, 'pnpm-workspace.yaml'), - 'packages:\n - packages/*\n', - ) - writeJson(join(root, 'package.json'), { - name: 'monorepo', - private: true, - }) - - const appDir = join(root, 'packages', 'app') - createDir(root, 'packages', 'app') - writeJson(join(appDir, 'package.json'), { - name: '@monorepo/app', - version: '1.0.0', - dependencies: { 'wrapper': '1.0.0' }, - }) - - // wrapper has no skills, but depends on skills-pkg - createDir(appDir, 'node_modules', 'wrapper') - writeJson(join(appDir, 'node_modules', 'wrapper', 'package.json'), { - name: 'wrapper', - version: '1.0.0', - dependencies: { 'skills-pkg': '1.0.0' }, - }) - - // skills-pkg is a transitive dep (sibling in node_modules) - createDir(appDir, 'node_modules', 'skills-pkg') - createDir(appDir, 'node_modules', 'skills-pkg', 'skills', 'core') - writeJson(join(appDir, 'node_modules', 'skills-pkg', 'package.json'), { - name: 'skills-pkg', - version: '1.0.0', - intent: { version: 1, repo: 'test/skills', docs: 'https://example.com' }, - }) - writeSkillMd(join(appDir, 'node_modules', 'skills-pkg', 'skills', 'core'), { - name: 'core', - description: 'Core skill', - }) - - createDir(root, 'node_modules') - - const result = await scanForIntents(root) - expect(result.packages).toHaveLength(1) - expect(result.packages[0]!.name).toBe('skills-pkg') -}) - -it('discovers skills using package.json workspaces', async () => { - writeJson(join(root, 'package.json'), { - name: 'monorepo', - private: true, - workspaces: ['packages/*'], - }) - - const appDir = join(root, 'packages', 'app') - createDir(root, 'packages', 'app') - writeJson(join(appDir, 'package.json'), { - name: '@monorepo/app', - version: '1.0.0', - dependencies: { '@tanstack/db': '0.5.0' }, - }) - - createDir(root, 'node_modules', '@tanstack', 'db') - createDir(root, 'node_modules', '@tanstack', 'db', 'skills', 'db-core') - const dbDir = join(root, 'node_modules', '@tanstack', 'db') - writeJson(join(dbDir, 'package.json'), { - name: '@tanstack/db', - version: '0.5.0', - intent: { version: 1, repo: 'TanStack/db', docs: 'https://db.tanstack.com' }, - }) - writeSkillMd(join(dbDir, 'skills', 'db-core'), { - name: 'db-core', - description: 'Core database concepts', - }) - - const result = await scanForIntents(root) - expect(result.packages).toHaveLength(1) - expect(result.packages[0]!.name).toBe('@tanstack/db') -}) -``` - -- [ ] **Step 2: Run the tests to verify they fail** - -Run: `cd packages/intent && pnpm vitest run tests/scanner.test.ts -t "discovers skills in workspace"` -Expected: FAIL — scanner doesn't scan workspace packages' node_modules yet. - -### Task 4: Add workspace scanning phase to scanner.ts - -**Files:** -- Modify: `packages/intent/src/scanner.ts` - -- [ ] **Step 1: Import workspace resolution functions** - -```typescript -import { - readWorkspacePatterns, - resolveWorkspacePackages, -} from './setup.js' -``` - -- [ ] **Step 2: Add workspace scanning phase** - -After the existing Phase 1 (`scanTarget`), and after the `walkDeps`/`walkKnownPackages`/`walkProjectDeps` function definitions, add workspace scanning before the first `walkKnownPackages()` call: - -```typescript - // Phase 1b: In monorepos, discover workspace packages and walk their deps. - // This handles pnpm monorepos (workspace-specific node_modules) and ensures - // transitive skills packages are found through workspace package dependencies. - const workspacePatterns = readWorkspacePatterns(projectRoot) - if (workspacePatterns) { - for (const wsDir of resolveWorkspacePackages(projectRoot, workspacePatterns)) { - // Scan workspace package's own node_modules for skills - const wsNodeModules = join(wsDir, 'node_modules') - if (existsSync(wsNodeModules)) { - for (const dirPath of listNodeModulesPackageDirs(wsNodeModules)) { - tryRegister(dirPath, 'unknown') - } - } - - // Walk workspace package's deps to find transitive skills packages. - // createRequire-based resolveDepDir walks up from wsDir, so it finds - // deps hoisted to the monorepo root too. - const wsPkg = readPkgJson(wsDir) - if (wsPkg) { - const wsName = typeof wsPkg.name === 'string' ? wsPkg.name : 'unknown' - for (const depName of getDeps(wsPkg, true)) { - const depDir = resolveDepDir(depName, wsDir) - if (depDir && !walkVisited.has(depDir)) { - tryRegister(depDir, depName) - walkDeps(depDir, depName) - } - } - } - } - } -``` - -**Important:** All existing scanner phases are preserved — Phase 1 (`scanTarget` with `listNodeModulesPackageDirs`), Phase 2/3 (`walkKnownPackages`/`walkProjectDeps`), and global scanning (`ensureGlobalNodeModules`). The only changes to the scanner are: (a) `resolveDepDir` calls use 2 args instead of 4, (b) `tryRegister` added to `walkProjectDeps` (Task 1 Step 3b), and (c) this new workspace phase. - -- [ ] **Step 3: Run workspace tests** - -Run: `cd packages/intent && pnpm vitest run tests/scanner.test.ts -t "workspace\|hoisted"` -Expected: PASS - -- [ ] **Step 4: Run all scanner tests** - -Run: `cd packages/intent && pnpm vitest run tests/scanner.test.ts` -Expected: All pass - -- [ ] **Step 5: Commit** - -```bash -git add packages/intent/src/scanner.ts packages/intent/tests/scanner.test.ts -git commit -m "feat: scan workspace package dependencies from monorepo root - -Uses readWorkspacePatterns to discover workspace packages, then scans their -node_modules and walks their dependency trees. createRequire-based -resolveDepDir naturally finds deps hoisted to the workspace root." -``` - -### Task 5: Clean up Arborist spike - -**Files:** -- Delete: `packages/intent/src/scanner-arborist.ts` -- Modify: `packages/intent/package.json` - -- [ ] **Step 1: Delete spike and remove dependency** - -```bash -rm packages/intent/src/scanner-arborist.ts -cd packages/intent && pnpm remove @npmcli/arborist -``` - -- [ ] **Step 2: Run all tests** - -Run: `cd packages/intent && pnpm test:lib` -Expected: All pass - -- [ ] **Step 3: Commit** - -```bash -git add packages/intent/src/scanner-arborist.ts packages/intent/package.json ../../pnpm-lock.yaml -git commit -m "chore: remove arborist spike and dependency" -``` - ---- - -## Chunk 3: Integration Test Fixtures & Infrastructure - -### Task 6: Create fixture packages - -**Files:** -- Create: `packages/intent/tests/fixtures/integration/skills-leaf/package.json` -- Create: `packages/intent/tests/fixtures/integration/skills-leaf/skills/core/SKILL.md` -- Create: `packages/intent/tests/fixtures/integration/wrapper-1/package.json` -- Create: `packages/intent/tests/fixtures/integration/wrapper-2/package.json` -- Create: `packages/intent/tests/fixtures/integration/wrapper-3/package.json` - -- [ ] **Step 1: Create all fixture packages** - -`skills-leaf/package.json`: -```json -{ - "name": "@test-intent/skills-leaf", - "version": "1.0.0", - "intent": { - "version": 1, - "repo": "test/skills-leaf", - "docs": "https://example.com/docs" - }, - "files": ["skills"] -} -``` - -`skills-leaf/skills/core/SKILL.md`: -```markdown ---- -name: core -description: "Core skill for integration testing" -type: core ---- - -# Core Skill - -This is a test skill used by integration tests. -``` - -`wrapper-1/package.json`: -```json -{ - "name": "@test-intent/wrapper-1", - "version": "1.0.0", - "dependencies": { "@test-intent/skills-leaf": "1.0.0" } -} -``` - -`wrapper-2/package.json`: -```json -{ - "name": "@test-intent/wrapper-2", - "version": "1.0.0", - "dependencies": { "@test-intent/wrapper-1": "1.0.0" } -} -``` - -`wrapper-3/package.json`: -```json -{ - "name": "@test-intent/wrapper-3", - "version": "1.0.0", - "dependencies": { "@test-intent/wrapper-2": "1.0.0" } -} -``` - -- [ ] **Step 2: Commit** - -```bash -git add packages/intent/tests/fixtures/integration/ -git commit -m "test: add integration test fixture packages" -``` - -### Task 7: Install Verdaccio and create scaffold helpers - -**Files:** -- Modify: `packages/intent/package.json` -- Create: `packages/intent/tests/integration/scaffold.ts` - -- [ ] **Step 1: Install Verdaccio** - -```bash -cd packages/intent && pnpm add -D verdaccio @verdaccio/node-api -``` - -- [ ] **Step 2: Create scaffold.ts** - -`packages/intent/tests/integration/scaffold.ts`: - -```typescript -import { execSync, execFileSync } from 'node:child_process' -import { - mkdirSync, - mkdtempSync, - realpathSync, - rmSync, - symlinkSync, - writeFileSync, -} from 'node:fs' -import { tmpdir } from 'node:os' -import { dirname, join } from 'node:path' -import { fileURLToPath } from 'node:url' - -const thisDir = dirname(fileURLToPath(import.meta.url)) -const fixturesDir = join(thisDir, '..', 'fixtures', 'integration') -const cliPath = join(thisDir, '..', '..', 'dist', 'cli.mjs') -const realTmpdir = realpathSync(tmpdir()) - -// --------------------------------------------------------------------------- -// Verdaccio lifecycle -// --------------------------------------------------------------------------- - -export interface Registry { - url: string - stop: () => void -} - -export async function startRegistry(): Promise { - const { runServer } = await import('@verdaccio/node-api') - - const storageDir = mkdtempSync(join(realTmpdir, 'verdaccio-storage-')) - const port = 6000 + Math.floor(Math.random() * 4000) - const configPath = join(storageDir, 'config.yaml') - - writeFileSync( - configPath, - [ - `storage: ${storageDir}`, - 'uplinks:', - ' npmjs:', - ' url: https://registry.npmjs.org/', - 'packages:', - " '@test-intent/*':", - ' access: $all', - ' publish: $all', - " '**':", - ' access: $all', - ' proxy: npmjs', - 'log: { type: stdout, format: pretty, level: fatal }', - ].join('\n'), - ) - - const app = await runServer(configPath) - - return new Promise((resolve, reject) => { - const server = app.listen(port, () => { - resolve({ - url: `http://localhost:${port}`, - stop: () => { - server.close() - rmSync(storageDir, { recursive: true, force: true }) - }, - }) - }) - server.on('error', reject) - }) -} - -// --------------------------------------------------------------------------- -// Publishing fixtures -// --------------------------------------------------------------------------- - -export function publishFixtures(registryUrl: string): void { - // Order matters: leaf first, then wrappers that depend on it - for (const pkg of ['skills-leaf', 'wrapper-1', 'wrapper-2', 'wrapper-3']) { - execSync(`npm publish --registry ${registryUrl} --access public`, { - cwd: join(fixturesDir, pkg), - stdio: 'ignore', - }) - } -} - -// --------------------------------------------------------------------------- -// Project scaffolding -// --------------------------------------------------------------------------- - -export type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun' -export type ProjectStructure = 'single' | 'monorepo-root' | 'monorepo-workspace' - -interface ScaffoldResult { - root: string - cwd: string -} - -export function scaffoldProject(opts: { - pm: PackageManager - structure: ProjectStructure - dependency: string - registryUrl: string -}): ScaffoldResult { - const root = mkdtempSync(join(realTmpdir, `intent-integ-${opts.pm}-`)) - - // Lockfile marker so detectPackageManager works - const lockfiles: Record = { - npm: 'package-lock.json', - pnpm: 'pnpm-lock.yaml', - yarn: 'yarn.lock', - bun: 'bun.lock', - } - writeFileSync(join(root, lockfiles[opts.pm]), '') - - if (opts.structure === 'single') { - writeJson(join(root, 'package.json'), { - name: 'test-project', - private: true, - dependencies: { [opts.dependency]: '1.0.0' }, - }) - install(root, opts.pm, opts.registryUrl) - return { root, cwd: root } - } - - // Monorepo - writeJson(join(root, 'package.json'), { - name: 'test-monorepo', - private: true, - ...(opts.pm !== 'pnpm' ? { workspaces: ['packages/*'] } : {}), - }) - if (opts.pm === 'pnpm') { - writeFileSync(join(root, 'pnpm-workspace.yaml'), 'packages:\n - packages/*\n') - } - if (opts.pm === 'yarn') { - writeFileSync(join(root, '.yarnrc.yml'), 'nodeLinker: node-modules\n') - } - - const appDir = join(root, 'packages', 'app') - mkdirSync(appDir, { recursive: true }) - writeJson(join(appDir, 'package.json'), { - name: '@test/app', - version: '1.0.0', - dependencies: { [opts.dependency]: '1.0.0' }, - }) - - install(root, opts.pm, opts.registryUrl) - - return { - root, - cwd: opts.structure === 'monorepo-root' ? root : appDir, - } -} - -function install(dir: string, pm: PackageManager, registryUrl: string): void { - const env = { ...process.env, npm_config_registry: registryUrl } - const reg = `--registry=${registryUrl}` - - switch (pm) { - case 'npm': - execSync(`npm install ${reg}`, { cwd: dir, stdio: 'ignore', env }) - break - case 'pnpm': - execSync(`pnpm install ${reg} --no-frozen-lockfile`, { cwd: dir, stdio: 'ignore', env }) - break - case 'yarn': - execSync(`yarn install ${reg}`, { cwd: dir, stdio: 'ignore', env }) - break - case 'bun': - execSync(`bun install ${reg}`, { cwd: dir, stdio: 'ignore', env }) - break - } -} - -// --------------------------------------------------------------------------- -// CLI invocation -// --------------------------------------------------------------------------- - -export interface CliResult { - stdout: string - stderr: string - exitCode: number - parsed: any -} - -export function runScanner( - cwd: string, - method: 'direct' | 'symlink' = 'direct', -): CliResult { - let binPath = cliPath - - if (method === 'symlink') { - const linkDir = mkdtempSync(join(realTmpdir, 'intent-link-')) - const linkPath = join(linkDir, 'intent-cli.mjs') - symlinkSync(cliPath, linkPath) - binPath = linkPath - } - - try { - const stdout = execFileSync('node', [binPath, 'list', '--json'], { - cwd, - encoding: 'utf8', - stdio: ['ignore', 'pipe', 'pipe'], - }) - return { stdout, stderr: '', exitCode: 0, parsed: JSON.parse(stdout) } - } catch (err: any) { - return { - stdout: err.stdout ?? '', - stderr: err.stderr ?? '', - exitCode: err.status ?? 1, - parsed: null, - } - } -} - -// --------------------------------------------------------------------------- -// Helpers -// --------------------------------------------------------------------------- - -function writeJson(filePath: string, data: unknown): void { - mkdirSync(dirname(filePath), { recursive: true }) - writeFileSync(filePath, JSON.stringify(data, null, 2)) -} -``` - -- [ ] **Step 3: Exclude integration tests from `test:lib`, add `test:integration`** - -In `packages/intent/package.json`, update scripts: -```json -"test:lib": "vitest run --exclude tests/integration/**", -"test:integration": "vitest run tests/integration/" -``` - -- [ ] **Step 4: Commit** - -```bash -git add packages/intent/package.json packages/intent/tests/integration/scaffold.ts ../../pnpm-lock.yaml -git commit -m "test: add Verdaccio-based integration test infrastructure" -``` - ---- - -## Chunk 4: Integration Test Grid - -### Task 8: Write the integration test matrix - -**Files:** -- Create: `packages/intent/tests/integration/scanner-integration.test.ts` - -- [ ] **Step 1: Write the test file** - -```typescript -import { rmSync } from 'node:fs' -import { afterAll, beforeAll, describe, expect, it } from 'vitest' -import type { PackageManager, ProjectStructure, Registry } from './scaffold.js' -import { - publishFixtures, - runScanner, - scaffoldProject, - startRegistry, -} from './scaffold.js' - -const PACKAGE_MANAGERS: Array = ['npm', 'pnpm', 'yarn', 'bun'] -const STRUCTURES: Array = [ - 'single', - 'monorepo-root', - 'monorepo-workspace', -] -const DEPENDENCY_CHAINS: Array<{ label: string; dep: string }> = [ - { label: 'direct', dep: '@test-intent/skills-leaf' }, - { label: 'transitive+1', dep: '@test-intent/wrapper-1' }, - { label: 'transitive+2', dep: '@test-intent/wrapper-2' }, - { label: 'transitive+3', dep: '@test-intent/wrapper-3' }, -] - -let registry: Registry -const tempDirs: Array = [] - -beforeAll(async () => { - registry = await startRegistry() - publishFixtures(registry.url) -}, 30_000) - -afterAll(() => { - registry?.stop() - for (const dir of tempDirs) { - rmSync(dir, { recursive: true, force: true }) - } -}) - -describe.each(PACKAGE_MANAGERS)('package manager: %s', (pm) => { - describe.each(STRUCTURES)('structure: %s', (structure) => { - describe.each(DEPENDENCY_CHAINS)('dependency: $label', ({ dep }) => { - it('discovers @test-intent/skills-leaf and its core skill', () => { - const { root, cwd } = scaffoldProject({ - pm, - structure, - dependency: dep, - registryUrl: registry.url, - }) - tempDirs.push(root) - - const result = runScanner(cwd) - - expect(result.exitCode).toBe(0) - expect(result.parsed).toBeTruthy() - expect(result.parsed.packages).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - name: '@test-intent/skills-leaf', - version: '1.0.0', - skills: expect.arrayContaining([ - expect.objectContaining({ name: 'core', type: 'core' }), - ]), - }), - ]), - ) - }, 60_000) - }) - }) -}) - -describe('symlink invocation', () => { - it('finds skills when CLI is invoked through a symlink', () => { - const { root, cwd } = scaffoldProject({ - pm: 'npm', - structure: 'single', - dependency: '@test-intent/skills-leaf', - registryUrl: registry.url, - }) - tempDirs.push(root) - - const result = runScanner(cwd, 'symlink') - - expect(result.exitCode).toBe(0) - expect(result.parsed.packages).toHaveLength(1) - expect(result.parsed.packages[0].name).toBe('@test-intent/skills-leaf') - }, 60_000) -}) -``` - -- [ ] **Step 2: Build CLI and run integration tests** - -```bash -pnpm run build -cd packages/intent && pnpm test:integration -``` - -Expected: 4 PMs × 3 structures × 4 depths = 48 tests + 1 symlink test = 49 total. Debug failures as they arise (Task 9). - -- [ ] **Step 3: Commit** - -```bash -git add packages/intent/tests/integration/scanner-integration.test.ts -git commit -m "test: add cross-package-manager integration test grid (49 scenarios)" -``` - -### Task 9: Fix edge cases from integration testing - -Debug and fix failures. Common issues: -1. **Yarn Berry PnP** — `.yarnrc.yml` with `nodeLinker: node-modules` already added in scaffold -2. **pnpm transitive deps** — `createRequire` + workspace dep walking should handle this; if not, debug the resolution chain -3. **Bun workspaces** — uses `package.json` workspaces, should work - -- [ ] **Step 1: Fix failures, run `cd packages/intent && pnpm test:lib && pnpm test:integration`** -- [ ] **Step 2: Commit fixes** - ---- - -## Chunk 5: Final Verification - -### Task 10: End-to-end against real monorepo - -- [ ] **Step 1: Build CLI** - -```bash -pnpm run build -``` - -- [ ] **Step 2: Test from monorepo root** - -```bash -cd /Users/kylemathews/programs/darix/.worktrees/ts-darix-runtime -node /Users/kylemathews/programs/intent/packages/intent/dist/cli.mjs list -``` - -Expected: `@tanstack/db` with 6 skills (workspace scanning) - -- [ ] **Step 3: Test from workspace package subdir** - -```bash -cd /Users/kylemathews/programs/darix/.worktrees/ts-darix-runtime/packages/ts-darix-runtime -node /Users/kylemathews/programs/intent/packages/intent/dist/cli.mjs list -``` - -Expected: `@tanstack/db` with 6 skills (createRequire walks up to root node_modules) - -- [ ] **Step 4: Run `cd packages/intent && pnpm test:lib && pnpm test:integration`** - -Expected: All unit + integration tests pass - -- [ ] **Step 5: Final commit** - -```bash -git add -A -git commit -m "test: verify end-to-end against real monorepo" -```