import { buildGraphData, uriToWorkspacePath } from '@foam/core';
import { loadWorkspaceFromDirectory } from '../support/filesystem';
import { parseArgs, getFlag, resolveWorkspaceDir } from '../support/args';
import type { CliLogger } from '../support/types';
export const GRAPH_HELP = `Usage: foam graph [options]
Export the workspace link graph as JSON to stdout.
The output shape is compatible with d3-force and similar graph libraries:
{ "nodes": [ { "id", "type", "title", "properties", "tags" }, ... ],
"links": [ { "source", "target" }, ... ] }
Node IDs are workspace-relative POSIX paths.
Pipe to a file or another tool:
foam graph > graph.json
foam graph | jq '.nodes | length'
Options:
--include-placeholders Include broken-link targets as placeholder nodes
--workspace
Workspace root (default: FOAM_WORKSPACE env var, then cwd)
--help Show this help
`;
export async function runGraphCommand(
argv: string[],
logger: CliLogger
): Promise {
const parsed = parseArgs(argv);
if (getFlag(parsed, 'help')) {
logger.info(GRAPH_HELP);
return 0;
}
const includePlaceholders = getFlag(parsed, 'include-placeholders');
const workspaceDir = resolveWorkspaceDir(parsed);
try {
const { foam, workspace } = await loadWorkspaceFromDirectory(workspaceDir);
const { nodeInfo, links } = buildGraphData(
workspace.list(),
foam.graph.getAllConnections(),
{
resourceToId: uri => uriToWorkspacePath(uri, workspace),
includePlaceholders,
}
);
const output = { nodes: Object.values(nodeInfo), links };
logger.info(JSON.stringify(output, null, 2));
return 0;
} catch (err) {
logger.error(err instanceof Error ? err.message : String(err));
return 1;
}
}