Global

Members

AUTO_PAUSE_ON_TAB_SWITCH :boolean

When true, pauses a running timer automatically when the browser tab becomes hidden (visibilitychange → document.hidden). The pause is silent; the event is recorded in the console log via wlLog.info but no UI notification appears. Set to false to disable. Override in 00-config.local.js.

Type:
  • boolean
Default Value:
  • false
Source:

(constant) CAL_ACCOUNT_LABELS :Object.<string, string>

Maps raw Outlook account keys (lowercase) to human-readable labels shown in the calendar strip. The PowerShell server sends the DisplayName field; this map handles display-name variants, email domains, and substring matches.

Add an entry for each calendar account you want labelled; unknown accounts are shown without a label badge.

Type:
  • Object.<string, string>
Source:

(constant) COLLAPSE_PREFIX

localStorage key prefix for section open/collapsed state.

Source:

(constant) DAILY_GOAL_MS :number

Daily tracking goal in milliseconds. The header pace bar fills proportionally as today's logged time approaches this value. Default: 7 hours 30 minutes. Override in 00-config.local.js.

Type:
  • number
Source:

(constant) DEFAULT_WORK_LOCATION

Location id used for any day that has no stored value.

Source:

(constant) ICON_ACTIVITY

Activity-line SVG icon for the section header (Lucide-style, 24×24 viewBox, 1.5px stroke).

Source:

JIRA_BASE :string

Base URL for Jira ticket links. Ticket keys found in task names are converted to <a href="${JIRA_BASE}/${key}"> anchors. Set to '' to disable link generation. Override in src/js/00-config.local.js (gitignored) — copy from src/js/00-config.local.example.js and set your real instance URL.

Type:
  • string
Source:

(constant) MIGRATIONS :Array.<Migration>

Type:
Source:

(constant) RAPID_SIG_SHORTCUTS :Object.<string, string>

Signifier shortcode map for quick-capture inline tokens. Maps !<shortcode> tokens to signifier values used on entry objects. Unmapped tokens are left in the text unchanged.

Type:
  • Object.<string, string>
Source:

(constant) STORE_BLOCKS :string

localStorage key for the time-block array.

Type:
  • string
Source:

(constant) TF_PANE_IDS

Maps each view to the DOM id of the pane that hosts it.

Source:

(constant) TF_STRIP_END

21:00 in minutes from midnight — right edge of the day-overview strip.

Source:

(constant) TF_STRIP_START

07:00 in minutes from midnight — left edge of the day-overview strip.

Source:

(constant) TF_VIEWS

Ordered list of view ids — drives the segmented control and keyboard nav.

Source:

(constant) TF_VIEW_LABELS

Display labels for the segmented control. Static so we avoid recomputing on every render.

Source:

WEATHER_LAT :number

Latitude of the work location (decimal degrees). Default used when the server is not running; normally set via config.local.ps1.

Type:
  • number
Source:

WEATHER_LON :number

Longitude of the work location (decimal degrees). Default used when the server is not running; normally set via config.local.ps1.

Type:
  • number
Source:

WEATHER_NAME :string

Display name for the work location shown next to the weather widget. Default used when the server is not running; normally set via config.local.ps1.

Type:
  • string
Source:

(constant) WORK_LOCATIONS :Readonly.<Record.<string, {emoji: string, label: string}>>

Work-location presets keyed by their stored id. Each entry carries the emoji and human-readable label shown in the date-nav header. The first key is the default applied to any day with no stored location.

Type:
  • Readonly.<Record.<string, {emoji: string, label: string}>>
Source:

_boardDragTaskId

Shared drag-state for board column DnD (set by dragstart, read by drop).

Source:

_heroStopped :boolean

Type:
  • boolean
Source:

_heroStoppedEntry :Object|null

The log entry that was just stopped. Kept so the Undo action can recover it and the stopped panel can display the correct task name / session range.

Type:
  • Object | null
Source:

_heroStoppedTimer :number|null

Type:
  • number | null
Source:

_qcFilterCat :string|null

Active category chip selection. Serves two purposes:

  • filters the task list to show only that category, and
  • tags any ad-hoc log entry created via "Log without tracking". null means "All" (no filter; entry falls back to selectedTag).
Type:
  • string | null
Source:

_qcSearch :string

Type:
  • string
Source:

_qcTickInterval :number|null

Type:
  • number | null
Source:

_rapidOpen :boolean

Type:
  • boolean
Source:

catManageOpen

Controls whether the epic manage row (rename/delete/add) is expanded.

Source:

doneHistoryOpen

Whether the Done column's older-history expander is open.

Source:

emergencyMode :boolean

True while the focus/emergency overlay is visible.

Type:
  • boolean
Source:

planTasks :Array.<Object>

Plan task list — each item: { id, text, status, tag, date, [billable], [notionUrl], [emoji], [checkpoints], [parentId], [priority] }

Type:
  • Array.<Object>
Source:

wipWarnDismissed

Whether the WIP-over warning banner has been dismissed this render cycle.

Source:

Methods

_heroBindCatPicker(wrap)

Binds open/close/select keyboard and pointer events on a .hero-cat-wrap element.

Parameters:
Name Type Description
wrap HTMLElement

The .hero-cat-wrap container.

Source:

_heroCancelStoppedTimer()

Cancels the auto-dismiss timer (called by Undo / Done buttons).

Source:

_heroCatSelect(newTag)

Updates the active entry's category, persists, and re-renders.

Parameters:
Name Type Description
newTag string

Category ID to apply.

Source:

_heroFillIdle()

Updates the idle panel: logged-today total and last-session time.

Source:

_heroFillPaused()

Updates the paused panel with the frozen clock and task details.

Source:

_heroFillRunning()

Updates the running panel: category dot + task title + started-at sub-line.

Source:

_heroFillStopped()

Updates the stopped panel with the session summary.

Source:

_heroHandleDone()

Dismiss the stopped confirmation panel immediately (same as auto-dismiss).

Source:

_heroHandleStart()

Handles the "▶ Start tracking" button. Uses the composer input if it has text; otherwise focuses the plan input.

Source:

_heroHandleUndo()

Undo the just-stopped entry: remove it from entries and optionally restart the timer if the entry had been running (i.e. it had no prior tsEnd).

Source:

_heroLastNoteText(entryId) → {string}

Returns "↳ last note X ago" text for the most recent session-note on an entry, or an empty string when no session notes have been added yet.

Parameters:
Name Type Description
entryId string

ID of the active log entry.

Source:
Returns:
Type
string

_heroRenderRecentChips()

Builds the recent-task chip strip in the idle panel. Shows up to 3 distinct recent entries with their category dot.

Source:

_heroSessionCount(entry) → {number}

Returns the number of distinct time entries today for the same task text.

Parameters:
Name Type Description
entry Object
Source:
Returns:
Type
number

_heroSetCategory(elId, tag, interactiveopt)

Fills a category display cell with the dot + label (and optional caret/picker).

Parameters:
Name Type Attributes Default Description
elId string

ID of the .hero-task-category element.

tag string

Category ID.

interactive boolean <optional>
false

When true, renders a caret button and picker panel.

Source:

_heroShowPanel(id, visible)

Parameters:
Name Type Description
id string

Element ID.

visible boolean

Whether to show the element.

Source:

_heroStartFromChip(text, tag)

Starts tracking from a recent-chip click. Re-uses the existing entry (no duplicate) and starts the timer.

Parameters:
Name Type Description
text string

Task description.

tag string

Category ID.

Source:

_qcActivateRow(rowId, text, tag, isActive)

Starts or switches to a task from the quick-capture list. If the row is already the active timer, just closes the modal. For plan-task rows a fresh time entry is created.

Parameters:
Name Type Description
rowId string

Row ID from the data attribute.

text string

Task description.

tag string

Category ID.

isActive boolean

Whether this is the currently-running task.

Source:

_qcBindTaskListEvents(el)

Attaches click listeners to task-row action buttons and their parent rows. Separated from rendering so each has a single responsibility.

Parameters:
Name Type Description
el HTMLElement

The #qcTaskList container element.

Source:

_qcBuildTaskGroups(searchLower, todayKey) → {Object}

Collects and deduplicates the three task groups for the current filter state. Pure data function — performs no DOM operations.

Parameters:
Name Type Description
searchLower string

Lower-cased search string; empty string means no filter.

todayKey string

Date key for today in YYYY-MM-DD format.

Source:
Returns:
Type
Object

_qcLogOnly()

Handles the "Log without tracking" footer button and Enter keypress.

Parses inline shorthand tokens from the input before creating the entry: #<cat> overrides category, !<sig> sets the signifier, ><date> sets the entry date (today / tomorrow / YYYY-MM-DD / weekday).

  • Non-empty text after token stripping → creates a log entry (no timer) and closes.
  • Only tokens, no text → refocuses the input so the user adds a description.
  • Completely empty input → closes and focuses the ad-hoc row in the time log.
Source:

_qcRenderAll()

Re-renders all dynamic regions of the quick-capture modal.

Source:

_qcRenderCatChips()

Renders the "All" chip plus one chip per category. The active chip is highlighted; clicking a chip filters the task list.

Source:

_qcRenderRunningStrip()

Shows or hides the running strip. When a timer is active the strip displays the current task and elapsed time. When idle the strip is hidden and the pulsing-dot class is removed.

Source:

_qcRenderTaskList()

Orchestrates data collection, rendering, and event binding for the task list. Delegates each concern to a single-purpose helper.

Source:

_qcRenderTokenPreview(parsed)

Renders colored pill badges below the search input for any recognised inline tokens in the current input value. Hides the preview container when no tokens are active (e.g. on modal open or after the field is cleared).

Parameters:
Name Type Description
parsed Object

Result of parseRapidTokens() for the current raw input value.

Source:

_qcStartTick()

Starts a 1-second interval to update the elapsed-time label in the running strip.

Source:

_qcStopTick()

Clears the running-strip interval.

Source:

_qcTaskListHtml(groups, search) → {string}

