Ultradian Cycle Tracker

Know When To Take A Break 😌

Your Focus can only sustain ~90 minutes. Know how long your are sitting on your computer and give yourself some rest.

Subtle Display.
Displays the time since your last login in the menu bar. It is not intrusive and does not distract you from your work.
90 Minute Reminder.
Reminds you after 90 minutes to take a break. It repeats the notification every 5 minutes until you take a break.
Adjustable Break Time.
You can adjust the break time to your needs. The default is 90 minutes, but you can change it to your needs.
Based On Open Source Software.
All tools are based solely on ScripKit, an open source application. You will get the source code and can modify it as you wish.
Easily Customizable.
You will receive the scripts as they are, and they can be customized according to your requirements.
Runs Locally - No Data Stored Somewhere Else.
Your data stays on your local machine. Your data is never stored somewhere else.

Login Trigger 🔧

This script is triggered when the user logs in. St... (Read more)

// Author: Eduard Uffelmann
// Linkedin: https://www.linkedin.com/in/euffelmann/
// Twitter: @schmedu_
// Website: https://schmedu.com
// System: unlock-screen

import "@johnlindquist/kit";

async function getSystemInfoDb() {
    let database = await db(await kenvPath("db", "system-info.json"), {
        lastLogin: new Date().toString(),
        lastLogout: void 0,
        dates: {},
        currentTasks: [],
        wasShutDown: false,
    });
    return database;
}

let database = await getSystemInfoDb();

database.lastLogin = new Date().toString();
await database.write();

await menu("0m");

Logout Trigger 🔧

This script is triggered when the user logs out. R... (Read more)

// Author: Eduard Uffelmann
// Linkedin: https://www.linkedin.com/in/euffelmann/
// Twitter: @schmedu_
// Website: https://schmedu.com
// System: lock-screen

import "@johnlindquist/kit";

async function getSystemInfoDb() {
    let database = await db(await kenvPath("db", "system-info.json"), {
        lastLogin: new Date().toString(),
        lastLogout: void 0,
        dates: {},
        currentTasks: [],
        wasShutDown: false,
    });
    return database;
}


let database = await getSystemInfoDb();

let now = new Date();

// get current date in format YYYY-MM-DD
let currentDate = now.toISOString().slice(0, 10);
let lastLogin = new Date(database.lastLogin);

let timeSinceLastLogin = (now.getTime() - lastLogin.getTime()) / 1000 / 60;
// parse date from loginTimeDate
let loginTimeDate = lastLogin.toISOString().slice(0, 10);
// check if loginTimeDate is today
if (loginTimeDate === currentDate) {
    if (database.dates[currentDate] === undefined) {
        database.dates[currentDate] = {
            totalTime: timeSinceLastLogin,
        };
    } else {
        database.dates[currentDate].totalTime += timeSinceLastLogin;
    }
} else {
    // create new date from midnight of today
    let midnight = new Date(
        now.getFullYear(),
        now.getMonth(),
        now.getDate(),
        0,
        0,
        0,
        0
    );
    // get minutes from lastLogin to midnight
    let minutesSinceLastLogin =
        (midnight.getTime() - lastLogin.getTime()) / 1000 / 60;
    if (database.dates[loginTimeDate] === undefined) {
        database.dates[loginTimeDate] = {
            totalTime: timeSinceLastLogin,
        };
    } else {
        database.dates[loginTimeDate].totalTime += timeSinceLastLogin;
        database.dates[loginTimeDate].totalTime += minutesSinceLastLogin;
    }

    // get minutes from midnight to now
    let minutesSinceMidnight = (now.getTime() - midnight.getTime()) / 1000 / 60;
    database.dates[currentDate].totalTime = minutesSinceMidnight;
}

database.lastLogout = now.toString();
await database.write();
await menu("")

Ultradian Cycle Tracker 🔧

This script tracks the time since the last login a... (Read more)

// Author: Eduard Uffelmann
// Linkedin: https://www.linkedin.com/in/euffelmann/
// Twitter: @schmedu_
// Website: https://schmedu.com
// Schedule: */1 * * * *

import "@johnlindquist/kit";

async function getSystemInfoDb() {
    let database = await db(await kenvPath("db", "system-info.json"), {
        lastLogin: new Date().toString(),
        lastLogout: void 0,
        dates: {},
        currentTasks: [],
        wasShutDown: false,
    });
    return database;
}

const TIME_LIMIT = 90;
const INTERVAL_TIME = 5;

let database = await getSystemInfoDb();

// check if last login is more than 90 minutes ago
let lastLogin = Date.parse(database.lastLogin);

// how much time has passed since last login
let timeSinceLastLogin = new Date().getTime() - lastLogin;

// timeSinceLastLogin in Minutes
let timeSinceLastLoginInMinutes = parseInt(
    (timeSinceLastLogin / 1000 / 60).toFixed(0)
);

await menu(`${timeSinceLastLoginInMinutes}m`); // update the time in the menu bar

if (process.env.KIT_TRIGGER === "menu" || process.env.KIT_TRIGGER === "kar") {
    let currentDate = new Date().toISOString().slice(0, 10);
    let totalTime = database.dates[currentDate]?.totalTime || 0;
    totalTime += timeSinceLastLoginInMinutes;
    notify({
        title: "Working Time",
        message: `Currently: ${timeSinceLastLoginInMinutes.toFixed(0)}m - Total: ${(totalTime / 60).toFixed(
            1
        )}h`,
    });
}

if (
    timeSinceLastLoginInMinutes >= TIME_LIMIT &&
    Number(timeSinceLastLoginInMinutes.toFixed(0)) % INTERVAL_TIME == 0 &&
    Date.parse(database.lastLogout) < lastLogin
) {
    notify({
        title: "Ultradian Cycle Tracker",
        message: `${timeSinceLastLoginInMinutes.toFixed(
            0
        )} mins worked! Take a break!`,
    });
}

Get The Toolkit Now!

You can install the 'Ultradian Cycle Tracker' Toolkit now and start using it today! It's free!