Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions .aiox-core/core/pro/pro-updater.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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) {
Expand Down Expand Up @@ -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'));
Expand All @@ -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'));
Expand All @@ -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];
Expand Down
6 changes: 3 additions & 3 deletions .aiox-core/data/entity-registry.yaml
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions .aiox-core/install-manifest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
7 changes: 4 additions & 3 deletions tests/cli/aiox-delegate.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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([
Expand Down Expand Up @@ -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'));
Expand All @@ -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]),
);
});

Expand Down
6 changes: 5 additions & 1 deletion tests/core/orchestration/bob-orchestrator.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down Expand Up @@ -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');
});
});
Expand Down
Loading