Skip to content

Commit 4058143

Browse files
basiclinesCopilot
andcommitted
Add dependabot config, issue/PR templates, and license section in README
Address OSPO readiness scanner findings: - Add .github/dependabot.yml for npm and GitHub Actions - Add bug report and feature request issue templates - Add pull request template - Add License section to README Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 2435347 commit 4058143

5 files changed

Lines changed: 85 additions & 302 deletions

File tree

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Bug report
2+
description: Report a problem with TUIKit
3+
labels: ["bug"]
4+
body:
5+
- type: textarea
6+
attributes:
7+
label: Describe the bug
8+
description: A clear description of what the bug is.
9+
validations:
10+
required: true
11+
- type: textarea
12+
attributes:
13+
label: Steps to reproduce
14+
description: Steps to reproduce the behavior.
15+
placeholder: |
16+
1. Run command ...
17+
2. See error ...
18+
validations:
19+
required: true
20+
- type: textarea
21+
attributes:
22+
label: Expected behavior
23+
description: What you expected to happen.
24+
validations:
25+
required: true
26+
- type: input
27+
attributes:
28+
label: TUIKit version or commit
29+
description: Which version or commit SHA are you using?
30+
validations:
31+
required: false
32+
- type: textarea
33+
attributes:
34+
label: Additional context
35+
description: Any other context, screenshots, or logs.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: Feature request
2+
description: Suggest an idea for TUIKit
3+
labels: ["enhancement"]
4+
body:
5+
- type: textarea
6+
attributes:
7+
label: Describe the feature
8+
description: A clear description of what you would like to happen.
9+
validations:
10+
required: true
11+
- type: textarea
12+
attributes:
13+
label: Use case
14+
description: What problem does this solve? Why is this needed?
15+
validations:
16+
required: true
17+
- type: textarea
18+
attributes:
19+
label: Alternatives considered
20+
description: Any alternative solutions or features you have considered.
21+
validations:
22+
required: false

.github/dependabot.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "npm"
4+
directory: "/"
5+
schedule:
6+
interval: "weekly"
7+
- package-ecosystem: "github-actions"
8+
directory: "/"
9+
schedule:
10+
interval: "weekly"

.github/pull_request_template.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
## Summary
2+
3+
<!-- Brief description of what this PR does -->
4+
5+
## Changes
6+
7+
<!-- List the key changes -->
8+
9+
## Testing
10+
11+
<!-- How was this tested? -->
12+
13+
## Checklist
14+
15+
- [ ] Specs lint passes (`bun run lint`)
16+
- [ ] Tests updated if applicable
17+
- [ ] Documentation updated if applicable

README.md