Renders the task list HTML string from pre-built group data. Receives all inputs as parameters — performs no DOM or module-state reads.

Parameters:
Name Type Description
groups Object
search string

Original (un-lowercased) search string for the empty-state message.

Source:
Returns:

HTML string ready for assignment to el.innerHTML.

Type
string

_qcTaskRowHtml(rowId, text, cat, isActive) → {string}

Returns the HTML for one task row in the task list. The action button is opacity-0 and revealed on row hover via CSS.

Parameters:
Name Type Description
rowId string

Unique row key: entry ID or 'plan:' + plan-task ID.

text string

Task/entry description text.

cat Object

Resolved category.

isActive boolean

True when this row matches the currently-running entry.

Source:
Returns:

HTML string.

Type
string

_qcUpdateElapsed()

Updates only the elapsed-time label; called every second by the ticker.

Source:

activeTimerDurationMs(entry) → {number}

Returns the effective tracked duration (ms) of an active-timer entry, honouring pause state — matches the formula used by renderFlowHeader so the strip bar and Flow-view duration freeze while paused.

Parameters:
Name Type Description
entry object
Source:
Returns:

0 if no timer is active for this entry.

Type
number

addEntry(withTimer)

Creates a new log entry from the capture input's current value. Optionally starts the timer on the new entry (withTimer = true), in which case any running timer is stopped first and the matching plan task is auto-promoted to "in progress".

Parameters:
Name Type Description
withTimer boolean

If true, start the timer on the new entry.

Source:

addLogNote()

Reads the note input, appends a note to logNotes, persists, and re-renders.

Source:

addPlanTask() → {void}

Reads the plan-input field and adds a new "todo" task to today's plan. Inherits the currently selected tag and that category's billable default. No-ops if the input is empty.

Source:
Returns:
Type
void

(async) addTaskToNotion(task) → {Promise.<string>}

Adds a work-log task to Notion as a child page under the matching project. The project is looked up server-side by matching the task's category label to a Notion project's Epic field. Uses /api/notion-add-task (Notion REST API, no AI).

Parameters:
Name Type Description
task Object

Plan task object with at least text and tag.

Source:
Throws:

If the API call fails or no URL is returned.

Type
Error
Returns:

The URL of the newly created Notion page.

Type
Promise.<string>

applyTime(baseTsMs, timeStr) → {number}

Replaces the hours/minutes of a base timestamp with values parsed from a "HH:MM" string, returning the resulting timestamp in milliseconds.

Parameters:
Name Type Description
baseTsMs number

Base Unix timestamp (ms) that supplies the date.

timeStr string

Time string in "HH:MM" format.

Source:
Returns:

New Unix timestamp (ms) with the updated time.

Type
number

autoCarryTasks() → {number|undefined}

Carries unfinished plan tasks from past days into today — runs once per day (guarded by a localStorage flag). Deduplicates by text, preserving the most recent past status and status-comment history. Checkpoints are carried forward with done reset to false for a fresh day.

Source:
Returns:

Number of tasks newly carried, or undefined if carry has already run today.

Type
number | undefined

billBtnHtml(t, status) → {string}

Builds the billable toggle button HTML for a task row. Returns empty string for pending/blocked/upcoming tasks where billing is irrelevant.

Parameters:
Name Type Description
t Object

The plan task.

status string

The task's current status.

Source:
Returns:

HTML button element, or ''.

Type
string

bindBoardColumnDnD()

Makes each rendered board card draggable and wires its dragstart/dragend. Called once per renderPlan() cycle after columns are populated. Static column drop-zone listeners are set up once in initBoardColumnDnD().

Source:

bindPlanEvents(lists)

Binds all plan list event handlers after each render.

Parameters:
Name Type Description
lists Array.<HTMLElement>

Column list elements (To Do, In Progress, Done).

Source:

bindSignifierClicks()

Attaches click and keyboard listeners to all .esig elements after a render.

Source:

buildBillableSummaryParts(mergedEntries, getCatLabel) → {Array.<string>}

Builds the parts of the pasteable billable summary from merged billable entries. Categorised tasks are grouped as Category (task1, task2); uncategorised tasks (no tag or other) are listed bare. Order of first appearance is preserved and duplicate task names are de-duplicated.

Parameters:
Name Type Description
mergedEntries Array.<Object>

Output of mergeAdjacentEntries.

getCatLabel function

Resolves a category key to its display label. Injected so this function stays free of global state.

Source:
Returns:

Summary parts, ready to be joined with , .

Type
Array.<string>

(async) buildBridge(meeting, expandedEl, bridgeBtn, onDismiss) → {Promise.<void>}

Determines the next task to transition to and delegates to fetchBridge. If multiple tasks are in-flight the user picks from a list; a single in-progress task is auto-selected; the only remaining task is auto-selected.

Parameters:
Name Type Description
meeting Object

The meeting that just ended.

expandedEl HTMLElement

Container for the bridge content.

bridgeBtn HTMLElement

"Build bridge" button (disabled during fetch).

onDismiss function

Callback to dismiss the banner.

Source:
Returns:
Type
Promise.<void>

buildDailyLogItems(dateKey) → {Array.<{ts: number, type: string, entryId: (string|undefined), parentEntryId: (string|undefined), color: string, text: string, sub: string}>}

Builds a chronologically sorted array of feed items for the Log view. Merges time entries, log notes, and task status comments for the given day.

Item types:

  • 'entry' — a time-tracked entry; includes entryId.
  • 'note' — a freeform log note; text is wrapped in <em>.
  • 'session-note' — a note attached to a running/completed entry; includes parentEntryId. Renderers nest these inside their parent entry row rather than as standalone timeline rows.
  • 'task' — a plan-task status comment.
Parameters:
Name Type Description
dateKey string

YYYY-MM-DD date string.

Source:
Returns:
Type
Array.<{ts: number, type: string, entryId: (string|undefined), parentEntryId: (string|undefined), color: string, text: string, sub: string}>

buildSessionNotesHtml(notes) → {string}

Builds the HTML fragment for a list of session-notes nested under a parent entry row. Returns an empty string when there are no notes.

Parameters:
Name Type Description
notes Array.<object>

Session-note items for one parent entry.

Source:
Returns:

HTML string, or '' if notes is empty.

Type
string

calAccountLabel(account) → {string|null}

Resolves a human-readable account label for an Outlook calendar account. The PowerShell server sends the raw DisplayName which may be an email address, a display name, or free-form company text. Tries three strategies in order: exact match, email domain extraction, and substring match.

Parameters:
Name Type Description
account string | null

Raw Outlook account identifier.

Source:
Returns:

Display label (e.g. "LähiTapiola"), or null if unknown.

Type
string | null

calcMonthSummaryStats(allEntries, monthPrefix, isBillable) → {Object}

Computes monthly summary statistics from a flat entries array. Pure: takes its own data dependency, no DOM, no module globals. Excludes entries with no tsEnd (still running) or signifier === 'cancelled'.

Parameters:
Name Type Description
allEntries Array.<Object>

The full entries array to filter.

monthPrefix string

Date prefix YYYY-MM used to select entries.

isBillable function

Predicate identifying billable entries; the caller supplies the project's isEntryBillable.

Source:
Returns:
Type
Object

calcMonthTaskCounts(allTasks, monthPrefix) → {Object}

Computes open / done / migrated task counts for a given month. Pure. _migrated (programmatic) and signifier === 'migrated' (BuJo marker) both count toward the migrated total.

Parameters:
Name Type Description
allTasks Array.<Object>

The full plan-tasks array.

monthPrefix string

Date prefix YYYY-MM used to select tasks.

Source:
Returns:
Type
Object

calcStreak() → {number}

Counts consecutive days with at least one logged entry, looking backwards from yesterday. Today is excluded so the streak only increments once the day has been completed.

Source:
Returns:
Type
number

(async) callClaudeWithNotion(prompt, optsopt) → {Promise.<string>}

Calls the Claude API with a Notion MCP server attached, via the local proxy at /api/notion-ai (API keys never exposed to the browser). Used for the URL-bookmarking form — task imports use addTaskToNotion instead.

Parameters:
Name Type Attributes Description
prompt string

User prompt text.

opts Object <optional>

Optional overrides (model string, maxTokens number).

Source:
Throws:

If the API returns a non-OK status.

Type
Error
Returns:

The concatenated text content of the response.

Type
Promise.<string>

carryMigTask(task)

Duplicates the task into next month (first day) and marks original as migrated.

Parameters:
Name Type Description
task Object
Source:

checkBlockNotifications()

Checks all of today's time blocks and acts on ones that have just become active:

  • Meeting blocks: auto-starts a log entry and timer at the scheduled start time.
  • Task blocks: prompts the user to switch/start within a 3-minute window. Each block is only acted on once (tracked in notifiedBlocks). No-ops when not viewing today.
Source:

checkChime(elapsedMs)

Fires an audible chime if the elapsed time has crossed a configured interval boundary since the last chime. No-ops when the timer is paused.

Parameters:
Name Type Description
elapsedMs number

Elapsed time in milliseconds.

Source:

checkNewDay()

Formerly showed a "new day" banner prompting the user to export yesterday's log. The banner was removed — end-of-day modal handles exports now. Kept as a no-op stub to avoid removing the call sites.

Source:

checkPomoWeeklyClear()

Clears the pomodoro log when a new ISO week begins. Compares the stored week key against the current ISO week; if they differ, the log is removed and the new week key is saved.

Source:

(async) clearDirHandle() → {Promise.<void>}

Clears the persisted FSA directory handle from both IndexedDB and the in-memory cache so future exports fall back to browser downloads.

Source:
Returns:
Type
Promise.<void>

closeAllEditors()

Closes every open inline time-editor panel and restores the display spans.

Source:

closeMigration()

Closes the migration overlay.

Source:

closeRapid()

Hides the quick-capture overlay and stops the elapsed ticker.

Source:

closeTrackerForm() → {void}

Hides the new-tracker form and resets the open-state flag.

Source:
Returns:
Type
void

