diff --git a/.aiox-core/core/pro/pro-updater.js b/.aiox-core/core/pro/pro-updater.js index b2b9fc78a5..d293ff794a 100644 --- a/.aiox-core/core/pro/pro-updater.js +++ b/.aiox-core/core/pro/pro-updater.js @@ -113,7 +113,7 @@ function resolveInstalledPro(projectRoot) { } function readProjectPackageJson(projectRoot) { - const packageJsonPath = path.join(projectRoot, 'package.json'); + const packageJsonPath = path.join(path.resolve(projectRoot), 'package.json'); if (!fs.existsSync(packageJsonPath)) { return null; } @@ -126,12 +126,14 @@ function readProjectPackageJson(projectRoot) { } function buildNodeModulesPackageJsonPath(projectRoot, packageName) { + const resolvedProjectRoot = path.resolve(projectRoot); + if (packageName.startsWith('@')) { const [scope, name] = packageName.slice(1).split('/'); - return path.join(projectRoot, 'node_modules', scope, name, 'package.json'); + return path.join(resolvedProjectRoot, 'node_modules', scope, name, 'package.json'); } - return path.join(projectRoot, 'node_modules', packageName, 'package.json'); + return path.join(resolvedProjectRoot, 'node_modules', packageName, 'package.json'); } function detectCorePackageName(projectRoot) { @@ -187,7 +189,8 @@ function assertValidProjectRoot(projectRoot) { * @returns {string|null} */ function getCoreVersion(projectRoot) { - const versionJsonPath = path.join(projectRoot, '.aiox-core', 'version.json'); + const resolvedProjectRoot = path.resolve(projectRoot); + const versionJsonPath = path.join(resolvedProjectRoot, '.aiox-core', 'version.json'); if (fs.existsSync(versionJsonPath)) { try { const versionInfo = JSON.parse(fs.readFileSync(versionJsonPath, 'utf8')); @@ -200,7 +203,7 @@ function getCoreVersion(projectRoot) { } for (const packageName of CORE_PACKAGES) { - const packageJsonPath = buildNodeModulesPackageJsonPath(projectRoot, packageName); + const packageJsonPath = buildNodeModulesPackageJsonPath(resolvedProjectRoot, packageName); if (fs.existsSync(packageJsonPath)) { try { const data = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); @@ -211,13 +214,13 @@ function getCoreVersion(projectRoot) { } } - const projectPackageJson = readProjectPackageJson(projectRoot); + const projectPackageJson = readProjectPackageJson(resolvedProjectRoot); if (projectPackageJson) { if (CORE_PACKAGES.includes(projectPackageJson.name)) { return projectPackageJson.version || null; } - const declaredCorePackage = detectCorePackageName(projectRoot); + const declaredCorePackage = detectCorePackageName(resolvedProjectRoot); if (declaredCorePackage) { for (const field of DEPENDENCY_FIELDS) { const declaredVersion = projectPackageJson[field]?.[declaredCorePackage]; diff --git a/.aiox-core/data/entity-registry.yaml b/.aiox-core/data/entity-registry.yaml index 3c8e711064..a655608a35 100644 --- a/.aiox-core/data/entity-registry.yaml +++ b/.aiox-core/data/entity-registry.yaml @@ -1,6 +1,6 @@ metadata: version: 1.0.0 - lastUpdated: '2026-05-08T19:57:34.743Z' + lastUpdated: '2026-05-08T21:17:46.181Z' entityCount: 755 checksumAlgorithm: sha256 resolutionRate: 100 @@ -12802,8 +12802,8 @@ entities: score: 0.4 constraints: [] extensionPoints: [] - checksum: sha256:532bdded456b4d5c62ddcfb82a145c67e2c34a42153589cf7a4632d27b16fa7d - lastVerified: '2026-05-08T19:57:34.737Z' + checksum: sha256:30ea78b8ab088e695936ae662057697410856751f463eeb649e00b67dcc31531 + lastVerified: '2026-05-08T21:17:46.174Z' externalDeps: [] plannedDeps: [] lifecycle: orphan diff --git a/.aiox-core/install-manifest.yaml b/.aiox-core/install-manifest.yaml index 157442cee3..5db5a1c3e2 100644 --- a/.aiox-core/install-manifest.yaml +++ b/.aiox-core/install-manifest.yaml @@ -8,7 +8,7 @@ # - File types for categorization # version: 5.1.15 -generated_at: "2026-05-08T21:14:02.282Z" +generated_at: "2026-05-08T21:28:13.872Z" generator: scripts/generate-install-manifest.js file_count: 1122 files: @@ -1009,9 +1009,9 @@ files: type: core size: 7193 - path: core/pro/pro-updater.js - hash: sha256:532bdded456b4d5c62ddcfb82a145c67e2c34a42153589cf7a4632d27b16fa7d + hash: sha256:30ea78b8ab088e695936ae662057697410856751f463eeb649e00b67dcc31531 type: core - size: 17817 + size: 17994 - path: core/quality-gates/base-layer.js hash: sha256:9a9a3921da08176b0bd44f338a59abc1f5107f3b1ee56571e840bf4e8ed233f4 type: core @@ -1277,7 +1277,7 @@ files: type: data size: 9590 - path: data/entity-registry.yaml - hash: sha256:978e53082f9799d21b396a23901bb97a524999ee2604d1d27454aba20bc68f32 + hash: sha256:c115355ba33df1671460f3ba51baba5235db865f34a0f3e8b6ec3c8a31134be2 type: data size: 528021 - path: data/learned-patterns.yaml diff --git a/tests/cli/aiox-delegate.test.js b/tests/cli/aiox-delegate.test.js index 079a5a9e94..eecfdcae19 100644 --- a/tests/cli/aiox-delegate.test.js +++ b/tests/cli/aiox-delegate.test.js @@ -12,6 +12,7 @@ const { describe('aiox-delegate external executor CLI', () => { const fixedDate = new Date(Date.UTC(2026, 4, 8, 2, 30, 45)); + const workdir = path.resolve('/tmp/work'); test('parses codex delegation arguments', () => { const options = parseArgs([ @@ -42,10 +43,10 @@ describe('aiox-delegate external executor CLI', () => { ); expect(plan.slug).toBe('story-4.3'); - expect(plan.runDir).toBe('/tmp/work/.aiox/external-runs/20260508-023045-story-4.3'); + expect(plan.runDir).toBe(path.join(workdir, '.aiox', 'external-runs', '20260508-023045-story-4.3')); expect(plan.command).toBe('codex'); expect(plan.args).toEqual( - expect.arrayContaining(['-a', 'never', '-s', 'workspace-write', 'exec', '-C', '/tmp/work']), + expect.arrayContaining(['-a', 'never', '-s', 'workspace-write', 'exec', '-C', workdir]), ); expect(plan.args.at(-1)).toBe('-'); expect(plan.outputPath).toBe(path.join(plan.runDir, 'output.md')); @@ -68,7 +69,7 @@ describe('aiox-delegate external executor CLI', () => { ); expect(plan.args).toEqual( - expect.arrayContaining(['-a', 'never', '-s', 'workspace-write', 'exec', '-C', '/tmp/work']), + expect.arrayContaining(['-a', 'never', '-s', 'workspace-write', 'exec', '-C', workdir]), ); }); diff --git a/tests/core/orchestration/bob-orchestrator.test.js b/tests/core/orchestration/bob-orchestrator.test.js index ad574ddb31..ec0f923efd 100644 --- a/tests/core/orchestration/bob-orchestrator.test.js +++ b/tests/core/orchestration/bob-orchestrator.test.js @@ -15,6 +15,10 @@ const { // Test fixtures const TEST_PROJECT_ROOT = path.join(__dirname, '../../fixtures/test-project-bob'); +function portablePath(targetPath) { + return String(targetPath).replace(/\\/g, '/'); +} + // Mock Epic 11 modules jest.mock('../../../.aiox-core/core/config/config-resolver', () => ({ resolveConfig: jest.fn(), @@ -1061,7 +1065,7 @@ describe('BobOrchestrator', () => { const result = orchestrator._resolveStoryPath('99.99'); // Then - expect(result).toContain('docs/stories/active'); + expect(portablePath(result)).toContain('docs/stories/active'); expect(result).toContain('99.99.story.md'); }); });