End actions (load-next, play-next) create playback automations that remove
operator control between events and can surprise users. The agenda-building
prompt previously encouraged play-next for back-to-back segments, causing the
agent to add end actions proactively.
Update the endAction field description and the create_rundown_from_agenda
prompt so end actions are only applied when the user explicitly asks for
automatic cueing or chaining; a seamless schedule no longer implies automation.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011u3XRF6QwHZNB5o69xJ7UB
Adds three new MCP tools for managing project-level custom field definitions:
- ontime_create_custom_field: create a field with label, type, colour; key is auto-derived from label
- ontime_update_custom_field: rename or recolour an existing field (cascades key renames to all entries)
- ontime_delete_custom_field: remove a field and its values from all entries across all rundowns
Also improves the assertKnownCustomFields error to guide the agent toward creating the
missing field rather than just reporting it as unknown, and adds a manage_custom_fields
prompt for guided field management workflows.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011u3XRF6QwHZNB5o69xJ7UB
- Tool handlers are now a typed map of thin translation wrappers: wire
arguments are cast once at the boundary to types derived (Pick) from
ontime-types, and all service calls are fully typed — a change to a
service signature or domain type now fails compilation in api-mcp
instead of drifting silently. No more 'as never' casts.
- Entry mutations target the loaded rundown explicitly, matching the
rundownId-first service signatures introduced with secondary rundowns.
- Rundown create/rename/delete/duplicate call the rundown service;
mcp.service.ts and its duplicated router logic are deleted.
- ontime_create_entry supports all entry types (event, delay, milestone,
group) and entry tools accept flag and custom field values, matching
what the workflow prompts already instruct agents to do. Tool names
use entry terminology consistently with the service layer.
- ontime_create_project description fixed: creating a project switches
to it.
https://claude.ai/code/session_01V27pYyjw2PGSWy7wNtiWKj
Reverts the change to the shared authenticate middleware, which made
every authenticated route accept Authorization: Bearer tokens. Bearer
support now lives in a wrapper middleware inside api-mcp, mounted only
on /mcp; all other requests fall through to the app middleware
unchanged. Removing the api-mcp module restores stock auth behaviour.
https://claude.ai/code/session_01V27pYyjw2PGSWy7wNtiWKj
Moves the logic previously inlined in the router handlers into
rundown.service.ts so other consumers (such as the MCP server) can reuse
it without duplication. Status codes and error messages are unchanged.
https://claude.ai/code/session_01V27pYyjw2PGSWy7wNtiWKj
mcp.resources.ts: replace 6-branch if-chain with a RESOURCE_READERS dispatch map.
Each resource is now a one-liner { mimeType, read } entry; handleReadResource
collapses to a 3-line lookup with a single throw.
mcp.prompts.ts: extract repeated message-wrapping boilerplate into userPrompt()
helper, reducing each prompt from ~10 lines of structure to a single call.
Enrich all four prompts with operational domain knowledge:
- create_rundown_from_agenda: entry type selection (event/milestone/delay/group),
timerType and endAction guidance, linkStart chain semantics, flag usage, colour
conventions
- bulk_edit_rundown: timeStrategy (lock-end vs lock-duration), endAction automation
risk, clarified time-shift mechanics
- validate_rundown: totalDelay/totalDays checks, linkStart chain validation,
play-next chain disclosure, flag audit
- restructure_rundown: group awareness (entries vs order arrays), insert order type,
move-out vs move-in patterns
https://claude.ai/code/session_01U24MeuUacYXeQhbX3tatEe
- mcp.router.ts: extract identical GET/DELETE 405 responses into methodNotAllowed
- mcp.service.ts: pass the already-patched rundown object to initRundown instead
of re-fetching it from the data provider
- McpSection.tsx: compute mcpClientConfig only when mcpEndpointUrl is truthy
https://claude.ai/code/session_01U24MeuUacYXeQhbX3tatEe
Single file to update when the data model changes:
- EVENT_TIMER_FIELDS and EVENT_WRITABLE_FIELDS (tool JSON schemas) moved from mcp.tools.ts
- ONTIME_SCHEMA_MARKDOWN and ONTIME_DOCS_MARKDOWN moved from mcp.resources.ts
- mcp.tools.ts and mcp.resources.ts now import from mcp.schema.ts
- Removed inline data model notes from the agenda prompt; replaced with a reference
to the ontime://schema resource
- Fixed inaccurate enum values in schema (Milestone type added, TimerType/EndAction
corrected to match ontime-types)
https://claude.ai/code/session_01U24MeuUacYXeQhbX3tatEe
Exposes a curated index of docs.getontime.no topic URLs as the
ontime://docs MCP resource, and adds a "Further reading" footer to
ontime://schema so agents reading the data model know where to find
deeper documentation.
https://claude.ai/code/session_01U24MeuUacYXeQhbX3tatEe
Adds five resources so the agent can load context once per session
instead of re-fetching via tools, and so it can ground its answers in
Ontime's data model without guessing:
- ontime://schema — markdown reference for the event/rundown/group
model, time format (ms from midnight), cue conventions, colours,
playback states
- ontime://rundown/current — full currently-loaded rundown (JSON)
- ontime://rundowns — every rundown in the project plus the loaded ID
- ontime://project/info — project metadata
- ontime://project/custom-fields — custom field definitions
Declares the resources capability on the MCP server and registers
resources/list and resources/read handlers that dispatch by URI.
https://claude.ai/code/session_01U24MeuUacYXeQhbX3tatEe
Adds 8 tools and 3 prompts to cover four priority pre-production flows:
build-from-agenda (batch create), bulk edit, validate, restructure.
Tools:
- create_events_batch, batch_update_events — avoid per-event round trips
- list_projects, load_project, create_project, rename_project,
duplicate_project, delete_project — project file management
Prompts:
- bulk_edit_rundown — teaches the agent to use batch_update_events vs
per-event updates based on whether fields are shared
- validate_rundown — pre-show checks for cue gaps, overlaps, missing
fields, duration anomalies
- restructure_rundown — teaches reorder_event sequencing
- create_rundown_from_agenda — updated to use create_events_batch
Safety:
- Mutating tools now attach a playback warning to their response when
timer state is not stopped, so the agent can relay it to the user
- create_automation description mentions the in-app test button
https://claude.ai/code/session_01U24MeuUacYXeQhbX3tatEe
- Session ID: deterministic UUID passed to sessionIdGenerator so the
map key matches the mcp-session-id header sent to clients; previously
two independent randomUUID() calls produced different IDs, breaking
all post-initialize requests
- rename_rundown: use spread { ...rundown, title } instead of narrow
structuredClone cast that silently stripped order/entries/revision
- DELETE /mcp: return 204 No Content instead of 200 with body
https://claude.ai/code/session_01U24MeuUacYXeQhbX3tatEe
Adds a Streamable HTTP MCP server at /mcp that exposes 19 tools
covering rundown entries, rundown management, runtime state, project
info, automations, and custom fields. Includes Bearer token auth
support and a UI card in Settings > Sharing showing the endpoint URL
and Claude Desktop config.
https://claude.ai/code/session_01U24MeuUacYXeQhbX3tatEe
* feat: create the first event from the cuesheet
* chore: cleanup css
* test: cuesheet beckground edit from empty state
* feat: only show +event button when user is in edit mode and have full write perms
* refactor: allow secondary rundowns
* ui: move dropdown
* feat: follow loaded
* ui: background edit warning
ui: fix disable radio button
* feat(ui): add loaded sufix in the rundown list
* feat(ui): add direct link to background edit from rundown manager
* fix: better fallback
* fix: default to is isCurrentRundown for nav bar colour
* chore: rename navigate to cuesheet
---------
Co-authored-by: alex-arc <ac@omnivox.dk>
Adds timer-legacy.html — a zero-dependency static page that connects
to the Ontime WebSocket and displays the live countdown for browsers
that cannot parse the Vite-built React bundle (Safari < 14, Chrome < 85).
Also adds a synchronous pre-React guard in index.html that redirects
/timer visitors to the legacy page when Promise.any is unavailable,
matching the Vite build target floor of Safari 14 / Chrome 85.
https://claude.ai/code/session_013MfdwdjdDUnr3akpGSGXa4
* feat: update auto cue numbering
* feat: renumber from ui
* refactor: patchEntries is not used
* chore: format
* fix: correct cue at top of group
* fix: handle precision
* refactor dialog
* bump limit for performance time test
* extract type
* add class name to lable
* fix rebase
* refator: extract renumering logic
* chore: comments for getIntegerAndFraction function
* chore: add the for renumber mutation
* fix: fraction match precision
* refactor: small cleanup
* refactor: use more narrow validator
---------
Co-authored-by: alex-Arc <omnivox@LAPTOP-RC5SNBVV.localdomain>
* refactor: remove unneeded async
* chore: add express Router type to all routes
* refactor: don't use index in react key
* refactor: correctly get error message in excel route
* refactor: avoid exporting muteable values
* refactor: replace traslation hook refetch time with stale time
* refactor: make it the service responsebillety to send refetch keys for asset changes
* chore: only run release action if we have a tag
* chore: typescript 6 is out of beta
* chore: update flaky test
* chore: update pnpm
* chore: update playwright and node types
* chore: migrate tsup to tsdown
* chore: update node to node 22.22.2(LTS)
* chore: fix lockfile
---------
Co-authored-by: alex-Arc <omnivox@LAPTOP-RC5SNBVV.localdomain>
* fix: prevent add filter from submitting form
* refactor: event clarifies whether automations exist but are disabled
* refactor: improve readability of automation form
* refactor: add affordance for field warnings
* refactor: improve visibility of automation off state
* refactor: apply warning styles to other feature toggles
* Adding playback actions to automations (#2024)
* adding intial automation actions
* cleaning up
* fixing formatting
* ran oxfmt
* switching action names to playback- to match the dropdown strings
* fixing flicker that was caused by scroll arrows gettting unmounted
---------
Co-authored-by: Cameron Slipp <cdslipp@gmail.com>
* chore: upgrade vite
* fix: inconsistentCjsInterop for ReactQR
* chore: e2e tests should use relativve path and get host from playwright config
* refactor: drop qr code dependency
---------
Co-authored-by: alex-Arc <omnivox@LAPTOP-RC5SNBVV.localdomain>
* chore: migrate eslint to oxlint
* chore: migrate prettier to oxfmt
* chore: migrate typescript
* chore: toThrow should have a expected value
* chore: cast test value as Day
* chore: small title fix
* chore: mocks should be hoisted
* chore: incorrect async useage
* chore: test should be inside description
* chore: test sohuld include an expeced
* chore: oxfmt
---------
Co-authored-by: alex-Arc <omnivox@LAPTOP-RC5SNBVV.localdomain>
* feat: get server port from app satate or env
optional startup port from env will always override
function for parsing port from env
populate default port in app state
add test for migration
* bump version
* feat: main src in backstage view
* feat: main src in timeline view
* feat: main src in countdown view
* feat: main src in studio view
* feat: hide past events in countdown view
* notes can not be set as main src
* feat: show group title as secondary src
* chore: spelling
Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
---------
Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
The logic for deciding whether to show the welcome modal has been moved from `app.ts` to `AppStateService.ts`. The `getShowWelcomeDialog` function now accepts a boolean indicating whether a restore point exists and returns `false` if it does. This keeps the business logic out of the main application file and in the relevant service.
* Fix(automation): Handles undefined values in conditions (#1933)
* Fix(automation): Handles undefined values in conditions
Addresses an issue where conditions with the 'not_equals' operator incorrectly evaluated undefined values. This change ensures that empty string comparisons correctly identify missing values in automation rules.
* Fixes automation "not equals" logic
Simplifies the 'not_equals' condition evaluation in automations by reusing the 'equals' condition, improving code readability and consistency.
Fixes#1932
* Test(automation): Expanding filter condition testing
Expanding test cases to cover various data types and edge case for each operators.
Unexpected behavior have been mark with a TO_DO.
* Fix(automation): Handles default filter case
- Ensures that their is a default scenario.
- Fixing Deepsource issue "No default cases in switch statements JS-0047"
* Test(automation): Remove abstraction in test
* move to test.each
* extract a isEquivalent function
* lowercase contains test
---------
Co-authored-by: Philippe Allard-Rousse <philrousse@gmail.com>
* chore: remove old comment
* chore: smal lclean up of a e2e test
* chore: bump to beta.6
* chore: cleanup imports
* fix integration values com in ms
* allow linkStart and timeStrategy from API
* remove local mac dist
* fix resolver build
* fix docker build
* node version in docker via arg
* add step to setup auth for pnpm
* lint
---------
Co-authored-by: Joel Wetzell <jwetzell@yahoo.com>
* refactor: use correct metadata in op view
* refactor: use correct metadata in backstage view
* remove uneeded test
* fix: correct offset colour
* refactor: use correct metadata in timline view
* refactor: schedule item dont pass the whole event
* chore: lint
* fix: patch in the active rundown id and title
* fix: send a ALL refetch on project patch
* fix: load the last used rundown on project patch and not just the first one
* chore: lint
* chore: clean up and let rundown service send the refetch request
* chore: dont destructure rundown
* feat: add group start time to state
* refactor: calculate expected times when offset mode changes
* feat: show relative data in ui
* fixup! feat: add group start time to state
* fixup! refactor: calculate expected times when offset mode changes
* fixup! feat: show relative data in ui
* try to handle multiday
* show planed/expected rundown end day offset values
* refactor: style tweaks to timers
* refactor: cleanup data use
* day offset
* update tests
* test getExpectedStart multiday
* write start epoch to restore file
* current day in relative mode
* remove todo
* move find day offset to utils
---------
Co-authored-by: arc-alex <ac@omnivox.dk>
* fix error with is linked to loaded metadata
* pass down metadata
* create expected schedule
* expected start in sub info
* for singel subscribtions
* refactor
* add color to single events
* refactor: clean up subscribtion data
* show schedule and secondray data for single events
* improve subscribtion data display
with this changes we allow the client and server to share the same data
shape. even if some of it is useless.
we also get an extra version property in the payload, if we want to save
the transfer cost, we would rather remove it from the sent payload
* refactor: align header columns
* refactor: improve scrollbar visibility
* refactor: center align table elements
* refactor: make param elements stateful
* fix: issue with collapsed elements not loosing value
* fix: prevent search params containing multiple alias references
* fix: the issue where a file disappears if it is both migrated and recovered in the same load operation (#1744)
* refactor: disable group action for elements in groups
* refactor: move context menu items into the event element (#1747)
* feat: sheet import new features for v4 (#1730)
* import milestone
* fixup! import milestone
* test: milestone import
* add entries to group
stop on new group or on group-end type
* fixup! add entries to group
* cleanup
* add event target duration
* link start if undefined
* add skip import type
* extract some to the excel paresing functions
* tweaks to presentation
* move file
---------
Co-authored-by: Carlos Valente <carlosvalente@pm.me>
* fix: notify runtimeStore of events bieng groupd
* fix: improve authentication and stage detection in demo
* chore: ship logo with project
* fix: client is referenced by name
* fix: prevent reflow in event editor
* fix: stale render on selected event due to ref mismatch
* Create/Load/Delete multiple rundowns (#1696)
* refactor: restore last loaded rundown
* refactor: initialise rundown in ProjectService
* feat: allow switching rundowns
ensure on coordination between the db object and the working object
server provide list of rundowns
implement switch in the UI
implement delete
implement new rundown button
* fix: render order for floating button
* refactor: appropriate names to service
* refactor: rundown endpoints
* refactor: save last loaded rundown ID
* refactor: rundown management UI
* refactor: emit refetch all on project load
---------
Co-authored-by: Carlos Valente <carlosvalente@pm.me>
* feat: recover single event subscription
* fixup! feat: sheet import new features for v4 (#1730)
* fix: prevent dropping a group inside another
* fixup! refactor: move context menu items into the event element (#1747)
* fix: prevent stale references to custom fields
* fix: propagate updates to all rundowns
* refactor: client rundown metadata (#1728)
* generate metadata in the hook
* move test
* ensure there is always a last element
* use for-loop
* update metadata in useEfect
* fully extract metadata generation
* use direct assignment
* cleanup
---------
Co-authored-by: Carlos Valente <carlosvalente@pm.me>
* refactor: small imporvement and tests for coerce functions (#1752)
* refactor: small imporvement and tests for coerce functions
add test `coerceString`
add test `coerceBoolean`
add test `coerceColour`
* remove old todo
* fix: consistent quick add behaviour
* refactor: create flat rundown with metadata
* fix: show add buttons on top
* feat: allow editing milestones
* refactor: style tweaks to rundown elements
refactor: milestones are full width
refactor: cuesheet header alignment
fix: editor styling in cuesheet
* refactor: virtualise table
* refactor: improve overscan (#1758)
* bump version to 4.0.0-alpha.5
---------
Co-authored-by: Alex Christoffer Rasmussen <ac@omnivox.dk>
The IntersectionObserver callback in rowObserver.ts was capturing the `addVisibleRow` and `removeVisibleRow` actions from the Zustand store only once, at the time of the observer's creation.
This created a potential for a stale closure bug, where the observer would call outdated action functions if the store's state or actions were ever re-initialized. This would lead to the application's state not being updated correctly, causing the bug where visible rows would not render their content.
This commit fixes the issue by calling `useVisibleRowsStore.getState()` inside the observer callback. This ensures that the latest, freshest versions of the action functions are always used, preventing the stale state bug.
* refactor: runtime types
* refactor: runtimeState functions to use the split type
* refactor: RuntimeService to use the new split data
* refactor: use the split data in the UI
* update comments
* refactor: rename runtime to offset
* fix utils test
* migrate settings
* migrate viewsettings
* migrate url preset
* migrate project data
* migrate custom fields
* migrate automations
* migrate rundown
* lint
* return custom field translation table
* check regex
* new url type
* refactor
* migrate old OSC subscriptions
* migrate old http subscriptions
* update comments
* migrate the whole db
* remove automation logging unlis there is an error
* return a new object
* refactor: copy currup is only used in one place
* make a copy of original migrated file
* refactor: ensure image flder is part of project service init
* add entrys to groups
* small cleanup
* just drop incorrect custom fields in the default data parser
* refactor: split event data and state data
* refactor: calculate the start time insted of until
* cleanup
* send next flag expected start from server
* refactor: render
* fix test
* use same icon
* refactor: group duration
* Optimize (#1711)
* refactor: consolidate block, flag and end loading and expected times
* work on test
* cal end value
* lint
* fix test
* remove todo
Updated DEVELOPMENT.MD to use `turbo run <task>` instead of `turbo <task>` for clarity and consistency when referring to Turborepo tasks that don't have a direct pnpm script alias.
Also, added `dependsOn: ["build"]` to `dist-*` tasks in `turbo.json` to ensure correct build order before packaging.
- italic and bold for rundown metadata entries
- allow deleting groups
- make groups in order
- correct style for milestones
- open playing groups
- style tweaks
* switch to base ui
* ensure all action types is part of the valitation
* update test
* atempt to do it in the base-ui way
* fix fixing
* allow undefide visible on set timer message
* fix set time not showing
* correct time data for aux set automation
---------
Co-authored-by: Carlos Valente <carlosvalente@pm.me>
fix: close modal with button
refactor: small type improvements
refactor: migrate time inputs
refactor: migrate tooltips
refactor: prevent component resizing
* Refactor: Remove GOT dependency, use simplified fetch wrapper
Replaced GOT with a lightweight, functional, fetch-based utility (`appClient.ts`) for handling JSON POST requests in `SheetService.ts`.
- Created `appClient.ts` to encapsulate fetch logic. It mimics GOT's behavior for sending JSON payloads and parsing JSON responses.
- Error handling in `appClient.ts` uses standard `Error` objects with descriptive messages, including status and error body details, instead of custom error types.
- Updated `SheetService.ts` to use the new `appClient.ts`.
- Removed `got` from server dependencies.
* cleanup
* dont throw when we know the error
* rearange logging
---------
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: arc-alex <ac@omnivox.dk>
Decouples the IntersectionObserver from the React component tree to
prevent
unnecessary re-renders of the entire Cuesheet table when row visibility
changes. Restores rootMargin for better UX and memoizes EventRow.
- Introduced `rowObserver.ts` to manage a global IntersectionObserver.
- Observer callback directly updates `useVisibleRowsStore`.
- Configured with `rootMargin: '400px 0px'` and `threshold: 0.01`
to pre-load and retain rows near the viewport, improving UX.
- `EventRow` components use `observeRow`/`unobserveRow` from
`rowObserver.ts`.
- `EventRow` is now wrapped in `React.memo` to prevent re-renders if
props
haven't changed when its parent re-renders.
- Removed observer creation and prop-drilling from `CuesheetBody.tsx`.
This ensures only individual rows re-render content based on visibility
and optimizes row component rendering, improving performance and UX.
* adding block now/next data
* add to ui
* add blockNext
* indicate in UI
* fix test
* restore block start at value
* one loop
* stricter null comparison
* test fails
* dev throw if id cant be found
* fix spelling
* revert client stuff
* rename
* add comment
* change load to use metadata
* update roll to use metadata
* remove filterTimedEvents
* add comment
* atempth to refactor rollUtils
* refactor util functions
* refactor: WS
* refactor refetch
extract refetch keys to package/types
auto invalidata all keys
use refetch keys for project data
no need for constant update of info, just fetch when looking at it
split refetch and query keys
rename types
* refactor viewSettings
* fixup! refactor: WS
* rearange files and make types for api calls
* cleanup viewsettings
* switch exhaustiveCheck
* combine send socket function
* exhaustive check
* rename type to tag
* fixup! fixup! refactor: WS
* remove custom etag solution
* get errors from socket
* lint
* small change
---------
Co-authored-by: Carlos Valente <carlosvalente@pm.me>
* Revert "refactor: add version to session endpoint"
This reverts commit cd40a6e55e.
* Revert "Remove public event feature (#1645)"
This reverts commit 08d9e24871.
* Revert "Fix: rearrange playing event (#1640)"
This reverts commit 0649678dca.
* Revert "refactor: style tweaks to edit css modal"
This reverts commit a00ec2d02a.
* Revert "refactor: remove usages of framer-motion"
This reverts commit 54a74ccc2a.
* Revert "Upgrade expressjs (#1633)"
This reverts commit 6f3ab274bd.
* Revert "Refactor: require trigger in all events objects (#1636)"
This reverts commit 90870ecfb6.
* Revert "Fix: Correct boundary condition in applyDelay"
This reverts commit b640e0e181.
* Revert "let vite be the proxy to the dev server (#1630)"
This reverts commit c41fe824cf.
* Revert "refactor: migrate custom fields to transactions"
This reverts commit 62c8319d70.
* Revert "refactor: simplify validations"
This reverts commit b1d23467a2.
* Revert "refactor: create transaction system and apply to adding entry (#1620)"
This reverts commit 9a62daf047.
* Revert "Refactor: better rounding (#1594)"
This reverts commit b9ab1c6fd7.
* Revert "refactor: improve reorder logic"
This reverts commit c1054711b0.
* Revert "chore: simplify URLs"
This reverts commit a4d4f29a37.
* Revert "refactor: order is single source of truth"
This reverts commit 2793aadea0.
* Revert "refactor: refetch targets is enum"
This reverts commit e7cfb7d9d9.
* Revert "refactor: small ux improvements"
This reverts commit 256a851c9b.
* Revert "refactor: remove trivially inferred numEvents"
This reverts commit 4ab9c81cb8.
* Revert "feat: duplicate groups"
This reverts commit 2f13d6c89e.
* Revert "feat: create group from entry selection"
This reverts commit f1f7bad25e.
* Revert "feat: create block from rundown empty"
This reverts commit a8b52a48f7.
* Revert "fix: collapsed blocks dont render children"
This reverts commit cd0999b2ab.
* Revert "refactor: type cleanup and test improvements"
This reverts commit b4c60f3f04.
* Revert "feat: allow dissolving a block"
This reverts commit 5cefad3666.
* Revert "fix: uncontrolled prop on controlled component"
This reverts commit 7a6ecd8c34.
* Revert "refactor: improve return of reorder"
This reverts commit ba96ecfd91.
* Revert "refactor: mutations on batch elements must have IDs"
This reverts commit 7bed3757f2.
* Revert "chore: upgrade dependencies"
This reverts commit e2e755b1d2.
* Revert "refactor: extract utility to merge two arrays"
This reverts commit a77d23109d.
* Revert "refactor: change network mode defaults"
This reverts commit 0eb3b8d382.
* Revert "fix: delete nested events"
This reverts commit 0021185288.
* Revert "fix: add event at end of block"
This reverts commit 94c72ff4f6.
* Revert "refactor: make finder available in exported rundown"
This reverts commit e4c08dc9b2.
* Revert "assert non null and update test (#1604)"
This reverts commit ec74af0d62.
* Revert "Fix project renumber (#1597)"
This reverts commit b6d72dd082.
* Revert "Refactor: WebSocket from flush queue to one patch (#1595)"
This reverts commit 31c311daf0.
* Revert "Refactor: ms for api calls (#1593)"
This reverts commit e9b3cc6090.
* Revert "fix test (#1601)"
This reverts commit 543b04a097.
* Revert "fix: rebase master"
This reverts commit d39b85b6e6.
* Revert "chore: correct test path"
This reverts commit bbe107bb2b.
* Revert "refactor: extract rundown parsing"
This reverts commit c616240db1.
* Revert "chore: improve convention entry <> event"
This reverts commit 166be66ce3.
* Revert "refactor: maintain flat orders"
This reverts commit 4180d0a337.
* Revert "refactor: implement operations on nested events"
This reverts commit 78108e316c.
* Revert "refactor: process events in rundown"
This reverts commit 3bb8b70915.
* Revert "chore: improve convention entry <> event"
This reverts commit 1c4f13a0ed.
* Revert "chore: rename currentBlock > parent"
This reverts commit 3ca0abad53.
* Revert "refactor: fix delay positioning in gaps"
This reverts commit 030c8f897f.
* Revert "refactor(e2e): skip flaky test"
This reverts commit 68175cfa3b.
* Revert "refactor: improve project loading"
This reverts commit fd8f757851.
* Revert "refactor: gather group metadata"
This reverts commit 876d111c61.
* Revert "refactor: swap maintains schedule"
This reverts commit 730cb95c04.
* Revert "chore: rename files"
This reverts commit 3c388d4fb5.
* Revert "refactor: restructure model to contain an object of rundowns"
This reverts commit 2e23718d73.
* Revert "refactor: clearer relationship on rundown elements"
This reverts commit 89ea8c470b.
* Revert "refactor: use strict typing"
This reverts commit 178640bfc4.
* Revert "refactor: remove stop as a possible end action"
This reverts commit 4ed38340e0.
* Revert "refactor: restructure model to contain an object of rundowns"
This reverts commit 69eb9a5eff.
* Revert "chore: remove IDE files"
This reverts commit 351425127a.
* Revert "refactor: remove unused and legacy code"
This reverts commit 95f2ba37cc.
* creat failing test
* find and pass index of eventNow in case it moved
* fix cache invalidate edits should also recalculate timer
* use coluor as test indicator
* fixed empty cue guard
Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
---------
Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
* upgrade expressjs
* migration
* reenable test
* extend timeout on download test
* fixup! migration
* move empty body test from controller to validator
* enusre not empty
* extract validation function
* fixup! reenable test
* remove thin controllers
* disable e2e test of project file download
The `applyDelay` function had a condition that incorrectly used `rundown.order.length` instead of `rundownMetadata.flatEntryOrder.length` to check if a delay entry was the last in the sequence. `rundown.order` only contains top-level entries, while `flatEntryOrder` contains all entries, including those within blocks, which is the relevant list for this check.
This commit corrects the condition to use `rundownMetadata.flatEntryOrder.length`.
Existing tests in `rundown.dao.test.ts` (specifically the test `removes delays in last position without applying changes`) already cover this scenario and pass with the correction, ensuring the fix behaves as expected.
* fix: generateUniqueFileName
* loadProject should not generate new names
* update comments
* extract and test getProjectNumber
* spell
* finish jsdoc
* use getProjectNumber
* cleanup loadProject
* create a `incrementProjectNumber` function
* spelling
Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
---------
Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
* creat failing test
* find and pass index of eventNow in case it moved
* fix cache invalidate edits should also recalculate timer
* use coluor as test indicator
* fixed empty cue guard
Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
---------
Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
* upgrade expressjs
* migration
* reenable test
* extend timeout on download test
* fixup! migration
* move empty body test from controller to validator
* enusre not empty
* extract validation function
* fixup! reenable test
* remove thin controllers
* disable e2e test of project file download
The `applyDelay` function had a condition that incorrectly used `rundown.order.length` instead of `rundownMetadata.flatEntryOrder.length` to check if a delay entry was the last in the sequence. `rundown.order` only contains top-level entries, while `flatEntryOrder` contains all entries, including those within blocks, which is the relevant list for this check.
This commit corrects the condition to use `rundownMetadata.flatEntryOrder.length`.
Existing tests in `rundown.dao.test.ts` (specifically the test `removes delays in last position without applying changes`) already cover this scenario and pass with the correction, ensuring the fix behaves as expected.
* fix: generateUniqueFileName
* loadProject should not generate new names
* update comments
* extract and test getProjectNumber
* spell
* finish jsdoc
* use getProjectNumber
* cleanup loadProject
* create a `incrementProjectNumber` function
* spelling
Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
---------
Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
* refactor
* separate in and out time
* keep element on screen
* animate on play
* spelling
* explain animation decisions
* guard numbers from url params
* spelling
Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
* rename safeParseNumber
* use view data
* refactor getOptionsFromParams
* rebalance animation timing
---------
Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
* inti relative mode
* send imediat update on mode change
* add relative to test
* don't persist offset mode
* add test relative and update calc function
* pass data from ssocket
* add dev guard
* spelling and comments
* show relative in offset overview
* remove comments
* refactor: move totalDelay to _rundown
* update clear naming and comments
* remove old testing values
* crude UI
* add server functionalety
* better event trigger list
* fix default value
* remove log
* add trigger to recalculate whitelist
* use DTO type
* fix rebase
* one callback for delete and submit
* refactor
* add invalid description
* clean up commits
* cleanup
* refactor: find event triggers in `triggerAutomations`
* refactor: switch to flat array for event triggers
* prevent deleting a automation that is in use
* refactor
* refactor: extract EventEditorCustom
* move trigger options to separate file
* move trigger edit down a file level
* cleanup
* spelling
* refactor: ui review proposal
* change default value
* fix delete filter
---------
Co-authored-by: Carlos Valente <carlosvalente@pm.me>
* create report service
* write report from runtimeState
* use in UI
* clear report
* update types
* clear all from settings menu
* rearence rightclik menu
* refactor styling
* also report roll events
* ontime/under time is same colour
* refactor reporter
* add target to ontime-refetch
* remove menu
* fectch only on message from server
* memo useGetEventReport
* refactor
* use staleTime
* dont add to menu yet
* implement review
* clear all from menu
* fix merge
* start end show
* combine test for the go button text and action
* add report to menu
* extract csv utility
* report management
* unneeded async
* small refacort of triggerReportEntry
---------
Co-authored-by: Carlos Valente <carlosvalente@pm.me>
refactor: improve empty state
refactor: review schedule design
- fit as many elements as possible
- expose cycle interval as an option
- stabilise rundown reference
- style tweaks
welcome modal is persisted in app state
created endpoints to set the visibility
added UI to support feature
Co-authored-by: Carlos Valente
<34649812+cpvalente@users.noreply.github.com>
* add dayOffset to OntimeEvent
* refactor: isNewLatest
* calculate totalDays
* refactor: getTimeFromPrevious
* add gap as dataset in OntimeEvent
* use in ui
* format overlap is just a simple text formatting, big test is not needed
* add new fields where needed
* update apply delay
* show nex day eaven if there is no gap
* create test
* use buildin day offset in timeline
* remove todo
* consistent naming
* make a calculateDayOffset util for rundownCache
* refactor: checkIsNextDay to use dayOffset
* spelling
Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
* remove unneeded test
* remove todo
* update test db
* use data-testid
* spelling
Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
* update comments
* remove null option
---------
Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
* create db event type
* dont use it yet
* convert to and from database type
* type needed in one place in client
* use flatMap to filter out unknow stuff
* leave revision in save file
* move to utils
* make test
* destructur entry
* simple test
* throw in rundownToDatabaseRundown
* clerify comment
* Refactor: avoid shadowing the rundown variable in rundownCache (#1409)
---------
Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
* rename to DAO
* add simple edit test
* only the generate function clears the state state
* strict guard for custom fields
* fix small strict issues
* ensure deep copy
* safely set isStale
* todo is done
* small type error
* these functions can work on DAO entries
* only reat rundown as DAO on initial load and the cast immediately and esure all fields are present
* eslint comment
Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
* fix spelling
Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
* fix spelling
Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
* comment not needed
* setIsStale
* remove DAO
* clean up commits
* remove unneeded async/await
* revert test
---------
Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
* detect `EADDRINUSE` on server start
* @ts-expect-error
* send portError to electron
* use escalateErrorFn
* dont move in docker
* allow errors to be sendt to electron UI
* Log after the new port is found
* Update comment
Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
* update comment
Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
* update comment
Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
* rename to escalate
* extract `serverTryDesiredPort`
* type check server.address()
* request shutdown on `unrecoverable` `escalateError`
* combine network utils
* reject promise
* not unrecoverable by default
* unneeded assignment
---------
Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
* pass on all event edits
* MakePublic
* trim value in cell
* edit notes
* title
* add key check
* don't log error
Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
* checkbox
* refactor
* remove log
* fix test
* use row number to test value
---------
Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
* feat: add lock icon when param `locked=true`
* chore: move `isViewLocked` logic up the component tree
* chore: remove extra container from lock icon
* chore: move fading logic into separate hook
* chore: move locked icon into separate component
* chore: rename variables
* use xlsx
* add existing custom fields to import map
* keep colours of existing custom fields
* use unknown
* fix
* revert
* allow space and upper case
* fix test
* define empty sheet
* remove custom field lowercasing
* don't allow custom field form to submit duplicate field
* remove unused
* update custom field tests
* also keep upper case when editing
* show key in UI
* also kep upper case when creating a new field
* fix test
* allow old forced case keys to stay as is
* allow space
* add extension to import
* supply initial key to CustomFieldForm
* refactor: improve element contrast
* refactor: style and composition
* consistent use of `customFieldLabelToKey`
* fix CopyTag
* remove log
---------
Co-authored-by: arc-alex <ac@omnivox.dk>
Co-authored-by: Carlos Valente <carlosvalente@pm.me>
* Revert "refactor: allow messages not starting with http"
This reverts commit 887e5c448e.
* Revert "refactor: allow messages not starting with http"
This reverts commit 6ce275da7a.
-**Run docker image from compose** by running `docker-compose up -d`
Other useful commands
-__List running processes__ by running `docker ps`
-__Kill running process__ by running `docker kill <process-id>`
-**List running processes** by running `docker ps`
-**Kill running process** by running `docker kill <process-id>`
## General Info
## FORMATTING AND LINTING
# APP Building
Ontime uses [oxfmt](https://oxc.rs/docs/guide/usage/formatter.html) for formatting and [oxlint](https://oxc.rs/docs/guide/usage/linter.html) for linting. Look for an [oxc extension](https://oxc.rs/docs/guide/usage/linter/editors) for your editor of choice.
We build the app from app.js for almost all applications. The output file will still be named index.cjs. This is because of Electron.
Building the app from index.ts only applies for applications that don't use electron. index.ts will take over the initialization of the server and UI when electron isn't present.
- **Run formatter** by running `pnpm format`
- **Run linter** by running `pnpm lint`
## CONTRIBUTION GUIDELINES
If you want to propose changes to the codebase, please reach out before opening a Pull Request.
For new PRs, please follow the following checklist:
- [ ] You have updated and ran unit locally and they are passing. Unit tests are generally created for all utility functions and business logic
- [ ] You have ran code formatting and linting in all your changes
- [ ] The branch is clean and the commits are meaningfully separated and contain descriptive messages
- [ ] The PR body contains description and motivation for the changes
After this checklist is complete, you can request a review from one of the maintainers to get feedback and approval on the changes. \
<a href="https://www.buymeacoffee.com/cpvalente" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" height="32"></a>
- Download for <a href="https://github.com/cpvalente/ontime/releases/latest/download/ontime-win64.exe">Windows</a>
- Download for <a href="https://github.com/cpvalente/ontime/releases/latest/download/ontime-macOS-arm64.dmg">MacOS Arm</a>
- Download for <a href="https://github.com/cpvalente/ontime/releases/latest/download/ontime-macOS-x64.dmg">MacOS Intel</a>
- Download AppImage for <a href="https://github.com/cpvalente/ontime/releases/latest/download/ontime-linux.AppImage">Linux</a>
- Download for <a href="https://github.com/cpvalente/ontime/releases/latest/download/ontime-macOS-arm64.dmg">macOS (Apple Silicon)</a>
- Download for <a href="https://github.com/cpvalente/ontime/releases/latest/download/ontime-macOS-x64.dmg">macOS (Intel)</a>
- Download AppImage for <a href="https://github.com/cpvalente/ontime/releases/latest/download/ontime-linux-x86_64.AppImage">Linux (Intel / AMD 64-bit)</a>
- Download AppImage for <a href="https://github.com/cpvalente/ontime/releases/latest/download/ontime-linux-arm64.AppImage">Linux (ARM 64-bit, Raspberry Pi 4+)</a>
- Get from <a href="https://hub.docker.com/r/getontime/ontime">Docker hub</a>
- Install from <a href="https://www.npmjs.com/package/@getontime/cli">NPM</a>
- Install from <a href="https://formulae.brew.sh/cask/ontime">Homebrew</a>
## Need help?
We do our best to have most topics covered by the documentation. However, if your question is not covered, you are welcome to [fill in a bug report in an issue](https://github.com/cpvalente/ontime/issues), [ask a question in GitHub discussions](https://github.com/cpvalente/ontime/discussions) or hop in the [discord server](https://discord.com/invite/eje3CSUEXm) for a chat.
## Using Ontime?
Let us know!
Ontime improves from the collaboration with its users. We would like to understand how you use Ontime and appreciate your feedback.
We would also like to include a testimonials section in our ✨new website✨. It would be great to showcase the diversity of users running Ontime.
# Ontime
Ontime is a browser-based application that manages event rundowns, scheduling, and cueing.
@@ -35,6 +46,17 @@ Ontime is made by entertainment and broadcast engineers and used by
- Theatres and opera houses
- Houses of worship
## Main features
- **Multiplatform**: Available as a Cloud service and for Windows, macOS, Linux, or self-hosted via Docker.
- **In any device**: Ontime is available to any device with a browser, eg: tablets, mobile phones, laptops, signage, media servers...
- **Team Collaboration**: Dedicated views for directors, operators, backstage, and signage.
- **Real-Time Updates**: Manage and communicate runtime delays effortlessly.
- **Automatable**: Ontime can be fully or partially controlled by an operator, or run standalone with the system clock
- **Flexible Integrations**: Use one of the APIs provided (OSC, HTTP, Websocket) or the available [Companion module](https://bitfocus.io/connections/getontime-ontime) to integrate into your workflow (vMix, disguise, Qlab, OBS)
... and a lot more ...
### For live environments
Ontime is designed for use in live environments. \
@@ -62,96 +84,29 @@ Ontime is made by video engineers and entertainment technicians.
## Using Ontime
Ontime can be started by downloading the latest release for your platform. \
Alternatively you can also use the docker image, available at [Docker Hub](https://hub.docker.com/r/getontime/ontime)
### Getting started
Once installed and running, any device in the network has access to Ontime.
The easiest way to start with Ontime is by leveraging our [Cloud service](https://getontime.no). \
This will give you immediate access to running instances of Ontime which are available to share with anyone with an internet connection.
Ontime provides different screens which allow for different types of interactions with the data. These are called
views. \
Each view in Ontime focuses on empowering a specific role or achieving a particular task.
Alternatively, you can run Ontime locally for free by downloading the latest release for your platform or using the docker image, available at [Docker Hub](https://hub.docker.com/r/getontime/ontime)
You can access the different views by reaching the ontime server, in your browser, at (_default port
4001_) `http://localhost:4001` or `http://192.168.1.3:4001`
Once installed and running, any device that shares the same network as Ontime will have access to Ontime.
Ontime does not exist as a fiscal entity. The sponsorship recipient is the project owner. In this light, contributors are funding the project owner's capacity to work on the project, not the project itself. As a contribution recipient, the code owner reserves the right to redistribute.
## Why sponsor
Ontime is and will remain free, regardless of your decision to contribute.
Regardless, you may choose to provide a monetary contribution:
### Improve user experience
Certain parts of the application user experience are tied to our capacity to pay for services. App signing and Google Sheets integration are good examples of this.
### Cool stuff
We may choose not to implement some features. This could be related to the complexity required, to the skill set, or to the fact that we just feel it doesn't improve the app for a significant percentage of users. In those cases, a feature may be considered "not worth it," regardless of its pertinence.
As a user, you can choose to sponsor a particular feature or donate to the app so that we can create bounties for features.
### Priorities
Monetary contributions are most immediately needed to offset the costs of presenting and distributing Ontime, i.e., hosting, domains, and certificates.
Additional funding will be considered according to the needs at the time.
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.