Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ trim_trailing_whitespace = true
indent_style = space
indent_size = 4

[*.cs]
# Keep service APIs instance-based even when a current method has no instance state.
dotnet_diagnostic.CA1822.severity = none
# Prefer interface-shaped collection boundaries over analyzer-suggested concrete types.
dotnet_diagnostic.CA1859.severity = none

[*.md]
end_of_line = lf
trim_trailing_whitespace = false
48 changes: 48 additions & 0 deletions .github/workflows/windows-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Windows build

on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:

permissions:
contents: read

jobs:
verify:
runs-on: windows-latest

steps:
- name: Check out repository
uses: actions/checkout@v4

- name: Set up .NET 10
uses: actions/setup-dotnet@v4
with:
dotnet-version: 10.0.x

- name: Restore
run: dotnet restore .\ColumnPadStudio.sln

- name: Check formatting
run: dotnet format .\ColumnPadStudio.sln --no-restore --verify-no-changes

- name: Build
run: dotnet build .\ColumnPadStudio.sln -c Release --no-restore

- name: Run domain checks
run: dotnet run --project .\tests\ColumnPadStudio.Domain.Tests\ColumnPadStudio.Domain.Tests.csproj -c Release --no-build

- name: Run app smoke checks
run: dotnet run --project .\tests\ColumnPadStudio.SmokeTests\ColumnPadStudio.SmokeTests.csproj -c Release --no-build

- name: Verify single-file publish
shell: pwsh
run: |
dotnet publish .\src\ColumnPadStudio\ColumnPadStudio.csproj -p:PublishProfile=FolderProfile
$files = @(Get-ChildItem .\src\ColumnPadStudio\publish -File)
if ($files.Count -ne 1 -or $files[0].Name -ne 'ColumnPadStudio.exe') {
throw "Expected publish output to contain only ColumnPadStudio.exe."
}
29 changes: 29 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,35 @@ All notable changes to this project are documented in this file.

## [Unreleased]

## [v2.5.0] - 2026-08-07

### Added
- Added saved Standard (320 px), Custom (220-5000 px), and Fit Columns to Window sizing, plus one global Snap control and adjustable spacing.
- Added a saved workspace-wide line-number gutter width from 32-160 px.
- Added theme-aware per-column text colours with presets, custom hexadecimal colours, and layout persistence.
- Added Ruled, Soft Ruled, and Strong Ruled paper styles aligned with the editor and gutter.
- Added an automated Windows build gate and explicit version signatures for saved and exported files.

### Changed
- Replaced Markdown document/export support with concise, readable JSON text exports; native `.columnpad.json` layouts remain the full-fidelity format.
- Embedded picture data in native layouts so saved workspaces remain portable if an original picture is moved or deleted.
- Moved the app, tests, automated build, and one-file release profile to the supported .NET 10 LTS runtime.
- Reworked recovery into complete atomic generations with fallback, and expanded workspace dirty-state tracking to include tab and session changes.
- Simplified Workflow Builder creation, connection editing, save/import/export actions, and automatic node placement while keeping older workflows compatible.

### Fixed
- Fixed column adding and resetting so pixel widths remain stable, horizontal workspace scrolling returns when needed, and long text scrolls inside its own column.
- Made Snap change only the shared gap and made Fit an explicit equal-width mode that preserves saved pixel widths.
- Fixed selection highlighting, keyboard-focus borders, paper alignment, gutter updates, and repeated blank lines during paste.
- Fixed save, exit, session-replacement, and crash-recovery paths so unsaved work and the previous healthy recovery generation are preserved.
- Prevented text and JSON exports from silently discarding pictures or rich column formatting by requiring a native layout save.
- Added stable workflow node IDs and migration for older step-list workflows.
- Quarantined malformed preferences, bounded crash-log growth, and strengthened layout, workflow, image, and recovery validation.

### Tested
- Added coverage for column spacing preferences, text-colour persistence, paper alignment and compatibility, selection contrast, keyboard focus, preference quarantine, transactional recovery, portable pictures, schema validation, migration, and import limits.
- Completed the Release build with no warnings or errors, passed 51 domain checks and 558 app smoke checks, and launch-checked the single-file Windows executable.

## [v2.4.1] - 2026-08-06

