diff --git a/CHANGELOG.md b/CHANGELOG.md index bbab128..7f1ed0f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## 6.1.10 + +### Fixed + +- Extended packed-package verification to reject bare side-effect imports of packages that patch Node builtins while continuing to allow dynamic imports. + +### Changed + +- Updated `@tangle-network/agent-eval` to `0.135.1` for strict rollout-record validation and stable estimated-cost receipt validation. +- Updated the installation example to pin the matching Knowledge and Eval releases. + ## 6.1.9 ### Fixed diff --git a/README.md b/README.md index d9b0b75..e6e9a8d 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Supply application callbacks for those decisions, or use `@tangle-network/agent- ## Install ```bash -pnpm add @tangle-network/agent-knowledge @tangle-network/agent-eval@0.134.1 +pnpm add @tangle-network/agent-knowledge@6.1.10 @tangle-network/agent-eval@0.135.1 ``` Requires Node.js 20.19 or later. diff --git a/package.json b/package.json index f5dee9a..bf549fb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@tangle-network/agent-knowledge", - "version": "6.1.9", + "version": "6.1.10", "description": "Build, search, evaluate, and improve source-backed knowledge bases.", "homepage": "https://github.com/tangle-network/agent-knowledge#readme", "repository": { @@ -75,7 +75,7 @@ "verify:official-optimizers": "node scripts/verify-official-optimizers.mjs" }, "dependencies": { - "@tangle-network/agent-eval": "0.134.2", + "@tangle-network/agent-eval": "0.135.1", "@tangle-network/agent-interface": "0.36.0", "proper-lockfile": "4.1.2", "zod": "^4.4.3" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4974d96..9059ab6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -16,8 +16,8 @@ importers: .: dependencies: '@tangle-network/agent-eval': - specifier: 0.134.2 - version: 0.134.2 + specifier: 0.135.1 + version: 0.135.1 '@tangle-network/agent-interface': specifier: 0.36.0 version: 0.36.0 @@ -636,8 +636,8 @@ packages: '@tangle-network/agent-core@0.4.25': resolution: {integrity: sha512-3hfIs64b/1/C1ezYhSPu6NC449lO4XAq79uaol0z0eLXcXDM+2znXThTeMTEZUPJ4iAsR514xcHL2OrP3dsE3g==} - '@tangle-network/agent-eval@0.134.2': - resolution: {integrity: sha512-+SooBL1Ca5nSx1kJDkEU3MAkadnsvbeeBMDZSFyuNSXLyz6dYtY3Cn4CLkn8AEJRhlm2kMs23yYpPHKHo7Y+Qw==} + '@tangle-network/agent-eval@0.135.1': + resolution: {integrity: sha512-YKJEn4+IJDSNYTP9MQTDqcyRIxcSVetkqxYqv+IWEPfVM9odsAQ95tmatb5wlYukuz9u5/Dk7Dm5AAFrHKZW6A==} engines: {node: '>=20'} hasBin: true @@ -2750,7 +2750,7 @@ snapshots: '@tangle-network/agent-interface': 0.36.0 zod: 4.4.3 - '@tangle-network/agent-eval@0.134.2': + '@tangle-network/agent-eval@0.135.1': dependencies: '@asteasolutions/zod-to-openapi': 9.1.0(zod@4.4.3) '@ax-llm/ax': 23.0.5(zod@4.4.3) diff --git a/scripts/verify-package.mjs b/scripts/verify-package.mjs index 5ca7821..166c446 100644 --- a/scripts/verify-package.mjs +++ b/scripts/verify-package.mjs @@ -69,6 +69,7 @@ const agentInterfaceVersion = sourcePackage.dependencies?.['@tangle-network/agen if (!/^\d+\.\d+\.\d+$/.test(agentInterfaceVersion)) { throw new Error('@tangle-network/agent-interface must be pinned to one exact version') } +assertEdgeUnsafeStaticImportMatcher() const tempRoot = mkdtempSync(join(tmpdir(), 'agent-knowledge-package-')) try { @@ -228,11 +229,9 @@ function assertNoEdgeUnsafeStaticImports(distDir) { for (const file of javascriptFiles(distDir)) { const source = readFileSync(file, 'utf8') for (const specifier of edgeUnsafeStaticImports) { - const quoted = `["']${specifier.replaceAll('/', '\\/')}["']` - // A static ESM import, a re-export, or a CJS require. `import(...)` is - // deliberately excluded: deferring the module scope is the whole fix. - const statik = new RegExp(`(?:from\\s*${quoted}|require\\(\\s*${quoted}\\s*\\))`) - if (statik.test(source)) offenders.push(`${file.slice(distDir.length + 1)} -> ${specifier}`) + if (hasStaticImport(source, specifier)) { + offenders.push(`${file.slice(distDir.length + 1)} -> ${specifier}`) + } } } if (offenders.length > 0) { @@ -247,6 +246,33 @@ function assertNoEdgeUnsafeStaticImports(distDir) { } } +function hasStaticImport(source, specifier) { + const escaped = specifier.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + const quoted = `["']${escaped}["']` + // Bound imports, bare side-effect imports, re-exports, and CommonJS require. + // Dynamic import() is deliberately excluded because it defers module scope. + return new RegExp( + `(?:\\bfrom\\s*${quoted}|\\bimport\\s*${quoted}|\\brequire\\(\\s*${quoted}\\s*\\))`, + ).test(source) +} + +function assertEdgeUnsafeStaticImportMatcher() { + const specifier = 'proper-lockfile' + const cases = [ + ['bound ESM import', `import value from '${specifier}'`, true], + ['bare side-effect ESM import', `import '${specifier}'`, true], + ['ESM re-export', `export { value } from '${specifier}'`, true], + ['CommonJS require', `require('${specifier}')`, true], + ['dynamic import', `await import('${specifier}')`, false], + ] + for (const [label, source, expected] of cases) { + const actual = hasStaticImport(source, specifier) + if (actual !== expected) { + throw new Error(`edge-unsafe static import matcher failed: ${label}`) + } + } +} + function javascriptFiles(directory) { const files = [] for (const entry of readdirSync(directory)) {