feat(ipuaro): add enum value definitions to initial context

Extract enum declarations with member names and values from TypeScript
AST and display them in the initial LLM context. This allows the LLM
to know valid enum values without making tool calls.

Features:
- Numeric values (Active=1)
- String values (Admin="admin")
- Implicit values (Up, Down)
- Negative numbers (Cold=-10)
- const enum modifier
- export enum modifier
- Long enum truncation (>100 chars)

Adds EnumInfo and EnumMemberInfo interfaces, extractEnum() method in
ASTParser, formatEnumSignature() in prompts.ts, and 17 new unit tests.
This commit is contained in:
imfozilbek
2025-12-05 13:14:51 +05:00
parent 806c9281b0
commit 5a22cd5c9b
7 changed files with 575 additions and 10 deletions

View File

@@ -240,6 +240,37 @@ function formatTypeAliasSignature(type: FileAST["typeAliases"][0]): string {
return `type ${type.name} = ${definition}`
}
/**
* Format an enum signature with members and values.
* Example: "enum Status { Active=1, Inactive=0, Pending=2 }"
* Example: "const enum Role { Admin="admin", User="user" }"
*/
function formatEnumSignature(enumInfo: FileAST["enums"][0]): string {
const constPrefix = enumInfo.isConst ? "const " : ""
if (enumInfo.members.length === 0) {
return `${constPrefix}enum ${enumInfo.name}`
}
const membersStr = enumInfo.members
.map((m) => {
if (m.value === undefined) {
return m.name
}
const valueStr = typeof m.value === "string" ? `"${m.value}"` : String(m.value)
return `${m.name}=${valueStr}`
})
.join(", ")
const result = `${constPrefix}enum ${enumInfo.name} { ${membersStr} }`
if (result.length > 100) {
return truncateDefinition(result, 100)
}
return result
}
/**
* Truncate long type definitions for display.
*/
@@ -297,6 +328,12 @@ function formatFileSummary(
}
}
if (ast.enums && ast.enums.length > 0) {
for (const enumInfo of ast.enums) {
lines.push(`- ${formatEnumSignature(enumInfo)}`)
}
}
if (lines.length === 1) {
return `- ${path}${flags}`
}
@@ -330,6 +367,11 @@ function formatFileSummaryCompact(path: string, ast: FileAST, flags: string): st
parts.push(`type: ${names}`)
}
if (ast.enums && ast.enums.length > 0) {
const names = ast.enums.map((e) => e.name).join(", ")
parts.push(`enum: ${names}`)
}
const summary = parts.length > 0 ? ` [${parts.join(" | ")}]` : ""
return `- ${path}${summary}${flags}`
}