Lines changed: 1 addition & 302 deletions
Original file line numberDiff line numberDiff line change
@@ -1,302 +1 @@
1-
# TUIkit Specs
2-
3-
A spec-driven system for building UI components across programming languages.
4-
Each component is defined as a language-agnostic markdown spec with behavioral
5-
tests. An LLM agent acts as the "compiler" — reading specs and generating
6-
idiomatic implementations per target framework.
7-
8-
## How it works
9-
10-
```mermaid
11-
flowchart LR
12-
Specs["Spec files\n(.md)"] --> Compile["compile.ts\n(prompt)"]
13-
Compile --> Agent["LLM Agent\n(compiler)"]
14-
Agent --> Dist["dist/{target}/\n(generated code)"]
15-
Agent --> Lock["lock file\n(.json)"]
16-
```
17-
18-
1. **Specs** define behavior + semantic tokens (like headless UI libraries)
19-
2. **Target specs** define how to translate to a specific language/framework
20-
3. **compile.ts** detects changed specs and generates a self-contained prompt
21-
4. An **LLM agent** reads the prompt and generates idiomatic code
22-
5. Generated code goes to **dist/** — specs stay clean
23-
6. **Lock files** track which spec versions have been compiled
24-
25-
## Quick start
26-
27-
### Prerequisites
28-
29-
- [Bun](https://bun.sh/) 1.1+ installed (`bun --version`)
30-
31-
### Install dependencies
32-
33-
```bash
34-
bun install
35-
```
36-
37-
### Common commands
38-
39-
```bash
40-
# Lint all specs against the schema
41-
bun run lint
42-
43-
# Check what needs compiling
44-
bun run compile status
45-
46-
# Generate a prompt for a target
47-
bun run compile prompt --target go
48-
49-
# The prompt is written to dist/go/_compile-prompt.md
50-
# Feed it to an LLM agent (e.g. Copilot CLI, Claude, etc.)
51-
# The agent writes generated code to dist/go/
52-
53-
# After verifying the generated code works, lock the hashes
54-
bun run compile lock --target go
55-
```
56-
57-
## Repository structure
58-
59-
```
60-
TUIKit/
61-
components/ Component specs, tests, and preview definitions
62-
tokens/ Semantic design tokens (colors, icons, breakpoints)
63-
targets/ Target language/framework definitions
64-
docs/ Meta-schema and design foundations
65-
scripts/ Compiler and linter CLIs
66-
dist/ Compiled output per target (gitignored)
67-
```
68-
69-
## Writing specs
70-
71-
### Component spec
72-
73-
Each component is a markdown file with YAML frontmatter and prose body:
74-
75-
````yaml
76-
---
77-
kind: component
78-
name: MyComponent
79-
description: One-line summary.
80-
version: 1
81-
category: input # input | display | navigation | layout | feedback
82-
83-
tokens:
84-
colors: [textPrimary, selected]
85-
icons: [iconPrompt]
86-
87-
props:
88-
label:
89-
type: string
90-
required: true
91-
description: Display text.
92-
93-
dependencies:
94-
tokens:
95-
- name: textPrimary
96-
kind: color
97-
usage: "Label text"
98-
required: true
99-
components: []
100-
101-
accessibility:
102-
role: button
103-
announce:
104-
on_mount: "Button: {label}"
105-
---
106-
107-
## Visual rules
108-
109-
- Label text MUST use the `textPrimary` color token
110-
- Active state MUST use the `selected` color token
111-
112-
## Rendering example
113-
114-
Given label: "Click me"
115-
116-
​```
117-
Click me
118-
​```
119-
120-
## Dependencies
121-
122-
| Dependency | Kind | Usage | Required |
123-
|------------|------|-------|----------|
124-
| `textPrimary` | color | Label text | Yes |
125-
| `selected` | color | Active state | Yes |
126-
````
127-
128-
### Test spec
129-
130-
Test specs live alongside component specs and use a block-based format:
131-
132-
```markdown
133-
---
134-
kind: test
135-
component: MyComponent
136-
version: 1
137-
---
138-
139-
## renders label text
140-
141-
​`props
142-
label: "Hello"
143-
​`
144-
145-
​`expect
146-
Hello
147-
​`
148-
```
149-
150-
See `docs/schema.md` for the full format reference, including `input`, `state`,
151-
`style`, and `accessibility` test blocks.
152-
153-
### Conformance language
154-
155-
All normative sections (Visual rules, Behavior, Edge cases) use
156-
[RFC 2119](https://datatracker.ietf.org/doc/html/rfc2119) keywords:
157-
158-
- **MUST** — absolute requirement
159-
- **SHOULD** — strong recommendation
160-
- **MAY** — optional behavior
161-
- **MUST NOT** — absolute prohibition
162-
163-
## Compiling to a target
164-
165-
### Available targets
166-
167-
| Target | Language | Framework | File |
168-
| -------- | ---------- | ---------------------- | ------------------- |
169-
| `go` | Go | Bubbletea + Lipgloss | `targets/go.md` |
170-
| `node` | TypeScript | Ink + React (Node.js) | `targets/node.md` |
171-
| `bun` | TypeScript | OpenTUI + React (Bun) | `targets/bun.md` |
172-
| `rust` | Rust | Ratatui + Crossterm | `targets/rust.md` |
173-
174-
### Workflow
175-
176-
```bash
177-
# 1. See what's changed
178-
bun run compile status
179-
180-
# 2. Generate the compilation prompt
181-
bun run compile prompt --target go
182-
183-
# 3. Feed dist/go/_compile-prompt.md to an LLM agent
184-
# The agent generates code into dist/go/
185-
186-
# 4. Verify: run tests, check the demo CLI
187-
cd dist/go && go test ./... && go run ./cmd/demo
188-
189-
# 5. Lock the hashes
190-
bun run compile lock --target go
191-
```
192-
193-
### Multi-pass compilation
194-
195-
A single compilation pass across the full component suite (17 components +
196-
tokens + demo) is usually not enough to reach production quality. We've found
197-
that **2–3 passes** produce notably better results:
198-
199-
| Pass | Focus | Typical outcome |
200-
| ---- | ----- | --------------- |
201-
| **1st** | Initial generation | All components scaffold correctly, most tests pass, demo wires up. Expect rough edges — missing edge cases, incomplete keybindings, demo wiring bugs. |
202-
| **2nd** | Review & fix | Agent reviews its own output against specs, fixes test failures, fills in missing behavior, improves demo interactivity. Test count typically grows 30–50%. |
203-
| **3rd** | Polish | Catches subtle spec violations, improves accessibility, hardens demo `--snapshot` smoke tests. Diminishing returns after this point. |
204-
205-
To run a follow-up pass, generate a new prompt and tell the agent to review
206-
and complete its existing work:
207-
208-
```bash
209-
# Generate a fresh prompt (it sees the current dist/ state)
210-
bun run compile prompt --target go
211-
212-
# Feed to the agent with instructions like:
213-
# "Review your existing implementation against the specs.
214-
# Fix any test failures, fill in missing behavior,
215-
# and ensure all --snapshot smoke tests pass."
216-
```
217-
218-
Each pass is fast because the agent builds on its own prior output rather than
219-
starting from scratch. The demo's `--list` and `--snapshot` flags make it easy
220-
for the agent to self-verify between passes.
221-
222-
### Custom output directory
223-
224-
By default, compiled code goes to `dist/`. Override with `--out`:
225-
226-
```bash
227-
# Output to a separate repo or directory
228-
bun run compile prompt --target go --out ~/my-tuikit-go
229-
230-
# The prompt and generated code go to ~/my-tuikit-go/go/
231-
```
232-
233-
### Adding a new target
234-
235-
1. Create `targets/{name}.md` following the target spec format in `docs/schema.md`
236-
2. Define: architecture pattern, type mapping, callback translation, state
237-
machine pattern, token access, styling, composition, test pattern, key
238-
mapping, dependencies, and demo CLI
239-
3. Run `bun run compile status` — your target will show up with all specs dirty
240-
4. Run `bun run compile prompt --target {name}` and compile
241-
242-
## Linting
243-
244-
```bash
245-
# Lint all specs
246-
bun run lint
247-
248-
# Lint a single component
249-
bun run lint --component Select
250-
251-
# Show fix suggestions
252-
bun run lint --fix
253-
254-
# See all rules
255-
bun run lint --help
256-
```
257-
258-
The linter checks:
259-
260-
- Required frontmatter fields and valid values (zod schemas)
261-
- Naming conventions (PascalCase components, camelCase props)
262-
- RFC 2119 keyword usage in normative sections
263-
- ARIA accessibility structure for interactive components
264-
- Token cross-references resolve to known tokens
265-
- Required body sections (Visual rules, Rendering example, Dependencies)
266-
- Test specs reference existing components
267-
- Broken internal markdown links
268-
269-
Rule definitions live in `scripts/lint-rules.ts` — edit that file to add or
270-
change rules, severities, and fix hints.
271-
272-
## CI checks
273-
274-
The GitHub Actions workflow (`.github/workflows/specs-ci.yml`) runs on every PR:
275-
276-
1. **Spec lint**`bun run lint`
277-
2. **Compiler health**`bun run compile status` for each target
278-
3. **Prompt smoke test**`bun run compile prompt` for each target
279-
4. **No generated output committed** — ensures `dist/` is not tracked
280-
5. **Changed-spec completeness** — if `{Name}.md` changes, matching `.test.md` and `.preview.md` must also change
281-
282-
## Design principles
283-
284-
- **Specs capture intent, not implementation**~95% behavioral intent vs.
285-
~5% framework hints. This lets agents generate idiomatic code per framework
286-
rather than awkward transliterations.
287-
288-
- **Color tokens define meaning, not color values** — tokens like `textPrimary`
289-
and `selected` define UI roles. The color engine (Rampa, hardcoded hex,
290-
ANSI palette) is an implementation detail per target.
291-
292-
- **Layout is out of scope** — specs define behavior and semantic tokens.
293-
Spacing, padding, and spatial polish are per-target decisions (similar to
294-
headless UI libraries like Radix or Base UI).
295-
296-
- **Lock files enable incremental compilation** — only dirty specs trigger
297-
regeneration. Schema changes invalidate everything. Lock files are gitignored;
298-
a fresh clone starts with everything dirty.
299-
300-
For TUI design foundations — color systems, typography, iconography, layout
301-
grids, accessibility patterns, keybinding conventions, and buffer management —
302-
see [`docs/foundations.md`](docs/foundations.md).
1+
@-

0 commit comments

Comments
 (0)