mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-17 03:03:44 +00:00
Centralize frontmatter parsing + parse frontmatter with yaml library (#728)
* Add frontmatter utility and tidy coding agent prompts * Add frontmatter parsing utilities and tests * Parse frontmatter with YAML parser * Simplify frontmatter parsing utilities * strip body in 1 place * Improve frontmatter parsing error handling * Normalize multiline skill and select-list descriptions
This commit is contained in:
parent
df58d3191e
commit
ce7e73b503
14 changed files with 213 additions and 126 deletions
|
|
@ -2,6 +2,8 @@ import { getEditorKeybindings } from "../keybindings.js";
|
|||
import type { Component } from "../tui.js";
|
||||
import { truncateToWidth } from "../utils.js";
|
||||
|
||||
const normalizeToSingleLine = (text: string): string => text.replace(/[\r\n]+/g, " ").trim();
|
||||
|
||||
export interface SelectItem {
|
||||
value: string;
|
||||
label: string;
|
||||
|
|
@ -70,6 +72,7 @@ export class SelectList implements Component {
|
|||
if (!item) continue;
|
||||
|
||||
const isSelected = i === this.selectedIndex;
|
||||
const descriptionSingleLine = item.description ? normalizeToSingleLine(item.description) : undefined;
|
||||
|
||||
let line = "";
|
||||
if (isSelected) {
|
||||
|
|
@ -77,7 +80,7 @@ export class SelectList implements Component {
|
|||
const prefixWidth = 2; // "→ " is 2 characters visually
|
||||
const displayValue = item.label || item.value;
|
||||
|
||||
if (item.description && width > 40) {
|
||||
if (descriptionSingleLine && width > 40) {
|
||||
// Calculate how much space we have for value + description
|
||||
const maxValueWidth = Math.min(30, width - prefixWidth - 4);
|
||||
const truncatedValue = truncateToWidth(displayValue, maxValueWidth, "");
|
||||
|
|
@ -88,7 +91,7 @@ export class SelectList implements Component {
|
|||
const remainingWidth = width - descriptionStart - 2; // -2 for safety
|
||||
|
||||
if (remainingWidth > 10) {
|
||||
const truncatedDesc = truncateToWidth(item.description, remainingWidth, "");
|
||||
const truncatedDesc = truncateToWidth(descriptionSingleLine, remainingWidth, "");
|
||||
// Apply selectedText to entire line content
|
||||
line = this.theme.selectedText(`→ ${truncatedValue}${spacing}${truncatedDesc}`);
|
||||
} else {
|
||||
|
|
@ -105,7 +108,7 @@ export class SelectList implements Component {
|
|||
const displayValue = item.label || item.value;
|
||||
const prefix = " ";
|
||||
|
||||
if (item.description && width > 40) {
|
||||
if (descriptionSingleLine && width > 40) {
|
||||
// Calculate how much space we have for value + description
|
||||
const maxValueWidth = Math.min(30, width - prefix.length - 4);
|
||||
const truncatedValue = truncateToWidth(displayValue, maxValueWidth, "");
|
||||
|
|
@ -116,7 +119,7 @@ export class SelectList implements Component {
|
|||
const remainingWidth = width - descriptionStart - 2; // -2 for safety
|
||||
|
||||
if (remainingWidth > 10) {
|
||||
const truncatedDesc = truncateToWidth(item.description, remainingWidth, "");
|
||||
const truncatedDesc = truncateToWidth(descriptionSingleLine, remainingWidth, "");
|
||||
const descText = this.theme.description(spacing + truncatedDesc);
|
||||
line = prefix + truncatedValue + descText;
|
||||
} else {
|
||||
|
|
|
|||
30
packages/tui/test/select-list.test.ts
Normal file
30
packages/tui/test/select-list.test.ts
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
import assert from "node:assert";
|
||||
import { describe, it } from "node:test";
|
||||
import { SelectList } from "../src/components/select-list.js";
|
||||
|
||||
const testTheme = {
|
||||
selectedPrefix: (text: string) => text,
|
||||
selectedText: (text: string) => text,
|
||||
description: (text: string) => text,
|
||||
scrollInfo: (text: string) => text,
|
||||
noMatch: (text: string) => text,
|
||||
};
|
||||
|
||||
describe("SelectList", () => {
|
||||
it("normalizes multiline descriptions to single line", () => {
|
||||
const items = [
|
||||
{
|
||||
value: "test",
|
||||
label: "test",
|
||||
description: "Line one\nLine two\nLine three",
|
||||
},
|
||||
];
|
||||
|
||||
const list = new SelectList(items, 5, testTheme);
|
||||
const rendered = list.render(100);
|
||||
|
||||
assert.ok(rendered.length > 0);
|
||||
assert.ok(!rendered[0].includes("\n"));
|
||||
assert.ok(rendered[0].includes("Line one Line two Line three"));
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue