aiwg
Version:
Deployment tool and support utility for AI context. Copies agents, skills, commands, rules, and behaviors into the paths each AI platform reads (Claude Code, Codex, Copilot, Cursor, Warp, OpenClaw, and 6 more) so one source of truth works across 10 platfo
112 lines • 3.14 kB
JavaScript
/**
* Artifact Index Reader
*
* Shared utility to load .aiwg/.index/ JSON files.
* Used by query, deps, and stats commands.
*
* @implements #420
* @source @src/artifacts/types.ts
* @tests @test/unit/artifacts/index-reader.test.ts
*/
import fs from 'fs';
import path from 'path';
import { INDEX_DIR, getGraphIndexDir } from './types.js';
/**
* Load a JSON file from the index directory
*
* @param cwd - Project root directory
* @param filename - JSON file to load (e.g. 'metadata.json')
* @returns Parsed JSON or null if file doesn't exist or is corrupt
*/
export function loadIndexFile(cwd, filename) {
const filePath = path.join(cwd, INDEX_DIR, filename);
if (!fs.existsSync(filePath)) {
return null;
}
try {
const content = fs.readFileSync(filePath, 'utf-8');
return JSON.parse(content);
}
catch {
return null;
}
}
/**
* Load the master metadata index
*/
export function loadMetadataIndex(cwd) {
return loadIndexFile(cwd, 'metadata.json');
}
/**
* Load the tag reverse index
*/
export function loadTagIndex(cwd) {
return loadIndexFile(cwd, 'tags.json');
}
/**
* Load the dependency graph
*/
export function loadDependencyGraph(cwd) {
return loadIndexFile(cwd, 'dependencies.json');
}
/**
* Load the index statistics
*/
export function loadIndexStats(cwd) {
return loadIndexFile(cwd, 'stats.json');
}
/**
* Check if an index exists
*/
export function indexExists(cwd) {
const metadataPath = path.join(cwd, INDEX_DIR, 'metadata.json');
return fs.existsSync(metadataPath);
}
/**
* Write a JSON file to the index directory atomically
*
* Uses write-to-temp + rename for POSIX-safe atomic writes.
*
* @param cwd - Project root directory
* @param filename - JSON file to write
* @param data - Data to serialize
* @param indexDir - Override index directory (for multi-graph support)
*/
export function writeIndexFile(cwd, filename, data, indexDir) {
const dirPath = indexDir ?? path.join(cwd, INDEX_DIR);
const filePath = path.join(dirPath, filename);
const tmpPath = `${filePath}.tmp`;
// Ensure directory exists
fs.mkdirSync(dirPath, { recursive: true });
// Write to temp, then rename (atomic on POSIX)
fs.writeFileSync(tmpPath, JSON.stringify(data, null, 2), 'utf-8');
fs.renameSync(tmpPath, filePath);
}
/**
* Resolve the index directory for a graph type
*
* @param cwd - Project root directory
* @param graph - Graph type (undefined = default .aiwg/.index/)
* @returns Absolute path to the index directory
*/
export function resolveIndexDir(cwd, graph) {
if (graph)
return getGraphIndexDir(cwd, graph);
return path.join(cwd, INDEX_DIR);
}
/**
* Load a JSON file from a graph-specific index directory
*/
export function loadGraphIndexFile(cwd, filename, graph) {
const dir = resolveIndexDir(cwd, graph);
const filePath = path.join(dir, filename);
if (!fs.existsSync(filePath))
return null;
try {
return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
}
catch {
return null;
}
}
//# sourceMappingURL=index-reader.js.map