### Windows Build
Expand Down
7 changes: 7 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Project>
<PropertyGroup>
<AnalysisLevel>latest-recommended</AnalysisLevel>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
</Project>
85 changes: 51 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,72 +3,89 @@
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
![Platform: Windows](https://img.shields.io/badge/platform-Windows-0078D6)

ColumnPad is a Windows writing app for notes, plans, prompts, checklists, and structured text. It gives each idea a clean, side-by-side column while keeping workspaces local, recoverable, and easy to export.
ColumnPad is a Windows writing app for notes, plans, prompts, checklists, and structured text. It keeps ideas separated in clean side-by-side columns while workspaces remain local, recoverable, and easy to export.

## Project Status

Active development. Current release: **v2.4.1**.
Active development. Current release: **v2.5.0**.

Release notes: [v2.4.1](docs/releases/v2.4.1.md).
Release notes: [v2.5.0](docs/releases/v2.5.0.md).

ColumnPad is a portable Windows desktop app. It does not require an account, cloud storage, or an always-on connection.

## Download and Install

Download the latest `ColumnPadStudio.exe` from the [GitHub Releases page](../../releases/latest), save it in a permanent folder, and run it like a normal Windows application.
Download `ColumnPadStudio.exe` from the [latest GitHub release](../../releases/latest), save it in a permanent folder, and run it like a normal Windows application.

The released executable is self-contained: Visual Studio, Git, and the .NET SDK are not required to use it.
The released executable is self-contained. Visual Studio, Git, and the .NET SDK are not required to use it.

ColumnPad is not code-signed yet. Windows SmartScreen may warn the first time it is opened; download releases only from this repository.
ColumnPad is not code-signed yet, so Windows SmartScreen may warn the first time it is opened. Download releases only from this repository.

## Screenshot

![ColumnPad desktop interface](docs/columnpad-screenshot.png)

The screenshot reflects the current three-column writing surface and contains no personal or sample document data.
The screenshot shows the current three-column writing surface with clean sample content and no personal data.

## Main Features

- Side-by-side writing columns with resize controls and workspace tabs.
- Single-text and column modes for different drafting styles.
- Plain-text, Markdown, native layout, and workspace-session open, save, and export flows.
- Standard 320 px, saved Custom 220-5000 px, and explicit Fit Columns to Window sizing.
- Stable fixed-width columns with automatic main-window left/right scrolling as more columns are added.
- One global Snap All Columns Together setting with an adjustable gap that does not resize columns.
- Per-column resizing, freeze/unfreeze, reset-to-default actions, and independent vertical scrolling for long text.
- Workspace-wide adjustable line-number gutter width from 32-160 px.
- Workspace tabs plus Single Text Mode and Column Mode.
- Plain `.txt`, concise readable `.json`, full-fidelity `.columnpad.json`, and multi-workspace session files.
- Auto-recovery, crash logging, and save-before-exit safeguards.
- Line numbers, word wrap, spell checking, proofing-language selection, lined-paper mode, and paste helpers for bullets and checklists.
- Line numbers, word wrap, spell checking, proofing-language selection, and paste helpers for bullets and checklists.
- Ruled, Soft Ruled, and Strong Ruled paper styles aligned with the editor and gutter.
- Light, dark, and default themes with saved preferences.
- In-column pictures with drag-and-drop placement, proportional resizing, and text layering.
- Workflow Builder templates, node colours, workflow JSON import/export, and readable text or Markdown workflow exports.
- A quiet, best-effort check for a newer stable GitHub release at startup.
- Theme-aware per-column text-colour presets and custom colours.
- In-column pictures with drag-and-drop placement, proportional resizing, text layering, and portable native-layout storage.
- Workflow Builder templates, node colours, connection editing, workflow JSON import/export, and readable text exports.
- A quiet, best-effort check for newer stable GitHub releases at startup.

## Supported Platforms and Technology

- Windows 10 or Windows 11, x64.
- C#, .NET 8, and WPF.
- C#, .NET 10 LTS, and WPF.
- Self-contained, single-file Windows publishing for releases.

## Privacy and Configuration
## Privacy and Local Storage

No account, API key, server, or project-level configuration is required.

ColumnPad keeps preferences, recovery data, workflow-library data, imported image copies, and crash logs in app-managed local application storage. Native layouts retain references to imported images rather than embedding image data, so keep the image copies with a layout when moving it to another computer.
ColumnPad keeps preferences, recovery data, saved workflows, imported image copies, and crash logs in app-managed local application storage. Native layouts embed bounded image data so a saved workspace remains portable if the original imported file is moved or deleted.

At startup, ColumnPad may make a brief request to the public GitHub releases endpoint to check for a newer stable version. The check never blocks writing or startup and does not send document content.
At startup, ColumnPad may make a brief request to the public GitHub releases endpoint to check for a newer stable version. The check never sends document content and never blocks writing or startup.

## Using ColumnPad

1. Create columns or a workspace tab for each topic you want to keep separate.
2. Write directly, use the View and Columns menus to adjust the editing surface, and use the editor menus for search, paste, and checklist actions.
3. Use File commands to open, save, export, or restore text, Markdown, native layouts, and workspace sessions.
4. Open the Workflow Builder from the Workflows menu to start from a template or import a workflow.
1. Create columns or workspace tabs for the topics you want to keep separate.
2. Use **Columns > Column Width** to choose Standard, Custom, or Fit Columns to Window sizing.
3. Use each column's **Actions** menu for rename, move, resize, reset, formatting, pictures, and other column-specific actions. Right-clicking a column header is reserved for renaming.
4. Use the **View** menu to adjust gutters, paper style, themes, wrapping, proofing, and Single Text or Column Mode.
5. Use **File** commands to open, save, export, restore, or print text, JSON, native layouts, and workspace sessions.
6. Open **Workflows** to create, import, edit, and save reusable workflow diagrams.

## File Formats

- `.txt` stores normal text documents and readable multi-column text exports.
- `.json` stores concise readable column text exports.
- `.columnpad.json` stores full layouts, including columns, formatting, settings, and embedded pictures.
- `.workflow.json` stores editable Workflow Builder diagrams.

Markdown document and export support has been retired. Existing Markdown files remain readable in ordinary text editors but are not presented as a ColumnPad file type.

## Building from Source

Developer requirements:

- Windows 10 or Windows 11.
- .NET 8 SDK or a newer SDK that can build `net8.0-windows`.
- .NET 10 SDK.
- Optional: Visual Studio with the .NET Desktop Development workload.

Clone the repository and build:
Clone and build:

```powershell
git clone <repository-url>
Expand All @@ -77,7 +94,7 @@ dotnet restore
dotnet build .\ColumnPadStudio.sln -c Release
```

Run the app from source:
Run from source:

```powershell
dotnet run --project .\src\ColumnPadStudio\ColumnPadStudio.csproj -c Release
Expand All @@ -89,7 +106,7 @@ Publish the portable single-file executable:
dotnet publish .\src\ColumnPadStudio\ColumnPadStudio.csproj -p:PublishProfile=FolderProfile
```

The publish output is `src\ColumnPadStudio\publish\ColumnPadStudio.exe`.
The release output is `src\ColumnPadStudio\publish\ColumnPadStudio.exe` with no loose runtime files beside it.

## Testing

Expand All @@ -100,29 +117,29 @@ dotnet run --project .\tests\ColumnPadStudio.Domain.Tests\ColumnPadStudio.Domain
dotnet run --project .\tests\ColumnPadStudio.SmokeTests\ColumnPadStudio.SmokeTests.csproj -c Release --no-build
```

Before publishing, also follow [RELEASE_CHECKLIST.md](RELEASE_CHECKLIST.md) and the visual checks in [docs/UI_QA_CHECKLIST.md](docs/UI_QA_CHECKLIST.md).
Before publishing, also follow [RELEASE_CHECKLIST.md](RELEASE_CHECKLIST.md) and [docs/UI_QA_CHECKLIST.md](docs/UI_QA_CHECKLIST.md).

## Project Structure

```text
src/ColumnPadStudio/ WPF app shell, controls, services, resources, and workflows
src/ColumnPadStudio.Domain/ Pure text, list, and workspace rules
src/ColumnPadStudio.Domain/ Reusable text, list, and workspace rules
tests/ Domain and app-level smoke checks
docs/ Release notes, architecture notes, workflows, screenshots, and QA guidance
tools/ Maintenance and asset-generation helpers
tools/ Maintenance helpers
```

For a detailed guide, see [docs/REPOSITORY_STRUCTURE.md](docs/REPOSITORY_STRUCTURE.md). Larger changes should follow [docs/APP_BUILDING_STANDARD.md](docs/APP_BUILDING_STANDARD.md).
See [docs/REPOSITORY_STRUCTURE.md](docs/REPOSITORY_STRUCTURE.md) for more detail. Larger changes should follow [docs/APP_BUILDING_STANDARD.md](docs/APP_BUILDING_STANDARD.md).

## Known Limitations

- The portable executable is currently unsigned and has no installer, automatic update, or uninstall flow.
- The app is Windows-only.
- Imported images remain local files referenced by native layouts; moving a layout alone does not package its images.
- The portable executable is unsigned and may trigger a SmartScreen warning.
- ColumnPad is Windows-only and currently has no installer or uninstall entry.
- Update checks notify the user but do not install updates automatically.

## Contributing

Keep changes focused, preserve local-data and secret exclusions, update relevant documentation, and run the Release build plus both test suites before opening a pull request. Add or refresh screenshots only when the visible interface has meaningfully changed.
Keep changes focused, preserve local-data and secret exclusions, update relevant documentation, and run the Release build plus both test suites before opening a pull request. Refresh screenshots only when the visible interface has meaningfully changed.

## License

Expand Down
25 changes: 18 additions & 7 deletions RELEASE_CHECKLIST.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ dotnet build .\ColumnPadStudio.sln -c Release
```

Expected result:
- `0 Warning(s)`
- `0 Error(s)`

## 3. Run domain tests
Expand Down Expand Up @@ -49,20 +50,30 @@ Expected output:
- `src\ColumnPadStudio\publish\ColumnPadStudio.exe`
- No `.pdb`, `.dll`, `.json`, or loose runtime files should remain beside the EXE for the public release asset.

Note: the publish profile pins the self-contained runtime pack to the cached .NET 8 patch version used for release builds. If this version is changed, restore the matching `win-x64` runtime packs before publishing.
The solution targets .NET 10 LTS. The self-contained publish resolves the latest available .NET 10 patch so the public EXE carries current runtime fixes.

## 6. Manual UI sanity checks
Run the fuller UI checklist in `docs\UI_QA_CHECKLIST.md` and check the app-building standard in `docs\APP_BUILDING_STANDARD.md`, then at minimum confirm:

1. Launch `ColumnPadStudio.exe`.
2. Open a saved layout or text document.
3. Confirm the selected theme still persists after closing and reopening the app.
4. Add/remove columns and verify scroll behavior still works.
5. Switch between single text mode and column mode.
6. Open the Workflow Builder and confirm preview/editing still works.
7. Save and reopen a `.columnpad.json` layout.
8. Verify recovery prompt wording is sensible if recovery data exists.
9. Right-click a column header, editor, line gutter, workspace tab, and workflow node; hover nested menu items and confirm hover colour plus text contrast are readable in light, dark, and default themes.
4. Under Columns > Column Width, select Standard and confirm new columns open at 320 px without shrinking existing columns.
5. Select Custom, enter a value from 220-5000 px, add another column, and confirm the new column uses that default while individually resized columns keep their widths.
6. Add enough fixed-width columns to exceed the window and confirm the bottom scrollbar moves the main workspace left and right.
7. Select Fit Columns to Window and confirm columns share the available width equally; switch back to Standard or Custom and confirm saved pixel widths return.
8. Freeze a resized column, then use Reset Selected and Reset All; confirm the affected columns return to the current default width and become unlocked.
9. Turn Snap All Columns Together on and off; confirm only the global gap changes and no column width changes.
10. Change the column gap and confirm existing plus newly added snapped columns follow the setting without shrinking.
11. Paste enough text into one column to overflow it and confirm only that column receives its own vertical scrollbar.
12. Apply per-column text colours and confirm they survive theme changes and layout reload.
13. Change the font size and confirm Ruled, Soft Ruled, and Strong Ruled paper stay aligned with text rows in every theme.
14. Select text, move focus, and confirm active/inactive selection plus keyboard-focus borders remain readable in every theme.
15. Switch between single text mode and column mode.
16. Open the Workflow Builder and confirm preview/editing still works.
17. Save and reopen a `.columnpad.json` layout with pictures and column formatting after moving the original picture file.
18. Verify recovery prompt wording is sensible if recovery data exists.
19. Right-click a column header, editor, line gutter, workspace tab, and workflow node; hover nested menu items and confirm hover colour plus text contrast are readable in light, dark, and default themes.

## 7. Release metadata
1. Update `CHANGELOG.md`.
Expand Down
Loading
Loading