Skip to content

Commit 5426f6f

Browse files
Merge pull request #60 from TwilioDevEd/feat/DEVED-13514-restore-char-detail-view
feat: Restore per-character detail view with UCS-2 highlighting
2 parents 6ce0fc5 + 2cf222a commit 5426f6f

36 files changed

Lines changed: 2961 additions & 172 deletions

.claude/settings.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"permissions": {
3+
"allow": [
4+
5+
]
6+
}
7+
}

.github/workflows/test.js.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ jobs:
1111

1212
strategy:
1313
matrix:
14-
node-version: [14.x, 16.x, 18.x, 19.x]
14+
node-version: [20.x, 22.x]
1515
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
16+
# Node 14/16/18 removed — EOL; lint-staged@16 requires >=20.17
1617

1718
steps:
1819
- uses: actions/checkout@v3

.gitignore

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,11 @@ typings/
3838
.DS_Store
3939

4040
# Context files (not for commits)
41-
.context/
41+
.context/
42+
43+
# Claude Code user-specific settings
44+
.claude/settings.local.json
45+
46+
# Playwright
47+
tests/e2e/results/
48+
tests/e2e/reports/

.husky/pre-commit

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
npx lint-staged

AGENTS.md

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# AGENTS.md — AI Agent Guidelines for Message Segment Calculator
2+
3+
This file provides universal guidelines for any AI agent (Claude Code, Codex, GitHub Copilot, or custom) working in this repository.
4+
5+
## Context Loading Protocol
6+
7+
Before starting any work:
8+
9+
1. Read `CLAUDE.md` for repo structure, conventions, and workflow
10+
2. Read this file for development workflow and review process
11+
3. Check `docs/pr-reviews/README.md` for the PR review process
12+
13+
## Development Workflow
14+
15+
```
16+
PLAN -> JIRA -> BRANCH -> CODE -> TESTS -> PR -> REVIEW
17+
```
18+
19+
1. **Plan**: Present a 3-7 bullet checklist before coding
20+
2. **JIRA**: Create or update a JIRA ticket using `createJiraService()` from `~/Projects/deved-agents/src/services/jira-service.js`
21+
3. **Branch**: Create branch as `{type}/{TICKET-KEY}-{description}`
22+
4. **Code**: Follow conventions in `CLAUDE.md`
23+
5. **Tests**: Run `npm run check` (lint + test), ensure all pass
24+
6. **PR**: Create PR with JIRA ticket key in description
25+
7. **Review**: Follow 3-agent + 1-human pattern (see below)
26+
27+
## PR Review Process
28+
29+
Every PR gets reviewed by 3 AI agents + 1 human:
30+
31+
| Reviewer | Focus | Template |
32+
|----------|-------|----------|
33+
| Claude Code | Architecture, quality, test coverage | `docs/pr-reviews/<ID>/claude.md` |
34+
| Codex | Correctness, security, edge cases | `docs/pr-reviews/<ID>/codex.md` |
35+
| GitHub Copilot | Inline suggestions, style | `docs/pr-reviews/<ID>/copilot.md` |
36+
| Human | Business logic, acceptance criteria | `docs/pr-reviews/<ID>/human.md` |
37+
38+
Create review scaffold: `mkdir docs/pr-reviews/<PR-number>` and add template files.
39+
40+
See `docs/pr-reviews/README.md` for the full review template and process.
41+
42+
## Security Gates
43+
44+
Before committing, verify:
45+
46+
- [ ] No secrets in code (API keys, tokens, passwords)
47+
- [ ] `.env` file is not staged
48+
- [ ] `.claude/settings.local.json` is not staged (gitignored)
49+
- [ ] No hardcoded credentials — use environment variables
50+
51+
## Quality Gates
52+
53+
Before creating a PR:
54+
55+
- [ ] `npm run check` passes (lint + test)
56+
- [ ] `npm run release` builds successfully
57+
- [ ] New UI uses CSS variables from `tokens.css`, not hard-coded colors
58+
- [ ] Interactive elements have `tabindex`, `role`, and `aria-label`
59+
- [ ] Both `dist/` and `docs/scripts/` built artifacts are committed
60+
61+
## JIRA Integration
62+
63+
DevEd JIRA is at `twilio-productivity.atlassian.net`, project `DEVED`.
64+
65+
Programmatic access uses `~/Projects/deved-agents/src/services/jira-service.js`:
66+
67+
```javascript
68+
import { createJiraService } from '~/Projects/deved-agents/src/services/jira-service.js';
69+
const jira = await createJiraService();
70+
const ticket = await jira.createTicket({
71+
summary: 'Messaging: Short description',
72+
description: 'Markdown description (auto-converted to ADF)',
73+
issueType: 'Task',
74+
component: 'DevEd Internal',
75+
storyPoints: 2,
76+
});
77+
```
78+
79+
Conventions:
80+
- Story points: 1, 2, 3, 5 (if 5+, consider breaking into an Epic)
81+
- Required: acceptance criteria on every ticket
82+
- Include JIRA key in branch name and PR description for auto-linking
83+
84+
## File Naming Conventions
85+
86+
| Element | Convention | Example |
87+
|---------|-----------|---------|
88+
| Library modules | PascalCase | `SegmentedMessage.ts` |
89+
| Browser modules | camelCase | `segmenter.ts`, `renderer.ts` |
90+
| Test files | camelCase + `.test.js` | `segments.test.js` |
91+
| CSS files | kebab-case | `tokens.css`, `components.css` |
92+
| PR review docs | `docs/pr-reviews/<PR#>/<reviewer>.md` | `docs/pr-reviews/60/claude.md` |
93+
94+
## Error Handling
95+
96+
- Library code (`src/libs/`) throws on invalid input (e.g., GSM-7 encoding with Unicode chars)
97+
- Browser code (`src/browser/`) catches errors and renders user-friendly messages
98+
- The `sms-error` element in `index.html` displays encoding errors gracefully

