Commit graph

47 commits

Author SHA1 Message Date
Thorsten Bus 5ac27d676c docs: prepare project for open-source release on GitHub
- Add MIT LICENSE (Thorsten Buss) with attribution to the upstream
  MIT-licensed greyshirtguy/ProPresenter7-Proto definitions.
- Add comprehensive README.md: badges, feature matrix, install,
  seven runnable getting-started examples (read/modify/generate
  songs, playlists, bundles, global libraries), CLI tool reference,
  documentation index, project structure, caveats.
- Update composer.json with package name (bussnet/propresenter7-php-api),
  MIT license, keywords, author, homepage, support URLs, dev autoload,
  and a `composer test` script.
- Polish doc/INDEX.md, doc/keywords.md, and doc/CONTRIBUTING.md so they
  read well for both humans and AI assistants; remove README-duplicate
  content from INDEX.md and link to the top-level README instead.
- Expand .gitignore to cover IDE/OS metadata and agent workspaces.

All 370 tests still pass (9,200 assertions). README examples #3 and #5
verified end-to-end (generate -> read back -> assert metadata).
2026-05-03 21:59:39 +02:00
Thorsten Bus 9e3e719806 feat(library): add readers + writers for all ProPresenter global libraries and theme bundles
Add full IO support for every global ProPresenter library file plus
theme folders, and extend the existing Labels/Macros readers with
exporters and editable accessors so every supported document is now a
round-trippable, mutable object.