commitBannerNote()

Saves a timestamped note attached to the currently-active timer entry. The note is stored in logNotes (type: 'session-note') and rendered nested under its parent entry in the flow/log views, rather than as a standalone time-tracked entry. No-ops when there is no active timer or the note is empty.

Source:

computeDayBounds(dayEntries, timedEntries, opts) → {Object}

Computes the day's start and end timestamps for the plaintext export header.

Start: the supplied day start (today only) or, failing that, the earliest entry start. End: the latest tracked end among timed entries, extended by the active timer's effective end so "Ended:" reflects work still in progress.

Pure: all environmental inputs (day start, the active timer, the current time) are injected via opts so the function can be unit-tested without globals.

Parameters:
Name Type Description
dayEntries Array.<Object>

All entries for the viewed day.

timedEntries Array.<Object>

Entries with a real tracked duration (tsEnd).

opts Object

Injected environment.

Properties
Name Type Description
isViewingToday boolean

Whether the viewed day is today.

dayStart number | null

Configured day-start ts, or null if not today.

activeTimer Object | null

The running/paused timer, or null.

now number

Current time in ms (Date.now()).

Source:
Returns:

Day bounds in ms.

Type
Object

config(cfg)

Logs a snapshot of runtime configuration at startup in a collapsed group. Called once by 07-lifecycle.js after state is loaded.

Parameters:
Name Type Description
cfg Object

Key/value pairs to display (e.g. version, entry count).

Source:

cycleSignifier(entryId)

Advances an entry's signifier one step through SIG_CYCLE and persists the change. Wraps from the last value back to null (no signifier).

Parameters:
Name Type Description
entryId string

ID of the entry to update.

Source:

debug(msg, dataopt)

Emits a debug-level message, visible only when DevTools verbose level is on.

Parameters:
Name Type Attributes Description
msg string

Human-readable message.

data * <optional>

Optional value to attach to the log line.

Source:

dk(d) → {string}

Formats a Date as YYYY-MM-DD using local calendar date. Uses local date components (getFullYear / getMonth / getDate) so the returned string always matches the date the user sees on their clock, regardless of timezone.

Parameters:
Name Type Description
d Date

Date to format.

Source:
Returns:

e.g. '2026-05-26'

Type
string
Example
dk(new Date(2026, 4, 26, 12, 0, 0))  // → '2026-05-26'  (noon local)
dk(new Date(2026, 11, 31, 23, 59, 0)) // → '2026-12-31' (11 PM local)
dk(new Date(2026, 0, 1, 0, 0, 0))    // → '2026-01-01'  (midnight local)

drawPomoSegments()

Redraws all pomodoro SVG segments to reflect the current remaining time. Each minute is a sector; filled sectors fade as time elapses.

Source:

dropMigTask(task)

Archives (drops) the task by marking it done and migrated.

Parameters:
Name Type Description
task Object
Source:

durLabel(tsStart, tsEnd) → {string}

Builds an HTML <span class="etime-dur"> containing the human-readable duration between two timestamps. Returns an empty string if the duration is zero or negative.

Parameters:
Name Type Description
tsStart number

Start Unix timestamp (ms).

tsEnd number

End Unix timestamp (ms).

Source:
Returns:

HTML string, or '' if duration ≤ 0.

Type
string

ensureDayStarted() → {void}

Records start-of-day silently (no backup-restore dialog) if the day has not already been started. Called automatically when the first task timer begins.

Source:
Returns:
Type
void

enterEmergency()

Activates focus/emergency mode: hides the main UI, shows the overlay, moves the pomodoro section into the overlay, and focuses the next-action input. The previously saved next-action note is restored if one exists for the active entry.

Source:

eodKey(dayopt) → {string}

Returns the localStorage key for a given day's end-of-day timestamp.

Parameters:
Name Type Attributes Default Description
day Date <optional>
viewDate

Day to key by; defaults to the day in view.

Source:
Returns:

Key in the format wl_eod_YYYY-MM-DD.

Type
string

error(msg, dataopt)

Emits an error — something that broke or produced an incorrect result.

Parameters:
Name Type Attributes Description
msg string

Human-readable message.

data * <optional>

Optional value to attach to the log line.

Source:

escHtml(s) → {string}

Escapes a string for safe insertion as HTML text content.

Parameters:
Name Type Description
s string

Raw string to escape.

Source:
Returns:

HTML-escaped string safe for insertion into the DOM.

Type
string
Example
escHtml('<b>bold</b>')   // → '&lt;b&gt;bold&lt;/b&gt;'
escHtml('a & b')         // → 'a &amp; b'
escHtml('"quoted"')      // → '&quot;quoted&quot;'
escHtml(42)              // → '42'

exitEmergency()

Deactivates focus/emergency mode: restores the main UI, saves the next-action note, moves the pomodoro section back to its normal position, and auto-expands the active task's checkpoint list so the user can pick up where they left off.

Source:

exportBackup()

Exports a full JSON backup of all application state: entries, categories, plan tasks, time blocks, pomodoro log, dev log, distractions, and hidden quick-pick items. Triggers a file download or writes to the save folder.

Source:

exportTxt()

Exports the currently viewed day's log as a plaintext file. Groups entries by category and task, includes a header with day start/end times and tracked time totals, and appends a pasteable billable summary. Writes to the user's chosen save folder via the File System Access API, or falls back to a browser download.

Source:

(async) fetchAndRenderCalendar() → {Promise.<void>}

Fetches today's meetings from the local PowerShell proxy (/api/calendar), caches the result, filters out user-hidden meetings, and calls renderCalStrip. Logs a warning and shows a fallback message on error.

Source:
Returns:
Type
Promise.<void>

(async) fetchBridge(meeting, task, expandedEl, bridgeBtn, onDismiss) → {Promise.<void>}

Calls the Claude API via /api/ai to generate 3 concrete physical steps for transitioning from the ended meeting to the next task. Displays the result in expandedEl; falls back to copying the prompt to the clipboard on API error.

Parameters:
Name Type Description
meeting Object

The meeting that just ended.

task Object

The next plan task to transition to.

expandedEl HTMLElement

Container for the bridge content.

bridgeBtn HTMLElement

"Build bridge" button (disabled during fetch).

onDismiss function

Callback to dismiss the banner.

Source:
Returns:
Type
Promise.<void>

fetchCalendarEvents()

Fetches today's Finnish flag days, public holidays, and notable days from the Nimipäivärajapinta Typesense API, displaying the first match in #liveFlagDay. If today has no event, shows the next upcoming one. Falls back to the hardcoded FLAG_DAYS_FIXED list if the API is unreachable.

Source:

fetchNameday()

Fetches today's Finnish and Swedish name days from the Nimipäivärajapinta API and renders them in #liveNameday. Falls back to an "API unavailable" note on error.

Source:

fetchWeather()

Fetches current weather, hourly precipitation probability, and sunrise/sunset data from the Open-Meteo API for the configured location (WEATHER_LAT, WEATHER_LON) and populates #liveWeather, #liveRain, and #liveSunrise. No-ops gracefully on file: protocol or network error.

Source:

findLargestGap(dateKey) → {Object|null}

Finds the largest untracked gap (≥ 15 min) today, including gaps between consecutive completed entries AND the trailing gap from the most recent entry's end to now (which is often the most actionable). Returns null for past days — only actionable today.

Parameters:
Name Type Description
dateKey string

YYYY-MM-DD.

Source:
Returns:
Type
Object | null

flatSort(tasks) → {Array.<Object>}

Sorts a flat list of plan tasks by status order and priority, inserting child tasks immediately after their parent. Tasks matching the currently running timer text are sorted first. Orphaned children (whose parent has been deleted or moved) are appended at the end.

Parameters:
Name Type Description
tasks Array.<Object>

Array of plan task objects to sort.

Source:
Returns:

New sorted array with children interleaved after parents.

Type
Array.<Object>

fmtAgo(ts, nowopt) → {string}

Formats a past timestamp as a relative "ago" string for the last-note reference line. Uses an injected now parameter so it is fully unit-testable without mocking Date.now.

Parameters:
Name Type Attributes Description
ts number

Unix timestamp in milliseconds of the past event.

now number <optional>

Current time in ms; defaults to Date.now().

Source:
Returns:

'just now' | 'X min ago' | 'Xh ago'

Type
string
Example
fmtAgo(Date.now() - 30000)          // → 'just now'
fmtAgo(Date.now() - 2 * 60000)      // → '2 min ago'
fmtAgo(Date.now() - 90 * 60000)     // → '1h ago'

fmtDur(ms) → {string}

Formats a duration in milliseconds as a compact human-readable string ("Xh Ym"). Used throughout the UI for tracked-time display in the timeline, chart, and plan.

Parameters:
Name Type Description
ms number

Duration in milliseconds.

Source:
Returns:

e.g. '1h 30m', '45m', '2h'

Type
string
Example
fmtDur(0)                  // → '0m'
fmtDur(45 * 60 * 1000)     // → '45m'
fmtDur(90 * 60 * 1000)     // → '1h 30m'
fmtDur(120 * 60 * 1000)    // → '2h'

fmtDurLong(ms) → {string}

Formats a duration in milliseconds as a human-readable string using the long "min" suffix. Used in plaintext exports where readability matters more than compactness.

Parameters:
Name Type Description
ms number

Duration in milliseconds.

Source:
Returns:

e.g. '1h 30min', '45min', '2h'

Type
string
Example
fmtDurLong(0)                 // → '0min'
fmtDurLong(45 * 60 * 1000)    // → '45min'
fmtDurLong(90 * 60 * 1000)    // → '1h 30min'
fmtDurLong(120 * 60 * 1000)   // → '2h'

fmtElapsed(ms) → {string}

Formats a duration in milliseconds as a compact time string.

Parameters:
Name Type Description
ms number

Duration in milliseconds.

Source:
Returns:

'MM:SS' for durations under an hour; 'HH:MM:SS' otherwise.