CLAUDE.md

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
# CLAUDE.md — Message Segment Calculator
2+
3+
You are a coding assistant working on Twilio's Message Segment Calculator, a TypeScript library and browser tool that helps customers understand how SMS and RCS messages are segmented and encoded.
4+
5+
## Quick Reference
6+
7+
```bash
8+
npm install # Install dependencies
9+
npm test # Type-check (tsc) + run tests (jest)
10+
npm run lint # ESLint on src/**/*.ts
11+
npm run lint:fix # ESLint with auto-fix
12+
npm run check # Lint + test (mirrors CI)
13+
npm run release # Type-check + webpack build (outputs to docs/scripts/)
14+
npm run build # Type-check only (tsc)
15+
npm run test:e2e # Playwright e2e tests (serves docs/ locally)
16+
npm run test:e2e:ui # Playwright interactive UI mode
17+
```
18+
19+
## Project Structure
20+
21+
```
22+
src/
23+
libs/ # Core library (encoding, segmentation)
24+
SegmentedMessage.ts # SMS segmentation logic (GSM-7 / UCS-2)
25+
RcsSegmentedMessage.ts # RCS segmentation logic (UTF-8)
26+
EncodedChar.ts # Single character with encoding info (isGSM7, codeUnits)
27+
Segment.ts # Segment container (extends Array)
28+
UserDataHeader.ts # UDH for multi-segment messages
29+
UnicodeToGSM.ts # GSM-7 character mapping table
30+
SmartEncodingMap.ts # Twilio Smart Encoding replacements
31+
textUtils.ts # Grapheme splitting utilities
32+
browser/ # Browser UI modules
33+
main.ts # Entry point, DOM wiring, event listeners
34+
segmenter.ts # Analysis functions (analyzeSms, analyzeRcs)
35+
renderer.ts # DOM rendering (segment tape, char detail, stats)
36+
types.ts # Shared type definitions (SmsAnalysis, RcsAnalysis, etc.)
37+
global.ts # Library exports for global scope
38+
index.ts # NPM package entry point
39+
docs/ # GitHub Pages site
40+
index.html # Main page
41+
scripts/ # Built JS bundles (from webpack)
42+
styles/ # CSS (tokens.css, layout.css, components.css, animations.css)
43+
pr-reviews/ # 3-agent + 1-human PR review docs
44+
tests/ # Test suites
45+
*.test.js # Jest unit tests
46+
e2e/ # Playwright e2e tests (char-detail.spec.ts, etc.)
47+
dist/ # Built library output (tsc)
48+
```
49+
50+
## Key Architecture Concepts
51+
52+
### SMS Encoding
53+
54+
- **GSM-7**: 7-bit encoding, 160 chars/segment (153 if multi-segment due to UDH)
55+
- **UCS-2**: 16-bit Unicode, 70 chars/segment (67 if multi-segment)
56+
- A single non-GSM character forces the entire message to UCS-2
57+
- `EncodedChar.isGSM7` identifies whether a character is in the GSM-7 set
58+
- `EncodedChar.codeUnits` gives the hex code units for any character
59+
60+
### RCS Encoding
61+
62+
- Always UTF-8
63+
- US: billed per 160-byte "Rich" segment
64+
- International: "Basic" (<=160 bytes) or "Single" (>160 bytes), no segmentation
65+
66+
### Browser UI Architecture
67+
68+
Data flows through three layers:
69+
1. **segmenter.ts**`analyzeSms()` / `analyzeRcs()` produce typed analysis objects
70+
2. **types.ts**`SmsAnalysis`, `RcsAnalysis`, `CharDetail`, `SegmentData` interfaces
71+
3. **renderer.ts** — Pure DOM rendering functions consume analysis objects and render to target elements
72+
73+
### Design System
74+
75+
- Dark theme using CSS custom properties in `docs/styles/tokens.css`
76+
- Font stack: Plus Jakarta Sans (display), DM Sans (body), JetBrains Mono (code)
77+
- All colors must use CSS variables from tokens.css, never hard-coded hex values
78+
- Segment palette: `--color-seg-N-bg` / `--color-seg-N-fg` (5 rotating colors)
79+
80+
## Code Conventions
81+
82+
- TypeScript throughout `src/`, compiled with `tsc`
83+
- ESLint with `eslint-config-twilio-ts` (includes prettier)
84+
- Named exports preferred over default exports for browser modules
85+
- Default exports used in core library (EncodedChar, Segment, etc.) — legacy pattern
86+
- `npm run lint` must pass with zero errors before committing (warnings are OK for pre-existing issues)
87+
- Accessibility: interactive elements need `tabindex`, `role`, and `aria-label`
88+
89+
## CI Pipeline
90+
91+
GitHub Actions runs on every PR to `main` (`.github/workflows/test.js.yml`):
92+
1. `npm install`
93+
2. `npm run lint` — ESLint (prettier + twilio-ts rules)
94+
3. `npm test` — tsc + jest
95+
96+
Matrix: Node 20.x, 22.x
97+
98+
Run `npm run check` locally to mirror CI before pushing.
99+
100+
## Pre-commit Hook
101+
102+
Husky + lint-staged runs `eslint --fix` on staged `src/**/*.ts` files at commit time.
103+
104+
## JIRA Conventions
105+
106+
- **Project**: DEVED on `twilio-productivity.atlassian.net`
107+
- **Component**: "DevEd Internal" for docs projects
108+
- **Branch naming**: `{type}/{TICKET-KEY}-{description}` (e.g., `feat/DEVED-13514-restore-char-detail-view`)
109+
- **PR auto-close**: Include JIRA ticket key in PR description
110+
- **Story points**: 1 (1-4 hrs), 2 (1-2 days), 3 (2-3 days), 5 (3-5 days)
111+
- **JIRA tooling**: Use `createJiraService()` from the deved-agents repo for programmatic ticket creation
112+
113+
## PR Workflow
114+
115+
1. Create branch from `main` with JIRA ticket key
116+
2. Implement, run `npm run check` locally
117+
3. Push and create PR with JIRA link in description
118+
4. Follow 3-agent + 1-human review (see `docs/pr-reviews/README.md`)
119+
5. Address review feedback
120+
6. Squash and merge
121+
122+
## E2E Testing (Playwright)
123+
124+
Tests live in `tests/e2e/` and run against the built `docs/` site:
125+
- Config: `playwright.config.ts` — auto-serves `docs/` on port 8080
126+
- Results/reports: `tests/e2e/results/` and `tests/e2e/reports/` (gitignored)
127+
- `tsconfig.json` includes only `src/`; `jest` ignores `tests/e2e/` — this prevents tsc and Jest from picking up Playwright files
128+
129+
Best practices:
130+
- Use semantic selectors (`#sms-char-detail`, `.char-block`) and Playwright's auto-waiting
131+
- Check attributes directly (`toHaveAttribute('hidden', '')`) when `toBeHidden()` doesn't work for elements inside open `<details>`
132+
- Run `npm run release` before e2e tests to ensure `docs/scripts/` bundles are current
133+
- Always rebuild dist/docs artifacts before committing changes to `src/browser/`
134+
135+
## Codex CLI Review
136+
137+
Run `codex review --base main` for automated code review. For re-reviews after changes:
138+
```bash
139+
codex review --base main --title "PR title here"
140+
```
141+
Capture findings in `docs/pr-reviews/<PR>/codex.md`. Mark issues as `[x]` when fixed and note which commit resolved them.
142+
143+
## Common Pitfalls
144+
145+
- `Segment` extends `Array` — iterating with `for...of` works but items include `UserDataHeader` entries. Filter with `isReservedChar` to get only user characters.
146+
- `EncodedChar.codeUnits` contains GSM-7 septet values for GSM characters, even in UCS-2 messages. When displaying code units for UCS-2 messages, derive UTF-16 values from `raw.charCodeAt()` instead.
147+
- `EncodedChar.isGSM7` indicates whether a character is in the GSM-7 character set, NOT the message encoding. Use `SegmentedMessage.encodingName` for the actual message encoding.
148+
- The `docs/scripts/` JS bundles are built artifacts from webpack — always run `npm run release` after changing `src/browser/` files.
149+
- `dist/` contains tsc output for the NPM package — also rebuilt by `npm run release`.
150+
- Both `docs/scripts/` and `dist/` should be committed (they are deployed artifacts).

