Conversation
- Updated @anthropic-ai/mcpb from 1.2.0 to 2.1.2 (MAJOR) - Updated eslint from 9.39.2 to 10.0.3 (MAJOR) - Updated @eslint/js from 9.39.2 to 10.0.1 (MAJOR) - Updated globals from 15.15.0 to 17.4.0 (MAJOR) - Updated typescript from 5.3.0 to 5.8.4 - Fixed flatted DoS vulnerability (CVE high) Improves: security, MCP compatibility, linting rules, TypeScript features
- Add comprehensive GitHub Actions CI workflow - Multi-node testing (18.x, 20.x, 22.x) - Lint, format, type-check, and test validation - Dependency audit and security checks - Build verification for all packages - Add unit tests for core package configuration loader - Test loadPipelineConfig, loadRalphConfig, loadValidationConfig - Test discoverPipelineConfig functionality - Test default configuration generators - Comprehensive error handling validation - Update critical dependencies to latest stable versions - @vitest/coverage-v8: 4.0.18 → 4.1.0 - lint-staged: 16.2.7 → 16.4.0 - typescript-eslint: 8.55.0 → 8.57.1 - Add CHANGELOG.md for better release tracking Addresses high priority items identified in code review: - Missing CI/CD pipeline for automated quality assurance - No test coverage for critical core package functionality - Outdated dependencies with available security updates
- Run npm audit fix on mcp-server workspace - Fixed 5 high and moderate severity vulnerabilities - Remaining 5 low severity vulnerabilities have no fix available
- Updated @anthropic-ai/sdk from 0.32.0 to 0.80.0 (major update with latest features) - Updated @types/node, vitest, typescript and other dev dependencies to latest stable versions - Updated CLI dependencies including critical Anthropic SDK - All tests passing, no vulnerabilities found Key updates: - @anthropic-ai/sdk: 0.32.0 → 0.80.0 - typescript: 5.3.0/5.6.3 → 5.7.3 - vitest: 4.0.18 → 4.1.0 - husky: 9.0.0 → 9.1.6 - inquirer: 12.2.0 → 12.11.1 - dotenv: 16.4.5 → 16.6.1
- fix security vulnerability via npm audit fix - all tests and type checks now passing
- Updated @commitlint packages to v20.5.0 - Updated @types/node to v25.5.0 in CLI and core workspaces - Installed dependencies for claw-pipeline/base-wallet-xray subdirectory - All tests, linting, and type checks pass Improves development tooling while maintaining compatibility with existing ESLint configurations.
| }, | ||
| }; | ||
|
|
||
| writeFileSync(configPath, JSON.stringify(validConfig, null, 2)); |
Check failure
Code scanning / CodeQL
Insecure temporary file High test
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 18 days ago
In general, to fix insecure temporary file issues you should avoid constructing paths under os.tmpdir() manually. Instead, use a library or API that creates a unique, securely permissioned temporary directory or file (for Node.js, commonly the tmp package), and then create your test files inside that directory.
For this snippet, the best minimal fix is to replace the manual tmpdir() + timestamp logic in setupTestDir() with a call to tmp.dirSync() from the tmp package. This returns a securely created, unique temporary directory path. We then keep the rest of the test logic unchanged: the tests still get a directory path in testDir and still create pipeline.json within that directory. Concretely:
- Add an import for
tmpat the top ofcore/src/__tests__/config-loader.test.js. - Change
setupTestDir()so that it callstmp.dirSync({ unsafeCleanup: true }).nameinstead of usingjoin(tmpdir(), ...)andmkdirSync. This preserves the external behavior (tests get an empty directory path), but uses a secure temp directory mechanism. - The
cleanupTestDir()function can remain as-is; it will remove whatever directory pathtmp.dirSync()created.
All other code paths (including the use of configPath and writeFileSync) can remain unchanged.
| @@ -7,6 +7,7 @@ | ||
| import { writeFileSync, mkdirSync, rmSync } from 'node:fs'; | ||
| import { join } from 'node:path'; | ||
| import { tmpdir } from 'node:os'; | ||
| import tmp from 'tmp'; | ||
|
|
||
| import { | ||
| loadPipelineConfig, | ||
| @@ -23,8 +24,7 @@ | ||
|
|
||
| // Setup test directory before each test | ||
| function setupTestDir() { | ||
| testDir = join(tmpdir(), `appfactory-test-${Date.now()}`); | ||
| mkdirSync(testDir, { recursive: true }); | ||
| testDir = tmp.dirSync({ unsafeCleanup: true }).name; | ||
| return testDir; | ||
| } | ||
|
|
| @@ -44,7 +44,8 @@ | ||
| "dependencies": { | ||
| "ajv": "^8.12.0", | ||
| "chalk": "^5.3.0", | ||
| "zod": "^3.22.0" | ||
| "zod": "^3.22.0", | ||
| "tmp": "^0.2.5" | ||
| }, | ||
| "engines": { | ||
| "node": ">=18.0.0" |
| Package | Version | Security advisories |
| tmp (npm) | 0.2.5 | None |
| const dir = setupTestDir(); | ||
| const configPath = join(dir, 'invalid.json'); | ||
|
|
||
| writeFileSync(configPath, '{ invalid json }'); |
Check failure
Code scanning / CodeQL
Insecure temporary file High test
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 18 days ago
In general, to fix insecure temp-file/directory issues, avoid manually constructing paths under os.tmpdir() with predictable names. Instead, delegate to a secure library (such as tmp) that creates unique, non-guessable directories or files with safe permissions and guarantees they don’t already exist.
For this specific file, the cleanest fix is to modify setupTestDir to create a secure temporary directory using the tmp package rather than join(tmpdir(), ...) and mkdirSync. We can import tmp at the top of the test file and call tmp.dirSync({ unsafeCleanup: true }) to get a unique temp directory path. We then store the directory name (tmp.dirSync().name) into testDir and return it. The rest of the tests can remain unchanged because they already treat setupTestDir() as a black box that returns a directory path. Cleanup can continue to use rmSync(testDir, { recursive: true, force: true }); unsafeCleanup is mostly for tmp’s own cleanup helpers, so we don’t need to use them if we prefer to keep the existing cleanupTestDir logic.
Concretely:
- Add
import tmp from 'tmp';near the top ofcore/src/__tests__/config-loader.test.js. - Change
setupTestDirso that instead of computingtestDir = join(tmpdir(), ...)and callingmkdirSync, it callstmp.dirSync({ unsafeCleanup: true }), assignstestDir = tmpDir.name, and returnstestDir. - Leave
cleanupTestDirand all test logic intact.
| @@ -7,6 +7,7 @@ | ||
| import { writeFileSync, mkdirSync, rmSync } from 'node:fs'; | ||
| import { join } from 'node:path'; | ||
| import { tmpdir } from 'node:os'; | ||
| import tmp from 'tmp'; | ||
|
|
||
| import { | ||
| loadPipelineConfig, | ||
| @@ -23,8 +24,8 @@ | ||
|
|
||
| // Setup test directory before each test | ||
| function setupTestDir() { | ||
| testDir = join(tmpdir(), `appfactory-test-${Date.now()}`); | ||
| mkdirSync(testDir, { recursive: true }); | ||
| const tmpDir = tmp.dirSync({ unsafeCleanup: true }); | ||
| testDir = tmpDir.name; | ||
| return testDir; | ||
| } | ||
|
|
| @@ -44,7 +44,8 @@ | ||
| "dependencies": { | ||
| "ajv": "^8.12.0", | ||
| "chalk": "^5.3.0", | ||
| "zod": "^3.22.0" | ||
| "zod": "^3.22.0", | ||
| "tmp": "^0.2.5" | ||
| }, | ||
| "engines": { | ||
| "node": ">=18.0.0" |
| Package | Version | Security advisories |
| tmp (npm) | 0.2.5 | None |
| runE2ETests: true, | ||
| }; | ||
|
|
||
| writeFileSync(configPath, JSON.stringify(validConfig, null, 2)); |
Check failure
Code scanning / CodeQL
Insecure temporary file High test
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 18 days ago
In general, the fix is to avoid creating predictable paths directly under os.tmpdir() and instead use a secure temporary directory creation mechanism that ensures uniqueness and appropriate permissions. In Node.js, the tmp package provides dirSync() which securely creates a new temporary directory with restrictive permissions and a non-predictable name; we can then create our test files inside that directory as before.
For this specific file, the simplest, least intrusive change is:
- Import
tmpat the top ofcore/src/__tests__/config-loader.test.js. - Rewrite
setupTestDir()so that it callstmp.dirSync({ unsafeCleanup: true })instead of manually composing a directory path withtmpdir()andmkdirSync. Store the returned directory name intestDir(as now) and return it. - Keep
cleanupTestDir()as-is: it will still removetestDirif set; even iftmpalready cleans up, double cleanup withrmSync(..., { force: true })is safe in tests and preserves existing behavior.
No other test logic (e.g., how configPath is constructed or used) needs to change because all tests already use setupTestDir() to obtain the directory in which they create config files.
Concretely:
- Add
import tmp from 'tmp';near the existing imports. - Replace the body of
setupTestDir()so that it usestmp.dirSync()and assignstestDir = tmp.dirSync({ unsafeCleanup: true }).name;.
| @@ -7,6 +7,7 @@ | ||
| import { writeFileSync, mkdirSync, rmSync } from 'node:fs'; | ||
| import { join } from 'node:path'; | ||
| import { tmpdir } from 'node:os'; | ||
| import tmp from 'tmp'; | ||
|
|
||
| import { | ||
| loadPipelineConfig, | ||
| @@ -23,8 +24,8 @@ | ||
|
|
||
| // Setup test directory before each test | ||
| function setupTestDir() { | ||
| testDir = join(tmpdir(), `appfactory-test-${Date.now()}`); | ||
| mkdirSync(testDir, { recursive: true }); | ||
| // Use a securely created temporary directory to avoid predictable paths in the OS temp dir | ||
| testDir = tmp.dirSync({ unsafeCleanup: true }).name; | ||
| return testDir; | ||
| } | ||
|
|
| @@ -44,7 +44,8 @@ | ||
| "dependencies": { | ||
| "ajv": "^8.12.0", | ||
| "chalk": "^5.3.0", | ||
| "zod": "^3.22.0" | ||
| "zod": "^3.22.0", | ||
| "tmp": "^0.2.5" | ||
| }, | ||
| "engines": { | ||
| "node": ">=18.0.0" |
| Package | Version | Security advisories |
| tmp (npm) | 0.2.5 | None |
| allowedDotfiles: ['.env.example'], | ||
| }; | ||
|
|
||
| writeFileSync(configPath, JSON.stringify(validConfig, null, 2)); |
Check failure
Code scanning / CodeQL
Insecure temporary file High test
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 18 days ago
General fix: avoid manually constructing paths under os.tmpdir() using timestamps or predictable names. Instead, delegate temp directory creation to a library like tmp, which will (a) create the directory atomically, (b) ensure it does not already exist, and (c) use restrictive permissions by default. Then, base all test file paths on the secure directory path returned by that library.
Best fix here: change setupTestDir so it uses tmp.dirSync (from the tmp package) to create a unique temporary directory, rather than join(tmpdir(), ...) plus mkdirSync. Keep the rest of the test logic unchanged: it should still return a directory path string that is later passed to join(dir, 'validation.json'), etc. The cleanupTestDir function can continue to use rmSync on testDir, since tmp.dirSync will create a real directory path on disk. We also need to import tmp at the top of the file.
Concretely:
- In
core/src/__tests__/config-loader.test.js:- Add
import tmp from 'tmp';alongside the other imports. - Update
setupTestDir:- Remove use of
tmpdir(),join, andmkdirSync. - Replace with
testDir = tmp.dirSync({ unsafeCleanup: true }).name;and return that.
- Remove use of
- Leave
cleanupTestDirunchanged; it will still remove the created directory tree.
- Add
No other tests or functions need modification.
| @@ -7,6 +7,7 @@ | ||
| import { writeFileSync, mkdirSync, rmSync } from 'node:fs'; | ||
| import { join } from 'node:path'; | ||
| import { tmpdir } from 'node:os'; | ||
| import tmp from 'tmp'; | ||
|
|
||
| import { | ||
| loadPipelineConfig, | ||
| @@ -23,8 +24,8 @@ | ||
|
|
||
| // Setup test directory before each test | ||
| function setupTestDir() { | ||
| testDir = join(tmpdir(), `appfactory-test-${Date.now()}`); | ||
| mkdirSync(testDir, { recursive: true }); | ||
| const tmpDir = tmp.dirSync({ unsafeCleanup: true }); | ||
| testDir = tmpDir.name; | ||
| return testDir; | ||
| } | ||
|
|
| @@ -44,7 +44,8 @@ | ||
| "dependencies": { | ||
| "ajv": "^8.12.0", | ||
| "chalk": "^5.3.0", | ||
| "zod": "^3.22.0" | ||
| "zod": "^3.22.0", | ||
| "tmp": "^0.2.5" | ||
| }, | ||
| "engines": { | ||
| "node": ">=18.0.0" |
| Package | Version | Security advisories |
| tmp (npm) | 0.2.5 | None |
| }, | ||
| }; | ||
|
|
||
| writeFileSync(configPath, JSON.stringify(validConfig, null, 2)); |
Check failure
Code scanning / CodeQL
Insecure temporary file High test
Copilot Autofix
AI 18 days ago
Copilot could not generate an autofix suggestion
Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.
| }, | ||
| }; | ||
|
|
||
| writeFileSync(configPath, JSON.stringify(validConfig, null, 2)); |
Check failure
Code scanning / CodeQL
Insecure temporary file High test
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 18 days ago
In general, to fix insecure temp file/directory creation you should avoid manually constructing paths under os.tmpdir() and instead use a library (such as tmp) that atomically creates unique, non‑guessable directories or files with appropriate permissions, returning a path you can safely use.
For this specific test file, the issue comes from setupTestDir:
function setupTestDir() {
testDir = join(tmpdir(), `appfactory-test-${Date.now()}`);
mkdirSync(testDir, { recursive: true });
return testDir;
}We should replace this with a call to tmp.dirSync so the directory is securely and uniquely created by the library, while preserving existing behavior: returning a path in testDir that the tests then use, and cleaning it up with rmSync at the end. The concrete steps:
- Add an import for the
tmppackage at the top ofcore/src/__tests__/config-loader.test.js. - Update
setupTestDirto calltmp.dirSync({ unsafeCleanup: true, prefix: 'appfactory-test-' }), store the resulting directory path intestDir, and return it.unsafeCleanup: trueensures nested files/dirs are also removed if we ever decide to use the cleanup callback; in our current code we still callrmSync, which is fine since it’s recursive and forced.- Using a
prefixmaintains similar naming for readability while lettingtmphandle uniqueness and security.
- Remove the direct use of
tmpdir()andmkdirSyncinsidesetupTestDir; other tests can continue to callsetupTestDir()unchanged.
No other logic in the tests has to change; they already rely only on the directory path setupTestDir returns.
| @@ -7,6 +7,7 @@ | ||
| import { writeFileSync, mkdirSync, rmSync } from 'node:fs'; | ||
| import { join } from 'node:path'; | ||
| import { tmpdir } from 'node:os'; | ||
| import tmp from 'tmp'; | ||
|
|
||
| import { | ||
| loadPipelineConfig, | ||
| @@ -23,8 +24,8 @@ | ||
|
|
||
| // Setup test directory before each test | ||
| function setupTestDir() { | ||
| testDir = join(tmpdir(), `appfactory-test-${Date.now()}`); | ||
| mkdirSync(testDir, { recursive: true }); | ||
| const tmpDir = tmp.dirSync({ unsafeCleanup: true, prefix: 'appfactory-test-' }); | ||
| testDir = tmpDir.name; | ||
| return testDir; | ||
| } | ||
|
|
| @@ -44,7 +44,8 @@ | ||
| "dependencies": { | ||
| "ajv": "^8.12.0", | ||
| "chalk": "^5.3.0", | ||
| "zod": "^3.22.0" | ||
| "zod": "^3.22.0", | ||
| "tmp": "^0.2.5" | ||
| }, | ||
| "engines": { | ||
| "node": ">=18.0.0" |
| Package | Version | Security advisories |
| tmp (npm) | 0.2.5 | None |
This PR updates several development dependencies to their latest compatible versions:
What:
Why:
Tested:
npm run ci)The changes improve development tooling while maintaining full backward compatibility.