Type
string
Example
fmtElapsed(0)              // → '00:00'
fmtElapsed(90 * 1000)      // → '01:30'
fmtElapsed(3600 * 1000)    // → '01:00:00'
fmtElapsed(5461 * 1000)    // → '01:31:01'

fmtHm(ts) → {string}

Formats a Unix timestamp (ms) as HH:MM in local time.

Parameters:
Name Type Description
ts number
Source:
Returns:
Type
string

fmtLabel(d) → {string}

Returns a human-readable day label: 'today', 'yesterday', or a short locale date string.

Parameters:
Name Type Description
d Date
Source:
Returns:
Type
string

fmtMD(d) → {string}

Formats a Date as a zero-padded "MM-DD" string used as flag-day map keys.

Parameters:
Name Type Description
d Date

The date to format.

Source:
Returns:

e.g. "06-04" for the 4th of June.

Type
string

fmtTime(ts) → {string}

Formats a Unix timestamp as HH:MM in 24-hour local time.

Parameters:
Name Type Description
ts number

Unix timestamp in milliseconds.

Source:
Returns:

e.g. '09:30'

Type
string
Example
fmtTime(new Date('2026-05-25T09:05:00').getTime()) // → '09:05'
fmtTime(new Date('2026-05-25T14:30:00').getTime()) // → '14:30'

focusTabAt(nextIndex)

Selects the view at index nextIndex in TF_VIEWS, focuses its tab button, and re-renders. Shared by the keyboard handler in initTodayFlow().

Parameters:
Name Type Description
nextIndex number
Source:

formatGroupedLines(catOrder, catGrouped, fmtDuration, getCatLabel) → {Array.<string>}

Renders the grouped-by-category structure into indented text lines: one line per category (with its total), each followed by its indented task lines.

Pure: the duration formatter and category-label resolver are injected so this function has no dependency on global state and can be unit-tested directly.

Parameters:
Name Type Description
catOrder Array.<string>

Category keys in display order.

catGrouped Object

Grouping produced by groupEntriesByCategory.

fmtDuration function

Formats a duration in ms (e.g. fmtDurLong).

getCatLabel function

Resolves a category key to its label.

Source:
Returns:

The body lines for the export file.

Type
Array.<string>

getCat(id) → {Object}

Returns the category object for id, falling back to 'other' if not found. The returned colour is always sanitised through safeCssColor.

Parameters:
Name Type Description
id string

Category ID.

Source:
Returns:
Type
Object

getDayStart(dayopt) → {number|null}

Retrieves a given day's recorded start-of-day timestamp from localStorage.

Parameters:
Name Type Attributes Default Description
day Date <optional>
viewDate

Day to read; defaults to the day in view.

Source:
Returns:

Unix timestamp (ms), or null if not yet set.

Type
number | null

getElapsedMs() → {number}

Returns the total elapsed milliseconds for the active timer. Accounts for accumulated time from previous pause/resume cycles. Returns 0 if no timer is active.

Source:
Returns:

Elapsed time in milliseconds.

Type
number

getEodTs(dayopt) → {number|null}

Retrieves a given day's recorded end-of-day timestamp from localStorage.

Parameters:
Name Type Attributes Default Description
day Date <optional>
viewDate

Day to read; defaults to the day in view.

Source:
Returns:

Unix timestamp (ms), or null if not yet set.

Type
number | null

getFlagDays(year) → {Object.<string, string>}

Returns an object mapping "MM-DD" strings to Finnish flag-day names for the given year. Combines fixed dates with computed moveable feasts.

Parameters:
Name Type Description
year number

The full 4-digit year.

Source:
Returns:

Map of "MM-DD" → event name.

Type
Object.<string, string>

getFlowView() → {'flow'|'log'|'blocks'|'month'}

Returns the persisted view preference, defaulting to 'flow'.

Source:
Returns:
Type
'flow' | 'log' | 'blocks' | 'month'

getHandoffNote(entryText) → {string|null}

Retrieves the stored handoff note for a given entry text. The lookup is case-insensitive and trims whitespace.

Parameters:
Name Type Description
entryText string

The entry text to look up.

Source:
Returns:

The stored note, or null if none exists.

Type
string | null

getISOWeek(d) → {number}

Returns the ISO 8601 week number for a given date.

Parameters:
Name Type Description
d Date

The date to evaluate.

Source:
Returns:

ISO week number (1–53).

Type
number

getIterationExpiry(completedDay) → {string|null}

Returns the first iteration expiry date that is strictly later than completedDay, or null if none is configured beyond that date.

Parameters:
Name Type Description
completedDay string

Completion date in "YYYY-MM-DD" format.

Source:
Returns:

The next expiry date, or null.

Type
string | null

getMeetingKey(m) → {string}

Returns a stable string key for a meeting used to deduplicate bridge banners.

Parameters:
Name Type Description
m Object

Meeting object.

Source:
Returns:
Type
string

getMigrationRecord() → {Object}

Returns the migration completion record (map of YYYY-MM → boolean).

Source:
Returns:
Type
Object

getMoonData(date) → {Object}

Calculates moon phase, illumination percentage, and zodiac sign for a date using a simplified version of the Meeus algorithm.

Parameters:
Name Type Description
date Date

The date to evaluate.

Source:
Returns:

emoji = phase emoji, phase = phase name, illum = illumination (%), sign = [symbol, name] of the current zodiac sign.

Type
Object

getReflectionForDate(dateKey) → {Object|null}

Returns the stored reflection record for a given day, or null if none exists.

Parameters:
Name Type Description
dateKey string

YYYY-MM-DD date string.

Source:
Returns:
Type
Object | null

(async) getSavedDir() → {Promise.<(FileSystemDirectoryHandle|null)>}

Retrieves the previously granted File System Access directory handle from IndexedDB (with an in-memory cache).

Source:
Returns:

The handle, or null if none saved.

Type
Promise.<(FileSystemDirectoryHandle|null)>

getSeenEnded() → {Set.<string>}

Returns the set of meeting keys (subject|start) that have already triggered a bridge banner in this session, loaded from localStorage.

Source:
Returns:
Type
Set.<string>

getViewLocation() → {string}

Resolves the work location for the currently viewed day.

Source:
Returns:

A location id present in WORK_LOCATIONS.

Type
string

groupEntriesByCategory(dayEntries) → {Object}

Groups a day's log entries by category and, within each category, by task (case-insensitively), preserving first-seen order. Accumulates tracked time (where tsEnd > ts) per task and per category.

Pure data transform — reads only entry fields and performs no formatting, so the caller decides how to render the durations and labels.

Parameters:
Name Type Description
dayEntries Array.<Object>

Entries for the viewed day.

Source:
Returns:

catOrder is the list of category keys in first-seen order; catGrouped[catKey] is { totalMs, tasks: { [taskKey]: { label, totalMs, hasTime } }, taskOrder }.

Type
Object

groupTasksByColumn(viewKey) → {Object}

Partitions today's plan tasks into the three kanban column groups.

Parameters:
Name Type Description
viewKey string

Date key (YYYY-MM-DD) for the current view.

Source:
Returns:
Type
Object

handleMoodSelect(mood, icon)

Handles a mood selection from the banner dropdown. Records a distraction or parked thought as an entry (for distracted/parked moods), triggers the hook panel for 'interesting', and sets focus mode for 'focus'. Closes the panel afterwards.

Parameters:
Name Type Description
mood string

One of 'distracted' | 'parked' | 'focus' | 'interesting'.

icon string

Emoji icon for the mood.

Source:

heroEnterStopped(entry)

Called by stopTimer() just before activeTimer is cleared. Shows the stopped confirmation panel and arms the 6s auto-dismiss.

Parameters:
Name Type Description
entry Object

The log entry that was just stopped.

Source:

heroGetState() → {'idle'|'running'|'paused'|'stopped'}

Derives the current hero state from module-level timer variables.

Source:
Returns:
Type
'idle' | 'running' | 'paused' | 'stopped'

heroUpdateClock()

Updates the running-state elapsed clock without a full render. Only touches the clock element so the DOM churn stays minimal.

Source:

hideHandoffInput()

Hides and clears the handoff-note text field.

Source:

(async) importBackup(file) → {Promise.<void>}

Restores application state from a JSON backup file previously created by exportBackup. Reads the file, validates its structure via validateBackupFile, asks the user to confirm, writes all arrays to their localStorage keys, then reloads the page so state is re-initialised cleanly from the restored data.

Assumption: import is a full replace, not a merge. All data currently in the affected localStorage keys is overwritten after the user confirms. If selective-date merging is ever needed, add a merge mode option here and update the confirmation dialog accordingly.

Parameters:
Name Type Description
file File

The .json backup file selected by the user.

Source:
Returns:
Type
Promise.<void>

info(msg, dataopt)

Emits an informational message.

Parameters:
Name Type Attributes Description
msg string

Human-readable message.

data * <optional>

Optional value to attach to the log line.

Source:

initBannerControls()

Binds all interactive controls on the V5 timer banner: mood dropdown, quick-note input, and Break / Lunch / Meeting utility pills. Called once from 07-lifecycle.js after DOMContentLoaded is guaranteed.

Source:

initBoardColumnDnD()

Registers dragover, dragleave, and drop listeners on the three static board column lists. Called exactly once on DOMContentLoaded from 07-lifecycle.js. Card draggable wiring (re-rendered each cycle) stays in bindBoardColumnDnD().

Source:

initHero()

Binds all Hero Card button events. Called once from DOMContentLoaded in 07-lifecycle.js.

Source:

initLocation() → {void}

Binds the location toggle button. Called exactly once from the boot sequence in 07-lifecycle.js; there is no re-invocation path, so the click listener is attached without a guard. If a future caller invokes this more than once, add a removeEventListener (or an "already bound" flag) first to avoid duplicate handlers. Safe to call when the button is missing.

Source:
Returns:
Type
void

initMigration()

Initialises the migration overlay: wires close button and optionally shows a last-day-of-month banner once per month.

Source:

initMonthlyLog() → {void}

