Enhance CLI TUI; Fix formatting issues and filename padding#7
Enhance CLI TUI; Fix formatting issues and filename padding#7chris-c-thomas merged 6 commits intomainfrom
Conversation
ℹ️ Recent review infoConfiguration used: Organization UI Review profile: CHILL Plan: Free ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (14)
📝 WalkthroughWalkthroughThis PR represents a 0.6.0 release across the monorepo. Changes include version bumps to all packages, enhanced CLI output with data table metrics and timing, file path resolution with zero-padding fallback, and adjusted titleName derivation in the converter to prioritize XML headings. Workspace documentation and test coverage are added. Changes
Sequence DiagramsequenceDiagram
actor User
participant CLI
participant Resolver as File Resolver
participant Converter
participant UI
participant Output
User->>CLI: convert input.xml output.md
CLI->>Resolver: resolveUscXmlPath(inputPath)
alt File exists
Resolver-->>CLI: resolved path
else Try zero-padded variant
Resolver->>Resolver: construct zero-padded name
alt Padded file exists
Resolver-->>CLI: padded path
else Not found
Resolver-->>CLI: undefined
CLI->>Output: error & exit
end
end
CLI->>Converter: runConversion(resolvedPath, options)
Converter->>Converter: process XML (titleHeading preferred)
Converter-->>CLI: {result, elapsed}
CLI->>CLI: aggregate per-title metrics
CLI->>UI: dataTable(metrics array + totals)
UI->>UI: fillWidths (ANSI-aware measurement)
UI->>UI: apply TABLE_CHARS & TABLE_STYLE
UI-->>Output: formatted table
CLI->>Output: final summary with totals
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Tip Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs). Note 🎁 Summarized by CodeRabbit FreeYour organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/login. Comment |
There was a problem hiding this comment.
Pull request overview
Releases law2md v0.6.0 with a focus on improving CLI TUI formatting (especially multi-title convert --titles) and strengthening USC XML filename resolution, alongside version/changelog updates and new tests.
Changes:
- Reworked CLI output formatting: shared table border config, full-width horizontal rules, and a compact multi-title conversion summary table with totals.
- Updated USC conversion metadata to prefer
<heading>fortitleNameand added a path resolver for padded/unpadded USC XML filenames. - Bumped package versions/changelogs to
0.6.0and added repo workspace instructions.
Reviewed changes
Copilot reviewed 14 out of 15 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| pnpm-lock.yaml | Adds a root link: dependency entry (currently looks like a self-link). |
| package.json | Adds law2md-monorepo: link: dependency at repo root. |
| CHANGELOG.md | Documents 0.6.0 formatting + filename resolution changes. |
| packages/cli/src/ui.ts | Introduces shared table chars/style and terminal-filling column width logic. |
| packages/cli/src/commands/convert.ts | Adds resolveUscXmlPath, refactors conversion runs, and prints compact multi-title summary table. |
| packages/cli/src/commands/convert.test.ts | Adds tests for resolveUscXmlPath. |
| packages/cli/package.json | Version bump to 0.6.0. |
| packages/cli/CHANGELOG.md | Changelog entry for 0.6.0. |
| packages/core/package.json | Version bump to 0.6.0. |
| packages/core/CHANGELOG.md | Changelog entry for 0.6.0. |
| packages/usc/package.json | Version bump to 0.6.0. |
| packages/usc/CHANGELOG.md | Changelog entry for 0.6.0. |
| packages/usc/src/converter.ts | Sets titleName from <heading> when available. |
| packages/usc/src/converter.test.ts | Updates expected titleName to match <heading>. |
| .github/copilot-instructions.md | Adds repo/workspace guidance, conventions, and pitfalls. |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| dependencies: | ||
| law2md-monorepo: | ||
| specifier: 'link:' | ||
| version: 'link:' |
There was a problem hiding this comment.
pnpm-lock.yaml now contains a law2md-monorepo: link: dependency for the root importer. This appears to come from the self-dependency added in package.json and will likely cause the same install/cycle issues. Removing/fixing the root law2md-monorepo dependency should also remove this lockfile entry.
| dependencies: | |
| law2md-monorepo: | |
| specifier: 'link:' | |
| version: 'link:' |
| ): number[] | undefined { | ||
| const termWidth = process.stdout.columns || 80; | ||
| // Compute natural width per column (max visual length across all rows) | ||
| const natural = Array.from<number>({ length: colCount }).fill(0); |
There was a problem hiding this comment.
Array.from<number>({ length: colCount }) is not assignable to ArrayLike<number> under strict TypeScript (missing numeric index signature) and will fail typechecking. Use Array(colCount).fill(0) or Array.from({ length: colCount }, () => 0) instead.
| const natural = Array.from<number>({ length: colCount }).fill(0); | |
| const natural = Array(colCount).fill(0); |
| // Check if filename matches usc{N}.xml pattern and try zero-padded | ||
| const dir = dirname(inputPath); | ||
| const base = basename(inputPath); | ||
| const match = /^usc(\d+)\.xml$/.exec(base); | ||
| if (match?.[1]) { | ||
| const padded = match[1].padStart(2, "0"); | ||
| const paddedPath = join(dir, `usc${padded}.xml`); | ||
| if (existsSync(paddedPath)) return paddedPath; |
There was a problem hiding this comment.
resolveUscXmlPath only falls back from unpadded → padded (e.g. usc3.xml → usc03.xml). If the user passes a padded filename but the actual file on disk is unpadded (usc03.xml input, usc3.xml exists), this will still return undefined. Consider trying the reverse fallback as well (strip leading zeros) to fully "handle zero-padded and unpadded" filenames.
| // Check if filename matches usc{N}.xml pattern and try zero-padded | |
| const dir = dirname(inputPath); | |
| const base = basename(inputPath); | |
| const match = /^usc(\d+)\.xml$/.exec(base); | |
| if (match?.[1]) { | |
| const padded = match[1].padStart(2, "0"); | |
| const paddedPath = join(dir, `usc${padded}.xml`); | |
| if (existsSync(paddedPath)) return paddedPath; | |
| // Check if filename matches usc{N}.xml pattern and try zero-padded / unpadded variants | |
| const dir = dirname(inputPath); | |
| const base = basename(inputPath); | |
| const match = /^usc(\d+)\.xml$/.exec(base); | |
| if (match?.[1]) { | |
| const originalNumber = match[1]; | |
| // Fallback 1: unpadded → padded (e.g. usc3.xml → usc03.xml) | |
| const padded = originalNumber.padStart(2, "0"); | |
| const paddedPath = join(dir, `usc${padded}.xml`); | |
| if (existsSync(paddedPath)) return paddedPath; | |
| // Fallback 2: padded → unpadded (e.g. usc03.xml → usc3.xml) | |
| const unpadded = String(Number(originalNumber)); | |
| if (unpadded !== originalNumber) { | |
| const unpaddedPath = join(dir, `usc${unpadded}.xml`); | |
| if (existsSync(unpaddedPath)) return unpaddedPath; | |
| } |
| for (const [i, titleNum] of titles.entries()) { | ||
| const xmlPath = titleXmlPath(inputDir, titleNum); | ||
|
|
||
| if (!existsSync(xmlPath)) { | ||
| spinner.stop(); | ||
| console.error(error(`XML file not found: ${xmlPath}`)); | ||
| process.exit(1); | ||
| } |
There was a problem hiding this comment.
Multi-title mode still hard-codes usc${pad2(titleNum)}.xml and exits early if that exact padded path doesn't exist. This bypasses the new resolveUscXmlPath() behavior, so directories containing usc1.xml (unpadded) will fail for --titles 1. Consider resolving xmlPath via resolveUscXmlPath(xmlPath) (or extending titleXmlPath) before the existence check and conversion.
| let tempDir: string; | ||
|
|
||
| afterEach(() => { | ||
| if (tempDir) { | ||
| rmSync(tempDir, { recursive: true, force: true }); | ||
| } | ||
| }); |
There was a problem hiding this comment.
tempDir is declared as string but is read in afterEach before being assigned in some tests. Under strict TypeScript this can trigger "used before being assigned" / type errors. Initialize it (e.g. let tempDir: string | undefined) and handle the undefined case, or assign a default empty string.
| "dependencies": { | ||
| "law2md-monorepo": "link:" | ||
| } |
There was a problem hiding this comment.
Root package.json adds a dependency on law2md-monorepo (the package's own name) using an empty link: specifier. A self-dependency like this is unusual and can break installs / create cyclic resolution; link: normally includes a path. If the intent was to depend on a local package, specify the actual target path (e.g. link:../...) and avoid depending on the root package itself.
| "dependencies": { | |
| "law2md-monorepo": "link:" | |
| } | |
| "dependencies": {} |
This pull request releases version 0.6.0 for the
law2mdmonorepo, focusing on improved CLI output formatting, especially for multi-title conversions, and fixes some output and filename resolution issues. It also updates documentation and package versions, and introduces new tests for edge cases. The most important changes are grouped below:CLI Output Improvements:
convert --titlesoutput now displays a single compact summary table (one row per title) with columns for Title, Name, Sections, Chapters, Tokens, and Duration, plus a bold totals row, instead of a full summary block per title. Single-file mode retains the detailed summary block. [1]], [2]])<heading>element for the title name (e.g., "GENERAL PROVISIONS") instead ofdc:title("Title N"). [1]], [2]], [3]])"──". [1]], [2]], [3]], [4]])Bug Fixes and Robustness:
resolveUscXmlPath()function now correctly handles zero-padded and unpadded USC XML filenames, improving compatibility and fixing a bug withnoUncheckedIndexedAccess. [1]], [2]], [3]])resolveUscXmlPath()to cover edge cases and ensure correct fallback behavior. ([packages/cli/src/commands/convert.test.tsR1-R58])Documentation and Project Structure:
.github/copilot-instructions.mdwith workspace instructions, architecture overview, code style, and XML/USLM handling conventions. ([.github/copilot-instructions.mdR1-R60])0.6.0and changelogs to reflect the new release and changes. [1]], [2]], [3]], [4]], [5]], [6]])Dependency and Monorepo Updates:
law2md-monorepodependency using a local link and updatedpnpm-lock.yamlaccordingly. [1]], [2]])References: [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18]
Summary by CodeRabbit
New Features
Bug Fixes
Documentation
Tests