CONTRIBUTING.md

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,80 @@
1-
# Contributing to Twilio
1+
# Contributing to Message Segment Calculator
22

33
All third party contributors acknowledge that any contributions they provide will be made under the same open source license that the open source project is provided under.
4+
5+
## Quick Start
6+
7+
```bash
8+
git clone https://github.com/TwilioDevEd/message-segment-calculator.git
9+
cd message-segment-calculator
10+
npm install
11+
npm run check # Lint + test (mirrors CI)
12+
```
13+
14+
## Development
15+
16+
```bash
17+
npm test # Type-check + jest (659 tests)
18+
npm run lint # ESLint on src/**/*.ts
19+
npm run check # Lint + test (run before pushing)
20+
npm run release # Build library (dist/) + browser bundle (docs/scripts/)
21+
npm run dev # Watch mode for tsc
22+
```
23+
24+
### Local Preview
25+
26+
```bash
27+
npm run release
28+
python3 -m http.server 8080 --directory docs
29+
# Open http://localhost:8080
30+
```
31+
32+
## Project Layout
33+
34+
- `src/libs/` — Core library: SMS/RCS encoding and segmentation logic
35+
- `src/browser/` — Browser UI: analysis, rendering, DOM wiring
36+
- `docs/` — GitHub Pages site (HTML, CSS, built JS bundles)
37+
- `tests/` — Jest test suites
38+
- `dist/` — Built NPM package output (tsc)
39+
40+
See `CLAUDE.md` for detailed architecture documentation.
41+
42+
## Making Changes
43+
44+
1. Create a feature branch: `git checkout -b feat/DEVED-XXXXX-description`
45+
2. Make your changes in `src/`
46+
3. Run `npm run check` to verify lint + tests pass
47+
4. Run `npm run release` to rebuild `dist/` and `docs/scripts/`
48+
5. Commit all changes including built artifacts
49+
6. Push and create a PR against `main`
50+
51+
### Pre-commit Hook
52+
53+
Husky + lint-staged automatically runs `eslint --fix` on staged TypeScript files at commit time. If lint fails, the commit is blocked — fix the issues and try again.
54+
55+
### CI Pipeline
56+
57+
GitHub Actions runs on every PR to `main`:
58+
1. `npm run lint`
59+
2. `npm test`
60+
61+
Across Node.js 14.x, 16.x, 18.x, 19.x. Run `npm run check` locally to catch failures before pushing.
62+
63+
## Code Style
64+
65+
- TypeScript with `eslint-config-twilio-ts` (includes prettier)
66+
- CSS uses design tokens from `docs/styles/tokens.css` — never hard-code hex colors
67+
- Interactive UI elements need accessibility attributes (`tabindex`, `role`, `aria-label`)
68+
69+
## PR Review Process
70+
71+
PRs follow a 3-agent + 1-human review pattern:
72+
73+
| Reviewer | Focus |
74+
|----------|-------|
75+
| Claude Code | Architecture, quality, test coverage |
76+
| Codex | Correctness, security, edge cases |
77+
| GitHub Copilot | Inline suggestions, style |
78+
| Human | Business logic, acceptance criteria |
79+
80+
See `docs/pr-reviews/README.md` for the full process and templates.

dist/browser/main.js

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)