Bootstraps the Monthly Log feature. The Monthly Log is now the "Month" tab in Today's Flow; its visibility and rendering are driven by renderTodayFlow(). Month sync happens in initTodayFlow() when the Month tab is clicked. This function is kept as a no-op so the call site in 07-lifecycle.js does not need to change.

Source:
Returns:
Type
void

initPomo(mins)

Initialises (or re-initialises) the pomodoro timer for the given duration. Clears any running interval, resets state, and highlights the matching duration button.

Parameters:
Name Type Description
mins number

Session duration in minutes.

Source:

initRapid()

Registers all event listeners for the quick-capture overlay. Called once on DOMContentLoaded.

Source:

initSprints() → {void}

Registers all sprint UI event listeners: the sprint mode button, start, cancel, and Enter-key shortcut on the intention input. Called once on DOMContentLoaded.

Source:
Returns:
Type
void

initTodayFlow()

Binds the static listeners exactly once on DOMContentLoaded:

  • Log-note input/button (static HTML, never recreated)
  • Segmented-control click + keyboard nav, delegated off the stable #tfHeader container so we survive its innerHTML being rewritten by every renderFlowHeader() call. Avoids the listener-accumulation bug that occurred when binding happened inside render functions.
Source:

initTrackers() → {void}

Bootstraps the Trackers feature: performs the initial render and wires up the "+ New" button to toggle the tracker form open/closed. Called once on DOMContentLoaded.

Source:
Returns:
Type
void

isEntryBillable(entry) → {boolean}

Determines whether a log entry is billable, using a three-tier lookup:

  1. The entry's own billable flag (if explicitly set).
  2. The matching plan task's billable flag.
  3. The category default.

Assumption: entries and tasks where billable is undefined are treated as billable by default. This preserves backward compatibility with data created before the billable flag was introduced — older entries must not silently disappear from billing reports after an upgrade. If the default should change to non-billable, a migration of existing localStorage data is required (see DATA.md § wl_entries).

Parameters:
Name Type Description
entry Object

Log entry object.

Source:
Returns:

True if the entry should be counted as billable.

Type
boolean

isToday(d) → {boolean}

Returns true if d falls on today's calendar date (UTC).

Parameters:
Name Type Description
d Date
Source:
Returns:
Type
boolean

jiraTicketHtml(text) → {string}

Returns HTML for a task text string, converting any leading Jira ticket key (e.g. AITO-1234) into a clickable link. The remainder of the text is HTML-escaped and appended.

Parameters:
Name Type Description
text string

Raw task text, possibly starting with a Jira key.

Source:
Returns:

HTML string.

Type
string

lastWeekday(year, month, weekday) → {Date}

Returns the date of the last occurrence of a weekday in the given month.

Parameters:
Name Type Description
year number

Full 4-digit year.

month number

Month (1 = January … 12 = December).

weekday number

Day of week (0 = Sunday … 6 = Saturday).

Source:
Returns:
Type
Date

load()

Loads all persistent state from localStorage into module-level variables. Invalid records are dropped per-item (rather than rejecting entire arrays) and any drops are reported via wlLog.warn so data-quality issues are visible in DevTools rather than silently disappearing. Falls back to the last snapshot if entries are missing from primary storage.

Source:

loadBlocks()

Loads time blocks from localStorage into blocks, filtering invalid entries. Drops are reported via wlLog.warn so data-quality issues are visible in DevTools. Applies a one-time migration to shift existing block slots by +2 when the time-block grid start time changed from 08:00 to 07:00.

Source:

loadExpiryDates()

Loads iteration expiry dates from localStorage into _expiryDates. Seeds localStorage with EXPIRY_SEED on first run.

Source:

loadLocationMap() → {Record.<string, string>}

Reads the stored location map from localStorage. Returns an empty map (and logs a warning) if the value is missing or corrupt, so a single bad write can never break the header render.

Source:
Returns:

Date-key → location-id map.

Type
Record.<string, string>

loadPlan() → {void}

Loads plan tasks from localStorage into planTasks, filtering out invalid entries via validPlanTask. Drops are reported via wlLog.warn so data-quality issues are visible in DevTools. Resets to empty array on parse error.

Source:
Returns:
Type
void

loadReflection()

Loads reflection data from localStorage into _reflData.

Source:

loadSprintLog() → {void}

Loads sprint history from localStorage into the module-level sprintLog array. Falls back to an empty array and logs a warning on parse failure.

Source:
Returns:
Type
void

loadTrackers() → {void}

Loads the trackers array from localStorage into the module-level trackers variable. Falls back to an empty array and logs a warning on parse failure.

Source:
Returns:
Type
void

locationFor(map, dateKey) → {string}

Resolves the stored work location for a given day, falling back to the default when the day is unset or holds an unknown value.

Parameters:
Name Type Description
map Record.<string, string>

Date-key → location-id map.

dateKey string

Day key in YYYY-MM-DD form (see dk).

Source:
Returns:

A valid location id present in WORK_LOCATIONS.

Type
string
Example
locationFor({ '2026-06-03': 'office' }, '2026-06-03') // → 'office'
locationFor({}, '2026-06-03')                         // → 'remote'
locationFor({ '2026-06-03': 'bogus' }, '2026-06-03')  // → 'remote'

logUtilEntry(kind)

Logs a short well-known activity (break / lunch / meeting) as a new entry while keeping the active timer running. The active timer is NOT stopped so the user can resume without friction.

Parameters:
Name Type Description
kind 'break' | 'lunch' | 'meeting'

Activity type.

Source:

mergeAdjacentEntries(entries, gapMsopt) → {Array.<Object>}

Merges same-task entries that are separated by no more than gapMs into a single block, carrying the merged end time on a _end property.

Two entries merge only when they share the same task text and the same category (tag, with a missing tag normalised to other). Category is part of the key so that two adjacent entries with the same label but different categories are not collapsed — otherwise the later category would be lost from the exported billable summary, which reads tag from the merged block.

Rationale for the gap: the default 30-minute window matches the billing rounding unit — splitting a task at a gap shorter than one slot would produce two entries that each round to the same half-hour anyway, while making the summary harder to read. Input is not mutated; entries are sorted by start time first.

Parameters:
Name Type Attributes Default Description
entries Array.<Object>

Entries to merge (each with ts, optional tsEnd, text, tag).

gapMs number <optional>
1800000

Maximum gap, in ms, to bridge (default 30 min).

Source:
Returns:

New entry objects, each with a _end timestamp.

Type
Array.<Object>

mergeDevLog()

Merges the hardcoded DEV_CHANGES array into the persisted dev log in localStorage, adding only entries whose id is not already stored. Maintains chronological sort order by id.

Source:

migrateEntryDatesToLocal()

Fixes entry date fields that were stored using UTC midnight instead of the user's local calendar date.

Background: dk() previously called toISOString() (UTC). For UTC+ users (e.g., Finland, UTC+2/+3), entries logged between local midnight and 02:00–03:00 were stored under the previous day's UTC date. This migration re-derives date from the entry's ts timestamp using the now-correct local dk().

Safe to run multiple times — entries already on the correct local date are untouched.

Source:

migrateStorage()

Runs all pending schema migrations. Safe to call multiple times — migrations are skipped if the source key is absent or the destination key already has data.

Source:

mlDaysInMonth(y, m) → {number}

Returns the number of days in a given month.

Parameters:
Name Type Description
y number

Full year (e.g. 2026).

m number

Month index, 0-based (0 = January).

Source:
Returns:

Day count (28–31).

Type
number

mlHeatColor(hours) → {string}

Maps a logged-hours value to a CSS colour for the heatmap grid. Thresholds: 0h → bg3 (empty), <2h → faint blue, <5h → mid blue, <7h → strong blue, ≥7h → solid blue.

Parameters:
Name Type Description
hours number

Total logged hours for a single day.

Source:
Returns:

A CSS colour value (variable or rgba/hex string).

Type
string

mlHoursForDay(dateKey) → {number}

Sums tracked milliseconds for all non-cancelled entries on a given day.

Parameters:
Name Type Description
dateKey string
Source:
Returns:

Total hours (as a float).

Type
number

moveTaskToColumn(taskId, newStatus)

Moves a task to a new board column, updating its status and timer state. Dropping into In Progress stops any running timer, creates a new time entry, and starts tracking. Dropping into Done or To Do stops the active timer.

Parameters:
Name Type Description
taskId string

The plan task ID to move.

newStatus string

Target status: 'todo' | 'inprogress' | 'done'.

Source:

nearestWeekday(from, weekday) → {Date}

Returns the first date on or after from that falls on the given weekday.

Parameters:
Name Type Description
from Date

Start date (inclusive).

weekday number

Day of week (0 = Sunday … 6 = Saturday).

Source:
Returns:
Type
Date

nextDistinctColor() → {string}

Returns the next visually distinct colour from the palette for a new category. Falls back to golden-angle HSL generation once all palette colours are in use.

Source:
Returns:

A CSS colour string (hex or hsl).

Type
string

nextLocation(loc) → {string}

Returns the next location id when toggling, cycling through the keys of WORK_LOCATIONS. With the two presets this flips Remote ↔ Office. An unrecognised loc (indexOf → -1) is treated as "before the first" and wraps to the first location, so the toggle always recovers to a valid state.

Parameters:
Name Type Description
loc string

Current location id.

Source:
Returns:

The following location id (wraps around).

Type
string
Example
nextLocation('remote') // → 'office'
nextLocation('office') // → 'remote'
nextLocation('bogus')  // → 'remote'  (unknown input recovers to the first)

notifyPomodoroEnd() → {void}

Called from pomoDone() when the Pomodoro ring reaches zero. Fires the registered _onSprintEnd callback if one is set, then clears it so it cannot fire twice.

Source:
Returns:
Type
void

notionBtnHtml(t) → {string}

Builds the Notion send/link button HTML for a task row. Shows a link icon if already sent; send icon otherwise.

Parameters:
Name Type Description
t Object

The plan task.

Source:
Returns:

HTML button element.

Type
string

