From f45fb79a87bae8f100e7fa9cc859837dbaa5afe3 Mon Sep 17 00:00:00 2001 From: Amr Elsayed Date: Thu, 28 May 2026 10:56:38 +1000 Subject: [PATCH 1/5] chore(porch): bugfix-895 init bugfix --- .../status.yaml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 codev/projects/bugfix-895-vscode-uppercase-area-group-he/status.yaml diff --git a/codev/projects/bugfix-895-vscode-uppercase-area-group-he/status.yaml b/codev/projects/bugfix-895-vscode-uppercase-area-group-he/status.yaml new file mode 100644 index 00000000..955427c4 --- /dev/null +++ b/codev/projects/bugfix-895-vscode-uppercase-area-group-he/status.yaml @@ -0,0 +1,14 @@ +id: bugfix-895 +title: vscode-uppercase-area-group-he +protocol: bugfix +phase: investigate +plan_phases: [] +current_plan_phase: null +gates: + pr: + status: pending +iteration: 1 +build_complete: false +history: [] +started_at: '2026-05-28T00:56:37.908Z' +updated_at: '2026-05-28T00:56:37.908Z' From a3901ac4743197fd47db1b061cc35ddb71c82110 Mon Sep 17 00:00:00 2001 From: Amr Elsayed Date: Thu, 28 May 2026 10:57:55 +1000 Subject: [PATCH 2/5] chore(porch): bugfix-895 fix phase-transition --- .../bugfix-895-vscode-uppercase-area-group-he/status.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/codev/projects/bugfix-895-vscode-uppercase-area-group-he/status.yaml b/codev/projects/bugfix-895-vscode-uppercase-area-group-he/status.yaml index 955427c4..445ed50d 100644 --- a/codev/projects/bugfix-895-vscode-uppercase-area-group-he/status.yaml +++ b/codev/projects/bugfix-895-vscode-uppercase-area-group-he/status.yaml @@ -1,7 +1,7 @@ id: bugfix-895 title: vscode-uppercase-area-group-he protocol: bugfix -phase: investigate +phase: fix plan_phases: [] current_plan_phase: null gates: @@ -11,4 +11,4 @@ iteration: 1 build_complete: false history: [] started_at: '2026-05-28T00:56:37.908Z' -updated_at: '2026-05-28T00:56:37.908Z' +updated_at: '2026-05-28T00:57:55.884Z' From 2de9376a855ced8fcaf595a0f889dadcde1b32f5 Mon Sep 17 00:00:00 2001 From: Amr Elsayed Date: Thu, 28 May 2026 11:00:58 +1000 Subject: [PATCH 3/5] [Bugfix #895] UPPERCASE area group headers in VSCode sidebar Supersedes #885's per-word capitalization with a full uppercase transform, matching VSCode's own container-label convention (EXPLORER, SOURCE CONTROL, etc.). - `formatAreaForDisplay` renamed to `uppercaseAreaName`; implementation is now `area.toUpperCase()`. - Separators are preserved verbatim: `cross-cutting` -> `CROSS-CUTTING`, `front_end` -> `FRONT_END`. The previous behavior split-and-rejoined with spaces; the new behavior is a single character-level transform. - Tests rewritten against the new contract. --- codev/state/bugfix-895_thread.md | 15 ++++++++ packages/core/src/area-grouping.ts | 23 +++++------- .../vscode/src/test/area-grouping.test.ts | 37 +++++++++---------- .../vscode/src/views/area-group-tree-item.ts | 8 ++-- 4 files changed, 47 insertions(+), 36 deletions(-) create mode 100644 codev/state/bugfix-895_thread.md diff --git a/codev/state/bugfix-895_thread.md b/codev/state/bugfix-895_thread.md new file mode 100644 index 00000000..d52dc93e --- /dev/null +++ b/codev/state/bugfix-895_thread.md @@ -0,0 +1,15 @@ +# bugfix-895 thread + +## Investigate +- Issue #895: Replace per-word capitalization with full uppercase for area group headers in VSCode sidebar. +- Current `formatAreaForDisplay` in `packages/core/src/area-grouping.ts` splits on `[-_\s]+`, capitalizes first char of each word, joins with space. Produces `Cross Cutting` for `cross-cutting`. +- Issue's before/after table shows `Cross-cutting (1)` → `CROSS-CUTTING (1)` (preserves hyphen). The simplest reading that matches the table: replace the entire pipeline with `area.toUpperCase()`. That preserves `-` and `_` and matches every example in the table. +- Plan: rename `formatAreaForDisplay` → `uppercaseAreaName`, implementation becomes `area.toUpperCase()`. Update test + one caller in `area-group-tree-item.ts`. +- Callers: `packages/vscode/src/views/area-group-tree-item.ts` (one site) + tests in `packages/vscode/src/test/area-grouping.test.ts`. + +## Fix +- `packages/core/src/area-grouping.ts`: replaced multi-step pipeline with `area.toUpperCase()`; renamed `formatAreaForDisplay` → `uppercaseAreaName`; updated docstring. +- `packages/vscode/src/views/area-group-tree-item.ts`: import + call site renamed; updated docstring comment. +- `packages/vscode/src/test/area-grouping.test.ts`: suite renamed + assertions updated to uppercase expectations. Separator behavior changed: hyphens/underscores are now preserved (e.g. `cross-cutting` → `CROSS-CUTTING`, not `CROSS CUTTING`) — matches the issue's before/after table. The old "consecutive-separator collapsing" test was repurposed to lock in verbatim preservation. +- Verified: `pnpm --filter @cluesmith/codev-core build` (tsc), `pnpm --filter codev-vscode check-types`, `pnpm --filter codev-vscode lint`, `pnpm --filter codev-vscode test:unit` (49 pass), `pnpm --filter codev-vscode compile-tests` all clean. + diff --git a/packages/core/src/area-grouping.ts b/packages/core/src/area-grouping.ts index 1f2d4752..5b0ae355 100644 --- a/packages/core/src/area-grouping.ts +++ b/packages/core/src/area-grouping.ts @@ -8,24 +8,21 @@ import { UNCATEGORIZED_AREA } from './constants.js'; * `UNCATEGORIZED_AREA` sentinel) MUST continue to be used for * bucketing (`groupByArea`), id stability, and `===` matchers. * - * Rule: split on `-`, `_`, and whitespace; capitalize the first - * character of each word; rejoin with a single space. Examples: - * 'vscode' -> 'Vscode' - * 'cross-cutting' -> 'Cross Cutting' - * 'front_end' -> 'Front End' - * 'Uncategorized' -> 'Uncategorized' (no-op; sentinel is already - * single-word, first-char-upper) + * Rule: uppercase the entire string. Separators (`-`, `_`) are + * preserved as-is so the header reads as a single visual token + * matching VSCode's own container-label convention (EXPLORER, + * SOURCE CONTROL, etc.). Examples: + * 'vscode' -> 'VSCODE' + * 'cross-cutting' -> 'CROSS-CUTTING' + * 'front_end' -> 'FRONT_END' + * 'Uncategorized' -> 'UNCATEGORIZED' * * Purely structural: no hardcoded list of "known acronyms". Teams * using Codev decide their own labeling semantics; a per-repo * override map can be layered on top as a non-breaking extension. */ -export function formatAreaForDisplay(area: string): string { - return area - .split(/[-_\s]+/) - .filter(w => w.length > 0) - .map(w => w.charAt(0).toUpperCase() + w.slice(1)) - .join(' '); +export function uppercaseAreaName(area: string): string { + return area.toUpperCase(); } /** diff --git a/packages/vscode/src/test/area-grouping.test.ts b/packages/vscode/src/test/area-grouping.test.ts index 9dc97823..319638e7 100644 --- a/packages/vscode/src/test/area-grouping.test.ts +++ b/packages/vscode/src/test/area-grouping.test.ts @@ -1,5 +1,5 @@ import * as assert from 'assert'; -import { groupByArea, formatAreaForDisplay } from '@cluesmith/codev-core/area-grouping'; +import { groupByArea, uppercaseAreaName } from '@cluesmith/codev-core/area-grouping'; interface AreaItem { id: string; @@ -81,36 +81,35 @@ suite('groupByArea', () => { }); }); -suite('formatAreaForDisplay', () => { - test('lowercase single word -> capitalized first char', () => { - assert.strictEqual(formatAreaForDisplay('vscode'), 'Vscode'); - assert.strictEqual(formatAreaForDisplay('tower'), 'Tower'); - assert.strictEqual(formatAreaForDisplay('porch'), 'Porch'); +suite('uppercaseAreaName', () => { + test('lowercase single word -> full uppercase', () => { + assert.strictEqual(uppercaseAreaName('vscode'), 'VSCODE'); + assert.strictEqual(uppercaseAreaName('tower'), 'TOWER'); + assert.strictEqual(uppercaseAreaName('porch'), 'PORCH'); }); - test('hyphenated -> separator replaced with space, each word capitalized', () => { - assert.strictEqual(formatAreaForDisplay('cross-cutting'), 'Cross Cutting'); + test('hyphenated -> uppercase with hyphen preserved', () => { + assert.strictEqual(uppercaseAreaName('cross-cutting'), 'CROSS-CUTTING'); }); - test('underscored -> separator replaced with space, each word capitalized', () => { - assert.strictEqual(formatAreaForDisplay('front_end'), 'Front End'); + test('underscored -> uppercase with underscore preserved', () => { + assert.strictEqual(uppercaseAreaName('front_end'), 'FRONT_END'); }); - test('mixed separators and >2 words', () => { - assert.strictEqual(formatAreaForDisplay('front-end_ui'), 'Front End Ui'); + test('mixed separators preserved verbatim', () => { + assert.strictEqual(uppercaseAreaName('front-end_ui'), 'FRONT-END_UI'); }); - test('Uncategorized sentinel is a no-op (single word, first char already upper)', () => { - assert.strictEqual(formatAreaForDisplay('Uncategorized'), 'Uncategorized'); + test('Uncategorized sentinel uppercases to UNCATEGORIZED', () => { + assert.strictEqual(uppercaseAreaName('Uncategorized'), 'UNCATEGORIZED'); }); test('empty string -> empty string (defensive)', () => { - assert.strictEqual(formatAreaForDisplay(''), ''); + assert.strictEqual(uppercaseAreaName(''), ''); }); - test('collapses multiple consecutive separators', () => { - // Pathological but cheap to lock — no accidental double-spacing. - assert.strictEqual(formatAreaForDisplay('a--b'), 'A B'); - assert.strictEqual(formatAreaForDisplay('a__b'), 'A B'); + test('consecutive separators preserved verbatim (no collapsing)', () => { + assert.strictEqual(uppercaseAreaName('a--b'), 'A--B'); + assert.strictEqual(uppercaseAreaName('a__b'), 'A__B'); }); }); diff --git a/packages/vscode/src/views/area-group-tree-item.ts b/packages/vscode/src/views/area-group-tree-item.ts index d0d579dc..5dd5e474 100644 --- a/packages/vscode/src/views/area-group-tree-item.ts +++ b/packages/vscode/src/views/area-group-tree-item.ts @@ -1,5 +1,5 @@ import * as vscode from 'vscode'; -import { formatAreaForDisplay } from '@cluesmith/codev-core/area-grouping'; +import { uppercaseAreaName } from '@cluesmith/codev-core/area-grouping'; export type AreaGroupKind = 'backlog' | 'builder'; @@ -17,8 +17,8 @@ export type AreaGroupKind = 'backlog' | 'builder'; * `areaName`, `id`, and `contextValue` all use the raw wire value so * expansion-state persistence and `areaName === ...` matchers in the * per-view providers keep working. Only the human-visible label is - * passed through `formatAreaForDisplay` (title-case + separator-to- - * space, see #885). + * passed through `uppercaseAreaName`, matching VSCode's own + * container-label convention (EXPLORER, SOURCE CONTROL, etc.). */ export class AreaGroupTreeItem extends vscode.TreeItem { constructor( @@ -27,7 +27,7 @@ export class AreaGroupTreeItem extends vscode.TreeItem { count: number, collapsibleState: vscode.TreeItemCollapsibleState, ) { - super(`${formatAreaForDisplay(areaName)} (${count})`, collapsibleState); + super(`${uppercaseAreaName(areaName)} (${count})`, collapsibleState); this.id = `${kind}-group:${areaName}`; this.contextValue = `${kind}-group`; } From d2c41a2488e912b1a3bade1f4845ea16fe714026 Mon Sep 17 00:00:00 2001 From: Amr Elsayed Date: Thu, 28 May 2026 11:01:29 +1000 Subject: [PATCH 4/5] chore(porch): bugfix-895 pr phase-transition --- .../bugfix-895-vscode-uppercase-area-group-he/status.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/codev/projects/bugfix-895-vscode-uppercase-area-group-he/status.yaml b/codev/projects/bugfix-895-vscode-uppercase-area-group-he/status.yaml index 445ed50d..e0a4c07b 100644 --- a/codev/projects/bugfix-895-vscode-uppercase-area-group-he/status.yaml +++ b/codev/projects/bugfix-895-vscode-uppercase-area-group-he/status.yaml @@ -1,7 +1,7 @@ id: bugfix-895 title: vscode-uppercase-area-group-he protocol: bugfix -phase: fix +phase: pr plan_phases: [] current_plan_phase: null gates: @@ -11,4 +11,4 @@ iteration: 1 build_complete: false history: [] started_at: '2026-05-28T00:56:37.908Z' -updated_at: '2026-05-28T00:57:55.884Z' +updated_at: '2026-05-28T01:01:29.477Z' From 47234660e7fd87b2852eb4707b9b3a67fc869c26 Mon Sep 17 00:00:00 2001 From: Amr Elsayed Date: Thu, 28 May 2026 11:02:24 +1000 Subject: [PATCH 5/5] chore(porch): bugfix-895 pr gate-requested --- .../bugfix-895-vscode-uppercase-area-group-he/status.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/codev/projects/bugfix-895-vscode-uppercase-area-group-he/status.yaml b/codev/projects/bugfix-895-vscode-uppercase-area-group-he/status.yaml index e0a4c07b..018c0e7b 100644 --- a/codev/projects/bugfix-895-vscode-uppercase-area-group-he/status.yaml +++ b/codev/projects/bugfix-895-vscode-uppercase-area-group-he/status.yaml @@ -7,8 +7,10 @@ current_plan_phase: null gates: pr: status: pending + requested_at: '2026-05-28T01:02:24.638Z' iteration: 1 build_complete: false history: [] started_at: '2026-05-28T00:56:37.908Z' -updated_at: '2026-05-28T01:01:29.477Z' +updated_at: '2026-05-28T01:02:24.638Z' +pr_ready_for_human: true