knowledge-graph-preview / cli /arg-parser.js
mr4's picture
Upload 136 files
fd8cdf5 verified
export const SUPPORTED_TYPES = ['kiro', 'codex', 'opencode', 'claude-code', 'openclaw', 'cursor', 'openspec'];
export function parseArgs(argv) {
let inputPath = '';
let port = 3000;
let open = true;
let watch = true;
let init = false;
let full = false;
let command = 'help';
let type;
let i = 0;
while (i < argv.length) {
const arg = argv[i];
if (arg === '--help' || arg === '-h') {
command = 'help';
i++;
}
else if (arg === '--preview') {
command = 'preview';
i++;
if (i < argv.length && !argv[i].startsWith('-')) {
inputPath = argv[i];
i++;
}
}
else if (arg.startsWith('--preview=')) {
command = 'preview';
inputPath = arg.slice('--preview='.length);
i++;
}
else if (arg === '--create-md') {
command = 'create-md';
i++;
// Optional: next argument is the target path (if not a flag)
if (i < argv.length && !argv[i].startsWith('-')) {
inputPath = argv[i];
i++;
}
}
else if (arg.startsWith('--create-md=')) {
command = 'create-md';
inputPath = arg.slice('--create-md='.length);
i++;
}
else if (arg === '--analyze') {
command = 'analyze';
i++;
// Optional: next argument is the target path (if not a flag)
if (i < argv.length && !argv[i].startsWith('-')) {
inputPath = argv[i];
i++;
}
}
else if (arg.startsWith('--analyze=')) {
command = 'analyze';
inputPath = arg.slice('--analyze='.length);
i++;
}
else if (arg === '--full') {
full = true;
i++;
}
else if (arg === '--type') {
i++;
if (i < argv.length) {
const val = argv[i];
if (SUPPORTED_TYPES.includes(val)) {
type = val;
}
else {
return { success: false, error: `Invalid type: "${argv[i]}". Supported types: ${SUPPORTED_TYPES.join(', ')}` };
}
i++;
}
else {
return { success: false, error: `Missing value for --type. Supported types: ${SUPPORTED_TYPES.join(', ')}` };
}
}
else if (arg.startsWith('--type=')) {
const val = arg.slice('--type='.length);
if (SUPPORTED_TYPES.includes(val)) {
type = val;
}
else {
return { success: false, error: `Invalid type: "${val}". Supported types: ${SUPPORTED_TYPES.join(', ')}` };
}
i++;
}
else if (arg === '--no-open') {
open = false;
i++;
}
else if (arg === '--no-watch') {
watch = false;
i++;
}
else if (arg === '--init') {
init = true;
i++;
}
else if (arg === '--port') {
i++;
const portValue = argv[i];
const parsed = parsePort(portValue);
if (parsed === null) {
return { success: false, error: `Invalid port: ${portValue ?? ''}. Must be a number between 1 and 65535` };
}
port = parsed;
i++;
}
else if (arg.startsWith('--port=')) {
const portValue = arg.slice('--port='.length);
const parsed = parsePort(portValue);
if (parsed === null) {
return { success: false, error: `Invalid port: ${portValue}. Must be a number between 1 and 65535` };
}
port = parsed;
i++;
}
else if (arg.startsWith('-')) {
// Unknown flag — ignore (forward-compatible)
i++;
}
else {
// Positional argument — ignore
i++;
}
}
// Validation
if (command === 'preview' && !inputPath) {
return { success: false, error: 'Missing required path for --preview. Usage: project-understand --preview <path>' };
}
return {
success: true,
options: {
command,
inputPath,
port,
open,
watch,
init,
full,
type,
},
};
}
function parsePort(value) {
if (value === undefined || value === '') {
return null;
}
const num = Number(value);
if (!Number.isInteger(num) || num < 1 || num > 65535) {
return null;
}
return num;
}
export function getUsageText() {
return `Usage: project-understand [command] [options]
Commands:
--preview <path> Start a local preview server for dashboard files
--create-md [path] Generate agent config files for the target directory (default: current dir)
--analyze [path] Run static code analysis and generate a knowledge graph (default: current dir)
Options:
--type <type> Template type for --create-md (required)
Supported: kiro, codex, opencode, claude-code, openclaw, cursor, openspec
--init Install openspec globally and run 'openspec init' before generating files
--full Force full rebuild when running --analyze (skip incremental mode)
--port <number> Port for the preview server (default: 3000)
--no-open Do not open the browser automatically
--no-watch Do not watch for file changes
--help, -h Show this help message
Examples:
project-understand --preview ./dashboards
project-understand --preview ./my-dashboard.json --port 8080
project-understand --create-md --type kiro
project-understand --create-md ./my-project --type codex
project-understand --create-md --type openspec --init
project-understand --analyze
project-understand --analyze ./my-project
project-understand --analyze ./my-project --full`;
}