nthWeekday(year, month, weekday, n) → {Date}

Returns the date of the nth occurrence of a weekday in the given month.

Parameters:
Name Type Description
year number

Full 4-digit year.

month number

Month (1 = January … 12 = December).

weekday number

Day of week (0 = Sunday … 6 = Saturday).

n number

1-based occurrence index (1 = first, 2 = second, …).

Source:
Returns:
Type
Date

openBlockEmojiPicker(bid, anchor)

Opens a floating emoji picker anchored below anchor for a time block. Identical behaviour to openEmojiPicker but operates on blocks instead of planTasks. Calling again for the same block ID closes the picker.

Parameters:
Name Type Description
bid string

Block ID.

anchor HTMLElement

Element to position the picker below.

Source:

openEmojiPicker(pid, anchor)

Opens a floating emoji picker anchored below the given element. Includes a free-text input for custom emoji and a grid of common choices. Calling again for the same task ID closes the picker.

Parameters:
Name Type Description
pid string

Plan task ID.

anchor HTMLElement

Element to position the picker below.

Source:

openEodModal()

Opens the end-of-day modal: auto-exports the time log and JSON backup, saves the EOD timestamp, populates handoff notes for unfinished tasks, renders today's dev changelog entries, and lists the test areas to review.

Source:

openExpiryModal()

Opens the iteration-expiry editor modal, pre-filling the textarea with the current expiry dates (one per line).

Source:

openIDB() → {Promise.<IDBDatabase>}

Opens (or creates) the IndexedDB database used to persist the FSA directory handle.

Source:
Returns:

Resolves with the opened database instance.

Type
Promise.<IDBDatabase>

openMigration()

Opens the migration modal and populates it with open (unresolved) tasks for the current month. Alerts if there is nothing to migrate.

Source:

openRapid()

Opens the quick-capture overlay and focuses the search input.

Source:

openReflection(onCompleteopt)

Opens the end-of-day reflection overlay. Resets star ratings to 0, attaches Save/Skip handlers that call onComplete when dismissed.

Parameters:
Name Type Attributes Description
onComplete function <optional>

Callback invoked after Save or Skip.

Source:

openSprintSetup() → {void}

Shows the sprint setup panel, clears the intention input, resets the duration selection to 25 minutes, and focuses the intention field.

Source:
Returns:
Type
void

openTrackerForm() → {void}

Shows and populates the new-tracker form inside #trackerNewForm. Pre-fills the colour picker with the first category's colour. Attaches Save / Cancel / keyboard listeners.

Source:
Returns:
Type
void

parseRapidTokens(raw, cats, nowopt) → {Object}

Parses inline shorthand tokens from a raw quick-capture input string and returns a clean text plus structured token values.

Supported tokens (each stripped from the returned text):

  • #<cat> — Category: matched against category ids and labels (case-insensitive; prefix match as fallback). Last occurrence wins.
  • !<sig> — Signifier shortcode (see RAPID_SIG_SHORTCUTS). Last occurrence wins.
  • ><date> — Date pointer: today, tomorrow, YYYY-MM-DD, or weekday mon–sun (next occurrence). Last occurrence wins.

Unrecognised tokens are left in the text unchanged so the user sees them and can correct them without data being silently discarded.

Parameters:
Name Type Attributes Description
raw string

Raw input text that may contain inline shorthand tokens.

cats Array.<{id: string, label: string}>

Available categories for # resolution.

now Date <optional>

Reference date for relative date resolution; defaults to new Date().

Source:
Returns:
Type
Object

partitionSessionNotes(allItems) → {Object}

Partitions a flat item list from buildDailyLogItems into two structures: non-session-note items (the main timeline rows) and a lookup of session-note items keyed by their parentEntryId. Session-notes render nested inside their parent entry row rather than as standalone timeline entries.

Parameters:
Name Type Description
allItems Array.<object>

Items returned by buildDailyLogItems.

Source:
Returns:
Type
Object

patchCarriedTasks()

Applies data migrations and status patches to today's plan tasks after carry-over:

  • Stamps billable: true on tasks/categories that predate the feature.
  • Stamps completedAt on done tasks missing a timestamp.
  • Promotes today's task status to match the most recent past version when that version was pending/blocked/upcoming or in-progress.
Source:

pausePomo()

Pauses the pomodoro timer without resetting the remaining time.

Source:

pauseTimer()

Pauses the running timer, accumulating elapsed time so it can be resumed. No-ops if no timer is active or it is already paused.

Source:

(async) pickSaveFolder() → {Promise.<void>}

Prompts the user to select a save folder via the File System Access API and persists the resulting directory handle. Shows a fallback alert in browsers that do not support the API.

Source:
Returns:
Type
Promise.<void>

playChime()

Plays two soft sine-wave tones (528 Hz then 660 Hz) using the Web Audio API to signal an elapsed-time milestone. Silently skips if Web Audio is unavailable (e.g. browser privacy settings).

Source:

playPomoBeep()

Plays three short 660 Hz beeps spaced 350 ms apart using the Web Audio API to signal pomodoro completion. Silently skips if Web Audio is unavailable.

Source:

pomoAddTime()

Adds 120 seconds to the current running session without resetting segments. No-op if the timer is not running.

Source:

pomoAffirmation(totalopt, leftopt) → {string}

Returns a progress-aware affirmation string based on elapsed time. Default parameters let callers pass explicit values (useful for testing).

Parameters:
Name Type Attributes Description
total number <optional>

Total session seconds; defaults to pomoTotal.

left number <optional>

Remaining seconds; defaults to pomoLeft.

Source:
Returns:

Short motivational phrase.

Type
string

pomoBuildDateRange() → {Array.<string>}

Builds an array of POMO_SPARKLINE_DAYS date strings ending today, oldest first.

Source:
Returns:

Array of YYYY-MM-DD strings.

Type
Array.<string>

pomoDone()

Called when the pomodoro timer reaches zero. Plays the completion beep, briefly animates the time display, and appends a session record to the pomodoro log in localStorage.

Source:

pomoGap(n) → {number}

Returns the angular gap (in radians) between pomodoro timer segments. Smaller gaps are used for higher segment counts to keep them visually distinct.

Parameters:
Name Type Description
n number

Number of segments (minutes).

Source:
Returns:

Gap in radians.

Type
number

pomoGetLog() → {Array.<{ts: number, mins: number, task: (string|null)}>}

Reads and validates the pomodoro session log from localStorage. Invalid records are dropped and reported via wlLog.warn.

Source:
Returns:

Session log entries.

Type
Array.<{ts: number, mins: number, task: (string|null)}>

pomoSessionsOnDate(log, dateKey) → {number}

Returns the number of completed pomodoro sessions on the given date.

Parameters:
Name Type Description
log Array.<PomoSessionEntry>

Session log.

dateKey string

Date in YYYY-MM-DD format.

Source:
Returns:
Type
number

pomoSparkColours() → {Object}

Reads the --pomo-spark-fill and --pomo-spark-empty CSS variables for the active colour scheme. Falls back to hardcoded values when CSS vars are unavailable (e.g. headless test environments).

Source:
Returns:
Type
Object

pomoTapOut()

Ends the session early, logs a partial session, and transitions to done state. Records the elapsed minutes (minimum 1) so the session appears in the log.

Source:

positionNowLine()

Positions the "now" indicator line in the time-block grid to reflect the current time. Hides the line when outside the grid's time range (TB_STARTTB_END).

Source:

prioBtnHtml(t) → {string}

Builds the priority toggle button HTML for a task row. Click cycles: normal (0) → high (1) → low (-1) → normal.

Parameters:
Name Type Description
t Object

The plan task.

Source:
Returns:

HTML button element.

Type
string

readCollapseState(sectionId, defaultCollapsed) → {boolean}

Reads the stored collapsed state for a section from localStorage.

Parameters:
Name Type Description
sectionId string

The section element's id.

defaultCollapsed boolean

Value to use when nothing is stored.

Source:
Returns:

Whether the section should be collapsed.

Type
boolean

readOptionalLogForBackup(storeKey, label) → {Array}

Reads and parses an optional JSON-array log from localStorage for inclusion in a backup. If the stored value is present but not valid JSON, the failure is logged via wlLog (so the data loss is diagnosable rather than silent) and an empty array is returned so the rest of the backup still succeeds. Absent keys legitimately yield an empty array.

Parameters:
Name Type Description
storeKey string

The localStorage key to read.

label string

Human-readable log name for the warning message.

Source:
Returns:

The parsed array, or [] if absent or unparseable.

Type
Array

refreshPomoDashboard()

Full Pomodoro dashboard refresh: redraws the 28-day sparkline, ribbon footer, and composer task label. Called on module load and after every session completion.

Source:

render()

Full application re-render: updates the date label, timer bar, stat counters, sub-stats, time-log list, chart, quick-pick, plan, completed section, and time-block view. Call whenever persistent state changes.

Design trade-off: full DOM re-render on every change rather than targeted updates. Keeps state reasoning simple for a single-user personal tool where the entry list is small (typically < 50 items per day). If performance becomes a concern, the innermost timelineEl.querySelectorAll event-binding loop is the first candidate for optimisation (see phase 6 below).

Source:

renderBoardDoneHistory(doneListEl, viewKey)

Appends the collapsible "older history" expander to the Done column list. Shows completed tasks from prior dates, grouped by day, within the active iteration.

Parameters:
Name Type Description
doneListEl HTMLElement

The #doneList container element.

viewKey string

The current view date key (YYYY-MM-DD).

Source:

renderCalStrip(meetings)

Renders the calendar meetings strip for today. Sorts meetings by start time, marks past meetings grey/italic, pulses ongoing meetings, and provides ▶ start and ✕ hide buttons per meeting.

Parameters:
Name Type Description
meetings Array.<Object>

Array of meeting objects from the PS server.

Source:

renderChart(list)

Renders the time-tracking bar chart for the currently viewed day. Decorates the active timer's entry with a synthetic tsEnd so live time appears in real-time. Respects chartMode ('task' | 'category').