New library readers/writers (each: FileReader, FileWriter, Library
wrapper, element wrapper where applicable, CLI tool, tests, doc/api/*.md):

- Groups          (ProGroupsDocument)        + GroupDefinition
- ClearGroups     (ClearGroupsDocument)      + ClearGroupDefinition
- CCLI            (CCLIDocument)
- Messages        (MessageDocument)          + Message
- Timers          (TimersDocument + Clock)   + Timer
- Stage           (Stage.Document)           + StageLayout
- Workspace       (ProPresenterWorkspace)    + Screen
- Props           (PropDocument)             + Prop
- TestPatterns    (TestPatternDocument)
- Calendar        (new CalendarDocument)     + CalendarEvent
- KeyMappings     (new KeyMappingsDocument)  + KeyMapping
- CommunicationDevices (JSON file)           + CommunicationDevice
- Theme bundles   (Template.Document folder + Assets/) + ThemeBundle/Slide/Asset

Extensions to existing modules:

- LabelsFileWriter; Label and LabelLibrary gain setters, addLabel,
  removeLabel, setColor / setColorHex helpers
- MacrosFileWriter; Macro/MacroCollection/MacroLibrary gain UUID, name,
  color, image_type, image_data, trigger_on_startup setters plus
  add/remove for macros and collections

Two new minimal proto schemas were defined for documents that lacked
upstream definitions:

- proto/calendar.proto   - CalendarDocument with Event entries, raw
  bytes for the action/macro sub-messages so the schema can evolve
- proto/keyMappings.proto - KeyMappingsDocument with ApplicationInfo
  and a forward-looking Mapping message (sample only carries the info)

The Theme file turned out to be a regular Rv\Data\Template\Document, so
no new proto was required for theme content; ThemeBundle layers folder
+ Assets/ handling on top in the same spirit as PresentationBundle.

GroupDefinition is intentionally distinct from the existing Group class
(which wraps song-level CueGroup) to avoid breaking song APIs.

Verified with the full PHPUnit suite: 370 tests, 9200 assertions, all
green; LSP diagnostics clean across src/. The unmodified reference
samples for Labels, Groups, ClearGroups, TestPatterns, Calendar and
KeyMappings round-trip byte-for-byte; the others round-trip with the
same byte length (PHP protobuf is not canonically deterministic but
re-write-after-write stabilises).

doc/INDEX.md, doc/keywords.md and AGENTS.md updated so every new module
is discoverable from the top level.
2026-05-03 21:40:09 +02:00
Thorsten Bus 4e1ac9b7ea feat(labels): add reader for global Labels file
Mirrors the Macros reader: LabelsFileReader -> LabelLibrary -> Label wraps
the protobuf ProLabelsDocument and exposes each label's name (the proto
'text' field) plus optional RGBA color with a #RRGGBB hex helper. Includes
CLI tool, PHPUnit suite against the bundled reference Labels sample, and
api/labels.md docs.
2026-05-03 20:53:45 +02:00
Thorsten Bus b30918af41 feat(macros): add reader for global Macros file
Importer for ProPresenter's protobuf-encoded `Macros` document. Exposes
each macro's UUID and name plus the collections that group them.

- src/MacroLibrary.php: top-level wrapper indexed by UUID and name
- src/Macro.php, src/MacroCollection.php: per-entry wrappers
- src/MacrosFileReader.php: file -> MacroLibrary entry point
- bin/parse-macros.php: CLI listing macros and collections
- tests/MacrosFileReaderTest.php: 10 tests against reference sample
- doc/api/macros.md: API reference, plus INDEX/keywords updates
2026-05-03 20:38:47 +02:00
Thorsten Bus 22ba4aff7d refactor: make repo Composer-compatible by moving php/ to root and ref/ to doc/reference_samples
- Move src/, tests/, bin/, generated/, proto/, composer.json, composer.lock, phpunit.xml from php/ to repo root
- Move ref/ to doc/reference_samples/ for better organization
- Remove vendor/ from git tracking (now properly gitignored)
- Update all test file paths (dirname adjustments and ref/ -> doc/reference_samples/)
- Update all documentation paths (AGENTS.md, doc/*.md)
- Remove php.bak/ directory
- All 252 tests pass
2026-03-30 13:26:29 +02:00
Thorsten Bus 8dbcc1bafc feat(bundle): use ROOT_CURRENT_RESOURCE for portable flat media bundles
BREAKING: Bundle media entries are now flat filenames (no directories).
ProBundleWriter flattens all media paths to basename() automatically.
ProFileGenerator supports bundleRelative flag for ROOT_CURRENT_RESOURCE
URLs, enabling bundles that work on any machine without absolute paths.
2026-03-30 10:21:54 +02:00
Thorsten Bus 95a2b6984e remove and ignore files 2026-03-30 09:23:17 +02:00
Thorsten Bus af17f7eb3d add ref data for probundle 2026-03-30 09:21:49 +02:00
Thorsten Bus 22ebe5fd25 docs(bundle): add .probundle format spec and API documentation 2026-03-30 09:20:00 +02:00
Thorsten Bus deabfe4ffb feat(bundle): add .probundle reader, writer, and wrapper for presentation bundles
ProPresenter .probundle files are ZIP archives containing a single .pro
presentation with embedded media assets. This adds read/write support
verified against actual ProPresenter 7 exports.

- PresentationBundle: wrapper class (Song + media files + .pro filename)
- ProBundleReader: reads .probundle ZIPs, applies Zip64Fixer for PP exports
- ProBundleWriter: writes standard ZIP with media-first entry order
- ProFileGenerator: media URLs now include URL.local with LocalRelativePath
- 9 tests covering error handling, round-trip, PP export compat, ZIP format
- ref/TestBild.probundle: verified importable by ProPresenter 7
2026-03-30 08:58:48 +02:00
Thorsten Bus 9db2702b5f test(generator): end-to-end structural verification against ProPresenter format 2026-03-30 08:17:00 +02:00
Thorsten Bus 82a9673874 fix(generator): complete media action with name, audio, and image properties 2026-03-30 08:12:48 +02:00
Thorsten Bus 7cda7e7736 fix(generator): ROOT_USER_HOME fallback for user directory paths
- Add else branch in buildLocalRelativePath() to handle unmapped /Users/{username}/ paths
- Unmapped user directories now use ROOT_USER_HOME as root instead of ROOT_BOOT_VOLUME
- Extract user-relative path (e.g., AI/propresenter/ref/Media/test.png) for unmapped dirs
- Preserve existing behavior for mapped directories (Downloads, Documents, etc.)
- Preserve behavior for non-user paths (e.g., /tmp)
- Add 3 test cases covering all path scenarios: mapped, unmapped user, non-user
2026-03-30 08:06:43 +02:00
Thorsten Bus 6f79982283 fix(generator): add hotKey to Group and Cue 2026-03-30 08:04:32 +02:00
Thorsten Bus e46e7e5f9c fix(generator): set slide size and PresentationSlide chordChart 2026-03-30 08:04:07 +02:00
Thorsten Bus e2cebe419c fix(generator): add presentation-level fields (background, chordChart, ccli, timeline) 2026-03-30 08:03:28 +02:00
Thorsten Bus 1f17121b24 fix(generator): separate platform and application version info 2026-03-30 08:02:59 +02:00
Thorsten Bus 1f14724603 fix(generator): uppercase UUIDs to match ProPresenter format 2026-03-30 08:00:17 +02:00
Thorsten Bus 0de35a9e95 Merge branch 'propresenter-parser' 2026-03-29 18:03:59 +02:00
Thorsten Bus a63758dda8 restructure api stuff to doc and add refs 2026-03-29 18:03:52 +02:00
Thorsten Bus da1cb79603 Merge branch 'propresenter-parser' 2026-03-29 18:02:39 +02:00
Thorsten Bus b5fe0bcd64 ignore stuff 2026-03-29 18:02:36 +02:00
Thorsten Bus 0d27c0221e fix(test): use semantic comparison in BinaryFidelityTest
Replace byte-identical round-trip assertion with JSON-decoded semantic
comparison. Protobuf serialization does not guarantee byte-level
ordering, so the previous test failed on all 169 fixtures despite
data being functionally identical.
2026-03-02 23:01:36 +01:00
Thorsten Bus 2fefe72ef6 feat(pro): correct translated textbox positioning
- Create buildOriginalBounds(): origin(150, 99.543) size(1620×182.946)
- Create buildTranslationBounds(): origin(150, 303.166) size(1620×113.889)
- Modify buildCue() to use different bounds for translated vs non-translated
- Modify buildSlideElement() to accept optional bounds parameter
- Add test: translated slide has correct dual bounds
- Add test: non-translated slide has single full-size bounds
- All tests pass: 14 PHPUnit, 203 Laravel tests
2026-03-02 21:46:37 +01:00
Thorsten Bus 7de43f4aec feat(pro): auto-select 'normal' arrangement in generator
- Modified generate() method to loop through arrangements and find 'normal' (case-insensitive)
- Falls back to first arrangement if 'normal' not found
- Added test: testGenerateSelectsNormalArrangementWhenPresent
- Added test: testGenerateFallsBackToFirstArrangementWhenNoNormal
- All 12 ProFileGenerator tests pass (82 assertions)
2026-03-02 21:41:15 +01:00
Thorsten Bus e7c014abfe refactor(pro): set visual attributes to enable=false 2026-03-02 21:24:03 +01:00
Thorsten Bus 02b080a75d docs(notepad): record 100% completion of all 87 checkboxes 2026-03-01 21:52:05 +01:00
Thorsten Bus 2bf1eff12d chore(plan): mark all 58 acceptance criteria as complete
All acceptance criteria verified and marked complete:
- Task 1-13: Implementation acceptance criteria (all verified)
- Definition of Done: All 5 criteria met
- Final Verification: All 4 phases approved
- Final Checklist: All 7 items complete

Total: 87/87 checkboxes complete (29 main tasks + 58 acceptance criteria)
2026-03-01 21:51:52 +01:00
Thorsten Bus 157740c072 docs(playlist): add project completion summary and evidence files
- Record final project status in learnings.md
- Add all task evidence files (43 files)
- Add work plan with all 29 checkboxes complete
- Add boulder state tracking

Project complete: 99 tests passing, all deliverables verified
2026-03-01 21:49:06 +01:00
Thorsten Bus 813d30dd12 test(playlist): add integration tests and update AGENTS.md
- Add ProPlaylistIntegrationTest with 8 round-trip tests
- All 4 .proplaylist test files validated in ProPlaylistReaderTest
- Update AGENTS.md with playlist module documentation
- Document reading, writing, generating, CLI usage
- Add notepad learnings from Wave 4 tasks
2026-03-01 21:28:18 +01:00
Thorsten Bus d689a3076e feat(playlist): add parse-playlist.php CLI tool
- Create executable CLI tool following parse-song.php pattern
- Display playlist metadata, entries, embedded files
- Type-specific entry formatting: [H] header, [P] presentation, [-] placeholder, [C] cue
- Plain text output (no colors/ANSI codes)
- Error handling with user-friendly messages
- Verified with TestPlaylist.proplaylist (7 entries, 2 .pro files, 1 media file)

Task 10 of proplaylist-module plan complete
Wave 3 complete (Tasks 7-10)
2026-03-01 21:19:14 +01:00
Thorsten Bus d44e67186d feat(playlist): add ProPlaylistGenerator
- Implement ProPlaylistGenerator following ProFileGenerator pattern
- Static generate() + generateAndWrite() methods
- Support header, presentation, placeholder item types
- Build nested protobuf: PlaylistDocument → root → child → items
- Helper methods: buildApplicationInfo, newUuid, colorFromArray
- Default music key (MUSIC_KEY_C) for presentations
- 9 tests, 35 assertions — all pass
- Verified with mixed item generation

Task 9 of proplaylist-module plan complete
2026-03-01 21:16:27 +01:00
Thorsten Bus 66588c6eaf feat(playlist): add ProPlaylistWriter
- Implement ProPlaylistWriter::write() following ProFileWriter pattern
- ZIP creation with ZipArchive::CM_STORE (no compression)
- Proper temp file cleanup in finally block
- Directory validation matching ProFileWriter style
- 8 tests, 27 assertions — all pass
- Round-trip verification with ProPlaylistReader
- Verified with unzip -l (clean, standard-compliant ZIP)

Task 8 of proplaylist-module plan complete
2026-03-01 21:10:18 +01:00
Thorsten Bus 86b4e74577 feat(playlist): add ProPlaylistReader
- Implement ProPlaylistReader::read() following ProFileReader pattern
- ZIP handling: fix headers with Zip64Fixer, extract data + embedded files
- Comprehensive error handling: missing file, empty file, invalid ZIP, missing data entry
- Temp file cleanup in finally block (no leaks on error paths)
- 11 tests, 31 assertions — all pass
- Verified with all 4 .proplaylist test files

Task 7 of proplaylist-module plan complete
2026-03-01 21:04:48 +01:00
Thorsten Bus d58bb38bb6 feat(playlist): add PlaylistEntry, PlaylistNode, PlaylistArchive wrappers
- Implement PlaylistEntry wrapper for PlaylistItem proto (23 tests, 40 assertions)
  - Support all 4 item types: header, presentation, placeholder, cue
  - Expose arrangement_name (field 5) for presentation items
  - Type-specific getters with null safety
- Implement PlaylistNode wrapper for Playlist proto (15 tests, 37 assertions)
  - Handle both container nodes (child playlists) and leaf nodes (items)
  - Recursive wrapping of nested playlist structures
- Implement PlaylistArchive wrapper for PlaylistDocument proto (18 tests, 37 assertions)
  - Top-level integration of nodes, entries, and embedded files
  - Lazy parsing of embedded .pro files into Song objects
  - File partitioning: .pro files vs media files

Wave 2 of proplaylist-module plan complete (Tasks 4-6)
2026-03-01 20:58:39 +01:00
Thorsten Bus 2c1b8e3370 feat(playlist): add proto field 5, Zip64Fixer, and format spec
- Add arrangement_name field 5 to PlaylistItem.Presentation proto
- Regenerate PHP proto classes with new field
- Implement Zip64Fixer utility to patch ProPresenter's broken ZIP headers
- Add comprehensive test suite for Zip64Fixer (7 tests, 37 assertions)
- Create pp_playlist_spec.md documenting .proplaylist file format

Wave 1 of proplaylist-module plan complete (Tasks 1-3)
2026-03-01 20:50:14 +01:00
Thorsten Bus 16577ef8a6 [AI] update CLI and docs with macro, media, and label features 2026-03-01 18:46:12 +01:00
Thorsten Bus cb219ea139 [AI] extend ProFileGenerator with macro, media, and label creation 2026-03-01 18:46:10 +01:00
Thorsten Bus 3a33597bcf [AI] add slide label, macro, and media support 2026-03-01 18:46:08 +01:00
Thorsten Bus addda54957 add more test .pro files 2026-03-01 18:30:59 +01:00
Thorsten Bus f258f8f2ce [AI] update spec and docs with metadata and generator usage
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-03-01 16:34:17 +01:00
Thorsten Bus fd639e6938 [AI] integrate metadata display into CLI tool
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-03-01 16:34:12 +01:00
Thorsten Bus 22d98e2225 [AI] add ProFileGenerator to create .pro files from scratch
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-03-01 16:34:04 +01:00
Thorsten Bus 83fb1a71f4 [AI] add Song metadata getters/setters for CCLI, category, notes
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-03-01 16:34:00 +01:00
Thorsten Bus 3351b7f138 [AI] first parser implementation 2026-03-01 16:12:17 +01:00
Thorsten Bus b26eebe908 add ref and AGENTS.md 2026-03-01 14:40:50 +01:00
Thorsten Bus e00fda595d init 2026-03-01 14:17:00 +01:00