Parameters:
Name Type Description
list Array.<Object>

The array of log entries to chart.

Source:

renderCompleted()

Renders the completed-tasks section for the currently viewed date. Shows tasks that were completed on or before the view date and whose iteration expiry date has not yet passed. Deduplicates by task text, keeping only the most recently completed version. Hides the section when there are no matching tasks.

Source:

renderDayStrip(dateKey)

Renders the compact day-overview strip: hour-tick labels, entry footprints, and (today only) a live "now" cursor.

Parameters:
Name Type Description
dateKey string

YYYY-MM-DD.

Source:

renderEmergencyCps()

Renders the checkpoint list inside the focus-mode overlay for the currently active task. Hides the wrapper if the task has no checkpoints. Each checkpoint cycles through three states on click: false → 'partial' → true.

Source:

renderEodBtn()

Updates the "end the day" button to show the end time recorded for the day in view (if any) or its default label, and dims the button once a time is set.

Source:

renderFlagDay()

No longer actively used — fetchCalendarEvents handles flag-day display. Kept as a no-op stub so call sites don't need to be removed.

Source:

renderFlowHeader(dateKey, activeView)

Renders the section header: icon, title, tracked/billable totals, and the Flow / Log / Blocks segmented control.

Parameters:
Name Type Description
dateKey string
activeView 'flow' | 'log' | 'blocks'
Source:

renderFlowView(dateKey)

Renders the Flow view: a vertical list where each entry's accent strip height is proportional to its duration (height = max(64, 0.6 × minutes) px), giving longer tasks more visual weight.

Parameters:
Name Type Description
dateKey string
Source:

renderFolderStatus()

Updates the #folderStatus element to show the currently selected save folder name (green) or a "pick save folder" prompt (default colour).

Source:

renderGapReminder(dateKey)

Renders or hides the gap-reminder banner.

Parameters:
Name Type Description
dateKey string
Source:

renderHeroCard()

Switches the root card's state-modifier class and makes the matching inner panel visible. Updates all dynamic content for the current state.

Source:

renderLocation() → {void}

Updates the date-nav location button to reflect the viewed day's location. No-ops when the button is absent (e.g. in a reduced test DOM).

Source:
Returns:
Type
void

renderMigrationStep()

Renders the current migration step (or the "done" screen when all resolved).

Source:

renderMonthlyCalendar(calEl, year, month) → {void}

Renders the heatmap calendar grid: navigation header, day labels, day cells, and the colour legend. Binds cell-click (navigate to that day) and prev/next month buttons. Writes its full HTML to calEl.

Implicit dependency: the prev/next handlers mutate module-level _mlYear / _mlMonth and then call renderMonthlyLog() to re-render the whole view. Both globals must therefore be in scope when this function is called.

Parameters:
Name Type Description
calEl HTMLElement

The #mlCalendar container.

year number

Full year to render.

month number

Month index, 0-based.

Source:
See:
Returns:
Type
void

renderMonthlyLog() → {void}

Orchestrates the Monthly Log view: resolves DOM targets and delegates each panel to a single-purpose renderer.

Source:
Returns:
Type
void

renderMonthlySummary(sumEl, monthPrefix) → {void}

Renders the time-totals summary panel: total logged, billable, top category. Writes its full HTML to sumEl. No event binding. Early-returns if sumEl is absent so a partial DOM doesn't throw on innerHTML assignment.

Parameters:
Name Type Description
sumEl HTMLElement

The #mlSummary container.

monthPrefix string

Date prefix YYYY-MM used to filter entries.

Source:
Returns:
Type
void

renderMonthlyTasks(taskEl, monthPrefix) → {void}

Renders the task-inventory panel: open / done / migrated counts plus a "Run Migration" button. Writes its full HTML to taskEl and binds the button to openMigration() if that helper is loaded. Early-returns if taskEl is absent so a partial DOM doesn't throw on innerHTML.

Parameters:
Name Type Description
taskEl HTMLElement

The #mlTasks container.

monthPrefix string

Date prefix YYYY-MM used to filter plan tasks.

Source:
Returns:
Type
void

renderMoon()

Renders today's moon phase, illumination, and zodiac sign into #liveMoon. No-ops if the element is absent.

Source:

renderPlan()

Re-renders the entire plan UI as a 3-column kanban board (To Do / In Progress / Done). Pending and blocked tasks absorb into the To Do column with their existing badge treatment. The Done column shows today's completed tasks and a collapsible history expander for older ones.

Design trade-off: full DOM re-render on every state change rather than targeted updates. Acceptable for a personal tool where the task list is small (< 20 items).

Source:

renderPomoLog()

Renders the pomodoro session history list inside #pomoLog. Shows date/time, duration, and the task that was active during each session.

Source:

renderPomoRibbon()

Renders the ribbon footer below the 4-column grid:

  • #pomoRibbonDots: last-5-session dot sequence (● filled, · empty slot)
  • #pomoRibbonPill: "Peak Focus" pill when today matches the all-time high, otherwise "N sessions today", hidden when no sessions today
  • #pomoRibbonLink: "View all N sessions ↓" button that scrolls #pomoLog

Each element is individually guarded — no-op when absent from the DOM.

Source:

renderPomoSparkline()

Draws a 28-day focus density bar chart on the #pomoSparkline canvas. Each bar represents one calendar day; bar height is proportional to the number of completed pomodoro sessions on that day. No-op when the canvas element is absent or the 2D context is unavailable.

Source:

renderQuickPick()

Renders the "recent tasks" quick-pick bar below the capture input. Deduplicates entries by text, hides manually-dismissed tasks and tasks past their iteration expiry, and caps the list at 16 items.

Source:

renderReflStars(elId, current)

Renders a 1–5 star row inside elId, marking stars up to current as active.

Parameters:
Name Type Description
elId string

ID of the container element.

current number

Currently selected value (0 = none selected).

Source:

renderRow(t) → {string}

Builds the HTML string for a single plan task row. Handles two layout branches: pending/blocked (compact) and normal (full). Reads module-level state variables for edit mode, checkpoint open state, and pending comment state so re-renders are always consistent.

Parameters:
Name Type Description
t Object

The plan task object to render.

Source:
Returns:

HTML string for one .plan-item element (and optional split row).

Type
string

renderSodBtn() → {void}

Updates the session chip to show the start time recorded for the day in view (with a green dot), or the default "start the day" label when that day has no recorded start. The button's text content is its accessible name; no static aria-label is used so screen readers announce the current state ("started HH:MM" or "start the day").

Source:
Returns:
Type
void

renderSprintDurations() → {void}

Renders the duration chip row inside #sprintDurations, marking the currently selected duration active. Attaches click listeners to each chip.

Source:
Returns:
Type
void

renderTimeblock()

Renders the full time-block grid for the currently viewed date: time labels, grid rows, planned blocks (with drag-to-move), live timer block, a "now" line, and the plan-task drag targets. Also handles drag-and-drop wiring for moving existing blocks and dropping tasks from the plan list.

Source:

renderTodayFlow()

Renders the Today's Flow section: header, day-overview strip, gap reminder, and the active view pane (Flow / Log / Blocks / Month). Called from render() on every state change and when the view toggle fires.

Source:

renderTrackRecent()

Renders the "+ TRACK RECENT" strip inside #planTrackRecent. Shows chips for the most recent unique time-log entries from today so the user can restart a timer with a single click without re-typing. Limits to 5 entries; hidden when no entries exist for today.

Source:

renderTrackers() → {void}

Renders all tracker cards into #trackerList. Each card shows a 28-day hit/partial/miss grid, current streak, and total hit count. Attaches delete-button listeners after render.

Source:
Returns:
Type
void

resetPomo()

Resets the pomodoro timer to the full configured duration without starting it.

Source:

resolveCarryStatus(todayTask, prev) → {string|null}

Determines the carry-forward status a today-task should adopt based on its most recent past peer, implementing the following rules:

  • pending or blocked prev overrides todo or inprogress today — the task is still blocked so the blocking state wins.
  • upcoming prev overrides only a todo today — a todo placeholder created from an even-older copy should reflect the more recent intent to defer. It must NOT override inprogress, because the user explicitly started the task and a reload must not undo that.
  • inprogress prev promotes a todo today — the task was already being worked on and the carry placeholder should show that.

Returns null when no change is needed.

Parameters:
Name Type Description
todayTask Object

Today's task object.

prev Object

Most recent past task with the same text (case-insensitive).

Source:
Returns:

The new status to apply, or null for no change.

Type
string | null
Example
resolveCarryStatus({ status: 'todo' }, { status: 'upcoming' }) // → 'upcoming'
resolveCarryStatus({ status: 'inprogress' }, { status: 'upcoming' }) // → null
resolveCarryStatus({ status: 'todo' }, { status: 'pending' })  // → 'pending'

resolveRapidDate(token, nowopt) → {string|null}

Resolves a >date shorthand token to a YYYY-MM-DD date key. Supported tokens: 'today', 'tomorrow', exact 'YYYY-MM-DD', and weekday abbreviations 'mon'–'sun' (resolves to the next occurrence, never today).

Parameters:
Name Type Attributes Description
token string

Raw date token (without the leading >).

now Date <optional>

Reference date for relative resolution; defaults to new Date().

Source:
Returns:

Resolved date key, or null if the token is unrecognised.

Type
string | null

resumeTimer()

Resumes a paused timer from where it left off. No-ops if no timer is active or it is not paused.

Source:

resumeTimerIfActive()

Called at startup to reconnect the tick interval when the app is reloaded with an active timer persisted in localStorage. If the entry the timer was tracking no longer exists the timer is cleared. No-ops if no timer is active.

Source:

roundToNearest30(ts) → {number}

Rounds a timestamp to the nearest 30-minute clock mark.

Tie-breaking rule (at exactly 15 min into a 30-min slot): rounds DOWN. Rationale: conservative for billing — a task must exceed the midpoint of the slot before the next slot is claimed.

Assumption: rounding ties (exactly 15 min past a slot start) are resolved in favour of the earlier slot to avoid inflating billable time. This matches the intent documented in DATA.md under wl_entries.ts.

Parameters:
Name Type Description
ts number

Unix timestamp in milliseconds.

Source:
Returns:

Rounded Unix timestamp in milliseconds.

Type
number

roundToNearest30IfBillable(ts, entry) → {number}

Rounds ts to the nearest 30-minute mark only when entry is billable. Non-billable entries keep their exact timestamps for accurate reporting.

Parameters:
Name Type Description
ts number

Unix timestamp in milliseconds.

entry object | null

Work-log entry; if null, always rounds.

Source:
Returns:

Timestamp, conditionally rounded.

Type
number

roundUp30(ms) → {number}

Rounds a duration up to the nearest 30-minute slot, with a minimum of 30 min. Used for billing time estimates — even a 1-second task costs one half-hour slot.

Assumption: billing granularity is 30 minutes and the minimum billable unit is 30 minutes. Changing this assumption requires updating both this function and any UI that displays billable totals (e.g. the billable-time section in exports).

Parameters:
Name Type Description
ms number

Duration in milliseconds.

Source:
Returns:

Duration rounded up to nearest 30-min slot, in milliseconds.

Type
number
Example
roundUp30(0)                    // → 1_800_000  (30 min — minimum)
roundUp30(1)                    // → 1_800_000  (1 ms still costs one slot)
roundUp30(30 * 60 * 1000)       // → 1_800_000  (exactly 30 min stays at 30 min)
roundUp30(30 * 60 * 1000 + 1)   // → 3_600_000  (30 min + 1 ms rounds up to 60 min)

safeCssColor(c) → {string}

Returns c if it is a safe CSS colour (hex or hsl()), otherwise returns a neutral fallback. Prevents malformed user-supplied colour values from breaking layout or injecting CSS.

Parameters:
Name Type Description
c string

CSS colour string to validate.

Source:
Returns:

A safe CSS colour string.

Type
string
Example
safeCssColor('#7B61FF')      // → '#7B61FF'
safeCssColor('hsl(200,60%,50%)') // → 'hsl(200,60%,50%)'
safeCssColor('red')          // → '#888780'  (name blocked)
safeCssColor('')             // → '#888780'

safeRoundedStart() → {number}

Returns a rounded start timestamp that does not overlap any existing entry for today. Prevents new entries from appearing to start before a prior entry's end time.

Source:
Returns:

Unix timestamp in milliseconds.

Type
number

save()

Persists entries, active timer, and categories to localStorage. Refuses to overwrite existing non-empty data with an empty array to guard against accidental data loss if save() is called before load() completes.

Assumption: an empty entries array in memory while localStorage still holds data means save() was called before load() finished (e.g. a race during init), not that the user intentionally deleted everything. Intentional clearing goes through a dedicated wipe path that bypasses this guard.

Source:

saveBlocks()

Persists the current blocks array to localStorage.

Source:

saveEodHandoffNotes()

Reads all handoff-note inputs in the EOD modal and persists their values to the wl_handoff localStorage key. Empty values are removed from the map.

Source:

saveExpiryDates()

Reads the expiry-date textarea, validates each line against YYYY-MM-DD format, deduplicates and sorts the valid dates, persists them to localStorage, and closes the modal. Invalid lines are surfaced in the feedback element but not saved.

Source:

saveHandoffNote(entryText, note)

Persists a handoff note for a given entry text. Pass an empty string or falsy value to delete the stored note. The key is stored case-insensitively.

Parameters:
Name Type Description
entryText string

The entry text to associate the note with.

note string

The note to save; falsy removes the stored note.

Source:

saveLocationMap(map) → {void}

Persists the location map to localStorage.

Parameters:
Name Type Description
map Record.<string, string>

Date-key → location-id map.

Source:
Returns:
Type
void

saveMigrationRecord(rec)

Persists the migration completion record to localStorage.

Parameters:
Name Type Description
rec Object

Map of YYYY-MM → boolean.

Source:

savePlan() → {void}

Persists the current planTasks array to localStorage.

Source:
Returns:
Type
void

saveReflection()

Persists the current _reflData map to localStorage.

Source:

saveSnapshot()

Writes a recoverable snapshot of today's log entries to localStorage every 30 minutes. The snapshot contains both a human-readable plaintext summary and the raw entry/category arrays so data can be recovered after accidental clearing. No-ops when there are no entries for today.

Assumption: 30 minutes is an acceptable data-loss window for a personal work log used in a single browser tab. Browser crashes, accidental page reloads, and mis-clicks on "clear data" are the main risks; all are adequately covered by a 30-minute recovery point. If higher durability is needed, reduce the interval in the setInterval call in 07-lifecycle.js.

Source:

saveSprintLog() → {void}

Persists the current sprintLog array to localStorage.

Source:
Returns:
Type
void

saveTaskNotionUrl(taskId, url)

Persists the Notion page URL on a plan task so the per-task button changes to an "open in Notion" link on next render.

Parameters:
Name Type Description
taskId string

Plan task ID.

url string

Notion page URL returned by the API.

Source:

saveTrackerForm() → {void}

Reads the new-tracker form, validates inputs, pushes the tracker to the trackers array, persists it, and re-renders. Shows an alert if no category is selected; focuses the name field if the name is empty.

Source:
Returns:
Type
void

saveTrackers() → {void}

Persists the current trackers array to localStorage.

Source:
Returns:
Type
void

scheduleMigTask(task, dateStr)

Reschedules the task to the given date and marks it as migrated.

Parameters:
Name Type Description
task Object
dateStr string

YYYY-MM-DD

Source:

sectorPath(cx, cy, r, a1, a2) → {string}

Builds an SVG path string for a pie-chart sector (filled segment).

Parameters:
Name Type Description
cx number

Centre x coordinate.

cy number

Centre y coordinate.

r number

Radius.

a1 number

Start angle in radians (0 = 12 o'clock).

a2 number

End angle in radians.

Source:
Returns:

SVG path d attribute value.

Type
string

setBlockEmoji(bid, emoji)

Saves an emoji to a time block and closes the picker. Pass null or an empty string to remove the block's emoji.

Parameters:
Name Type Description
bid string

Block ID.

emoji string | null

Emoji character to assign, or null to remove.

Source:

setFavicon(state)

Updates the browser favicon to a coloured dot reflecting the timer state. Skips redundant redraws by tracking the last rendered state.

Parameters:
Name Type Description
state 'active' | 'paused' | 'hyperfocus' | 'idle'

Current timer state.

Source:

setFlowView(view)

Persists the active view selection.

Parameters:
Name Type Description
view 'flow' | 'log' | 'blocks'
Source:

setPomoFavicon()

Redraws the browser favicon as a depleting wedge mirroring the remaining pomodoro time. Silently skips when the canvas API is unavailable.

Source:

setSeenEnded(s)

Persists the set of seen-ended meeting keys to localStorage.

Parameters:
Name Type Description
s Set.<string>

Updated set to persist.

Source:

setTaskEmoji(pid, emoji)

Saves an emoji to a plan task and closes the picker. Pass null or an empty string to remove the task's emoji.

Parameters:
Name Type Description
pid string

Plan task ID.

emoji string | null

Emoji character to assign, or null to remove.

Source:

showBridgeBanner(meeting)

Shows the post-meeting bridge banner for the given meeting. Queues the meeting if another banner is already visible.

Parameters:
Name Type Description
meeting Object

The ended meeting.

Source:

showHandoffInput()

Shows the handoff-note text field in the timer bar so the user can record what a future self (or colleague) should know before picking this task up again.

Source:

showSprintReview() → {void}

Stops the main timer and renders the sprint review panel inside #sprintReview. Populates the intention label, wires outcome buttons (yes / partly / no), and on save: appends the sprint to sprintLog, tags the entry with the outcome, persists both, hides the panel, and triggers a full render.

Source:
Returns:
Type
void

sigHtml(entry) → {string}

Returns the HTML string for the clickable signifier widget on one entry row.

Parameters:
Name Type Description
entry Object

Log entry object.

Source:
Returns:

HTML string for a <span> button.

Type
string

sigSymbol(entry) → {string}

Returns the display symbol for an entry's signifier.

Parameters:
Name Type Description
entry Object

Log entry object.

Source:
Returns:

Unicode BuJo symbol (○ ★ → ✗ !) or '●' for the billable default.

Type
string

sigTitle(entry) → {string}

Returns the accessible title string for an entry's signifier.

Parameters:
Name Type Description
entry Object

Log entry object.

Source:
Returns:
Type
string

slotToTime(slot) → {string}

Converts a 0-based half-hour slot index to an "HH:MM" label. Slot 0 = TB_START:00, slot 2 = TB_START+1:00, etc.

Parameters:
Name Type Description
slot number

0-based slot index.

Source:
Returns:

"HH:MM" formatted time string.

Type
string

sodKey(dayopt) → {string}

Returns the localStorage key for a given day's start-of-day timestamp.

Parameters:
Name Type Attributes Default Description
day Date <optional>
viewDate

Day to key by; defaults to the day in view so the session chip reflects whichever day the user has navigated to.

Source:
Returns:

Key in the format wl_sod_YYYY-MM-DD.

Type
string

startPomo()

Starts the pomodoro countdown. Resets to full duration if already at zero. Fires pomoDone and clears the interval when time runs out.

Source:

startSprint() → {void}

Commits a new sprint: reads the intention from the input, creates a time-log entry, starts the main timer, starts the Pomodoro for _sprintDuration minutes, and sets _onSprintEnd so the review panel is shown when the ring reaches zero. No-ops with a focus call if the intention field is empty.

Source:
Returns:
Type
void

startTimer(entryId)

Starts (or restarts) the timer for the given entry. Clears any existing interval, resets the chime state, and begins a 1-second tick. Persists state and updates the UI immediately.

Parameters:
Name Type Description
entryId string

ID of the log entry to time.

Source:

statusOpts(cur) → {string}

Builds the