TreeMap
A free, open-source disk-space visualizer. Squarified treemap, duplicate hunting, disk-full forecasting, and cleanup that only ever moves files to the Trash.
翻譯準備中
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證Private, free time tracker for small teams. Data lives in your own GitHub repo.
翻譯準備中
取自儲存庫 README
正在載入完整 README。
檢視完整 README ↗A private, free and simple time tracker for small teams, as an alternative to Clockify.
entry: add 2h "Fix login" (alice)), so the data repo doubles as an audit log that you can revert.Try it without an account at workaddict.me by clicking "Try the demo" on the start page. Demo data stays in memory and is never saved.
Browser (this app, GitHub Pages) ──GitHub REST API──► private data repo
├─ tracker.json schema version
├─ workspace.json projects & tags
├─ roles.json member roles (optional)
├─ entries/<login>/<YYYY-MM>.json
└─ timers/<login>.json running timer
workspace.json is shared, and its writes retry automatically on conflicts.timeZone in workspace.json, set by team leaders under Settings → Time zone). Without one, each browser's zone is used. Privacy browsers often report UTC, so set a team time zone to keep everyone's times aligned.roles.json stores the role of each member (optional; created when an owner assigns the first role).tracker.json and workspace.json in an empty data repo.Open the app (for example workaddict.me) and click Set up a team. The wizard first asks who the setup is for:
gh commands) and your own token. At the end you get an invite link and a message for your team. Later you find both under Settings → Invite members.The sections below describe the same setup by hand and are the reference for special cases.
You need two repositories:
| Repository | Visibility | Contents |
|---|---|---|
| App repo (this one) | public (required for free GitHub Pages) | source code only, no data, no secrets |
| Data repo | private | your team's time data |
The order matters. The team owner first sets up the organization, the data repo, and everyone's access (step 1). Only then does each member create their token (step 2). A token created before its owner had access to the data repo will not work, even after access is granted later. See Troubleshooting sign-in.
The team owner does this once for the whole team. We recommend a free GitHub organization. The data repo lives inside it.
Why an organization? Fine-grained tokens (the safe kind) only work for repositories owned by your own account or by an organization you belong to. If the data repo belongs to someone else's personal account, the other members have to use classic tokens, which can access all of their repositories.
my-team. This name is the owner part of the data repo name later on (my-team/time-data).You are now the owner of the organization.
https://github.com/organizations/my-team/repositories/new (replace my-team with your organization name). Alternatively: open the organization page → Repositories tab → New repository.time-data.The full name of the data repo is now my-team/time-data. Write it down; every member needs it to sign in.
https://github.com/orgs/my-team/people).Every member must accept the invitation. They get an email, or they can open https://github.com/orgs/my-team/invitation while signed in and click Join my-team. An invitation that has not been accepted gives no access at all.
Being a member of the organization is not enough. By default, organization members only get Read access to the organization's repos, or none at all, and the app needs Write.
Simpler: open the organization → Settings → Member privileges → Base permissions and choose Write. Then every member can write to the data repo, and you can skip adding people one by one. This applies to all repos of the organization, so use an organization that holds only the time data.
Tip for larger teams: create a team (organization → Teams → New team, e.g. trackers), add all members to it, and then add the team to the data repo with the role Write via Add teams. New members then only have to be added to the team.
Members who should be able to assign roles in the app need the role Admin instead of Write (see Assign roles).
https://github.com/organizations/my-team/settings/personal-access-tokens).Checklist before members create their tokens:
Test: each member opens https://github.com/my-team/time-data in the browser while signed in to GitHub. If they see the (possibly empty) repo, their access is correct. If they see a 404 page, their access is not set up yet. Fix that first, before they create a token.
Alternative without an organization: a private repo in your personal account works too. You can use a fine-grained token yourself, but your collaborators must use classic tokens (see Fallback: classic token). Add them under the repo's Settings → Collaborators → Add people; they have to accept the invitation.
Every team member creates their own token on their own GitHub account. Never share one token between people: the app uses the token to find out who you are, and all your entries are saved under that account.
⚠️ Create the token only after you have accepted the organization invitation and can open the data repo in your browser (see the test above). A token created earlier cannot be fixed afterwards. If you already have one, delete it and create a new one.
Workaddict.Time tracking.my-team), not your own username.
my-team/time-data).
If the organization requires approval (the default, see step 1.5), your token shows up as pending and every request to the data repo fails with "Your token cannot see the repository" until an organization owner approves it. Tell your team owner that you created a token; the sign-in page has a Copy message for the owner button with the right link.
https://github.com/organizations/my-team/settings/personal-access-token-requests).You only see this page if you are an owner of the organization. If the list is empty, either no token is waiting or approval is turned off.
Use a classic token only if the data repo is owned by another person's personal account, or as a quick temporary workaround.
Workaddict. Expiration: as you like.repo scope (the whole group). Leave everything else unticked.ghp_).⚠️ A classic
repotoken grants read and write access to all repositories you can access, not just the data repo. Prefer a fine-grained token in an organization. Organizations can also block classic tokens (step 1.5, Personal access tokens (classic) tab).
main. The workflow in .github/workflows/deploy.yml runs npm ci → npm test → npm run build and deploys dist/. If tests fail, nothing is deployed and the previous version stays live. After a successful deploy it tags the commit and publishes a GitHub release when the version changed (see Versions and releases).https://<user-or-org>.github.io/<app-repo>/.Pull requests to main are checked by .github/workflows/ci.yml (audit, lint, tests, build) before they can be merged.
The build uses a relative base path and hash routing (#/stats), so it works under any repo name and page reloads never 404.
Deploying your own copy?
index.html(canonical andog:URLs), the static search pages (clockify-alternative/,import-from-clockify/and their German versions underde/: canonical,hreflangandog:URLs),public/robots.txtandpublic/sitemap.xmlpoint tohttps://workaddict.me. Change them to your own URL, or search engines will treat your copy as a duplicate of the official site. Links between the pages and the app are relative and work on any path.The import guides quote the app's labels (checked by
src/app/seoPages.test.ts). Update them, and retake their screenshots, when the Clockify import wizard changes.
owner/name, exactly as it appears in the browser's address bar when you open the repo, e.g. my-team/time-data. The owner is the organization name, not your username.Several workspaces. Each data repository is a workspace; its name defaults to owner/name and can be changed under Settings → Workspaces → Rename. Open the avatar menu → + Add workspace to add another one: when you already have a token for the same owner (or a classic token), the app offers to reuse it, otherwise you paste a new token (a fine-grained token covers only one organization or account). Switch workspaces with one click in the avatar menu; a dot marks workspaces where your timer is running. Each browser tab can show a different workspace. Settings → Workspaces has the unlock mode, Change passphrase, Export workspaces and Import workspaces (to move your workspaces to another device as an encrypted file), and Forget all workspaces on this device.
If sign-in fails, see Troubleshooting sign-in.
Every member has one of three roles:
| Permission | Worker | Editor | Team leader |
|---|---|---|---|
| Track time, run own timer, edit and delete own entries | ✓ | ✓ | ✓ |
| See all entries and statistics, export | ✓ | ✓ | ✓ |
| Add, edit, and delete other members' entries | ✓ | ✓ | |
| See who is tracking right now ("Team now" on the tracker page) | ✓ | ✓ | |
| Stop or discard other members' running timers | ✓ | ✓ | |
| Create, rename, recolor, archive, and delete projects and tags | ✓ | ✓ | |
| Import from Clockify | ✓ |
timers/ can be read by anyone with access to the data repo.owner/repo#42, paste the issue URL, paste the link of a card on your GitHub Projects board, or just type #42. For #42, an editor or team leader links the project's board or repository once (Projects & Tags → Link GitHub board or repository). With a board, paste one card link the first time; after that the number is enough for that card's repository. With several linked repositories, #42 goes to the default one (the first; Make default changes it) and api#42 to the one named api. The entry list links to the issue, and the exports have an "Issue" column (a hyperlink in Excel and OpenDocument). The app never loads issues from GitHub, so your token still needs access to the data repo only, and a link to a private repository works only for people who can see that repository.Switching from Clockify? A team leader opens Settings → Data → Import from Clockify. The wizard imports projects (name, color, archived), tags, and all completed time entries of the users you select, in a single commit.
clockify.<name>, so yearly totals stay correct), or skip them.clockify.* former members) to another, in one commit. Tick "Only entries that started before a date" and pick the import day so that entries the member tracked in Workaddict afterwards stay with them.Beta. The AI integration is new: the tools and the plugin may still change, and the activity heuristic only sees time in which Claude Code was working. Check the suggested entries before you confirm them.
Every member can let their own AI assistant work with Workaddict through the Workaddict MCP server (workaddict-mcp, runs on your computer via npx). Workaddict itself has no server and holds no AI key: whoever uses Claude Code, Claude Desktop, Cursor or another MCP client connects it with their own token, everyone else keeps using the app as before. Settings → AI assistants → Connect AI shows the commands below with your data repo filled in.
setx WORKADDICT_REPO "owner/repo" and setx WORKADDICT_TOKEN "github_pat_…"export WORKADDICT_REPO="owner/repo" and export WORKADDICT_TOKEN="github_pat_…" to your shell profile/workaddict:log-today and /workaddict:new-project:
/plugin install workaddict --marketplace Workaddict/workaddict
Without the plugin, add only the server: claude mcp add workaddict --scope user -e WORKADDICT_REPO=owner/repo -e WORKADDICT_TOKEN=github_pat_… -- npx -y [email protected] (on native Windows -- cmd /c npx -y …).{
"mcpServers": {
"workaddict": {
"command": "npx",
"args": ["-y", "[email protected]"],
"env": { "WORKADDICT_REPO": "owner/repo", "WORKADDICT_TOKEN": "github_pat_…" }
}
}
}
What it does:
/workaddict:log-today reads your Claude Code session transcripts (~/.claude/projects) on your computer only, turns them into activity blocks (a pause of 15 minutes starts a new block), matches each block to a project through its linked repositories and to an issue through the branch name (fix/42-login → #42), and shows you a table of suggested entries. Time you already tracked is left out. Nothing is saved until you confirm, and only the description the assistant writes is stored, never the transcript./workaddict:new-project turns a description ("new client Huber, shop is github.com/acme/huber-shop, we do support and development") into projects, linked repositories and tags, after you confirm. Needs the editor or team leader role.(via claude-code) (the client's name). Team leaders can also turn on Settings → AI assistants → Mark AI entries (off by default); new AI entries then show "via Claude Code" in the entry list.The app explains itself; nothing of this is tracked or sent anywhere.
#/help, signed in or not, in English and German: token & data repository, workspaces & passphrase, roles, projects & tags, Team now, issue links & project boards, connecting an AI assistant, export & backup, Clockify import, time zone, keyboard shortcuts and a glossary. Complex features have a ? button next to their heading that opens their topic. Each page ends with "Was this helpful?"; 👎 offers a prefilled question in GitHub Discussions, which you open yourself. The old #/token-help address redirects to #/help/token.The login page first checks the token and then the data repo. The error message tells you which step failed.
| Message on the login page | Cause | Fix |
|---|---|---|
| Enter the repository as owner/name | The repo field has the wrong format. | Enter my-team/time-data, with no https://github.com/ in front. |
| GitHub rejected this token | Token incomplete, expired, or deleted. | Copy it again without spaces, or create a new one (step 2). |
| There is no GitHub account or organization named … | The owner part of the repo name is misspelled. | Copy owner/name from the address bar of the repo on GitHub. |
| Your token cannot see the repository … | The token is valid but can't see an organization's repo. GitHub answers with 404. | The app lists the causes in order, starting with a token that waits for approval. See the checklist below. |
| … which belongs to the personal account of … | The repo is in another person's account. Fine-grained tokens can't reach it. | Move the repo into an organization, or use a classic token (step 2.4). |
| … in your own account | Wrong repo name, or the token doesn't include this repo. | Check the name and the token's Repository access. |
| You can read the repository …, but not write to it | Contents is only Read-only, or the member only has Read on the repo. | Set Contents to Read and write (step 2.1, item 7) and give the member Write (step 1.4). |
| GitHub rate limit reached | Too many requests. | Wait until the time shown. See the note below. |
Checklist for "Your token cannot see the repository" (404):
https://github.com/my-team/time-data while signed in. If they see a 404 page, the problem is their access, not the token. Go back to steps 1.3 and 1.4.Test without the app: run this in a terminal with the member's token:
curl -H "Authorization: Bearer <TOKEN>" https://api.github.com/repos/my-team/time-data
If this returns JSON with "full_name": "my-team/time-data" and "push": true, the token is fine. If it returns "message": "Not Found", the problem is on GitHub's side (checklist above).
Rate limit when testing in the browser: don't test by opening https://api.github.com/... links directly in the browser. Those requests are sent without a token, so GitHub only allows 60 per hour per IP address, shared by everyone in the same office network. They also always return 404 for a private repo. Some browsers auto-translate the message into something confusing (such as "installment payment" for "rate limit"). Use the curl command above instead. With a token, the limit is 5,000 requests per hour per token.
Read this before you use the app with real data. To report a vulnerability, see SECURITY.md.
roles.json itself. The app checks roles before every change it makes, but it cannot stop direct edits to the repository. Only add people you trust. Every change is a commit that names the acting user (for example entry: delete "Standup" for bob (carol), role: set bob to editor (alice)), so you can find and revert unwanted changes in the git history.localStorage (AES-GCM with a key derived from your passphrase by PBKDF2-SHA256, 600,000 iterations); no token or repository name is stored in plaintext, and nothing is sent anywhere. Without "Save as a workspace", the token stays in sessionStorage and is cleared when the tab closes. While the app is unlocked, the tokens are in memory, so any script that ran on the page could read them; the vault protects them at rest and in export files, not against such script. To limit the risk:
https://api.github.com and, for the one-time Clockify import, https://*.clockify.me. Trusted Types are enforced and inline styles are not allowed. Nothing is sent anywhere else: no analytics, no third-party scripts at runtime.Requirements: Node.js 20.19+ or 22.12+.
npm install
npm run dev # dev server at http://localhost:5173 (use "Try the demo" to skip login)
npm test # unit tests (Vitest)
npm run lint # ESLint
npm run build # type-check + production build into dist/
npm run preview # serve the production build (with CSP) locally
src/
app/ shell, routing, frame guard, static search pages, project links
components/ shared UI building blocks
domain/ types, time/duration helpers, month keys (pure, unit-tested)
storage/ StorageAdapter interface, memory adapter, GitHub adapter
features/ auth, tracker, workgroups, stats, export, import, data, settings,
onboarding, profiles, help (help pages, tour, "New" dots)
i18n/ English and German texts
styles/ design tokens, light/dark themes
mcp/ Workaddict MCP server (npm package workaddict-mcp)
plugin/ Claude Code plugin with the /workaddict:* skills
scripts/ build and release helpers
All data access goes through the StorageAdapter interface (src/storage/types.ts). UI code never calls GitHub directly. That makes it possible to swap the backend later (e.g. for Supabase), and the JSON backup format serves as the migration path. The MCP server reuses the same storage and domain code, so src/storage and src/domain must not use browser APIs.
The app's version is set automatically from the commit messages, which follow Conventional Commits. On every deploy, scripts/next-version.mjs looks at the commits since the last v* tag:
| Commits since the last release | Next version (from 1.1.0) |
|---|---|
at least one feat: | 1.2.0 |
only fix: or perf: (plus others) | 1.1.1 |
feat!:, fix!: … or a BREAKING CHANGE: footer | 2.0.0 |
only chore:, docs:, ci:, test:, refactor: … | no new version |
The build shows that version under Settings → About, and after a successful deploy the workflow creates the tag and a GitHub release with generated notes. Nothing is committed back to main; version in package.json is only used for local builds. When you add a feature to NEW_FEATURES (src/features/help/newFeatures.tsx) for a "New" dot, use the next minor version.
The MCP server and the plugin have their own versions and are published by hand (.github/workflows/publish-mcp.yml).
Workaddict is free and open-source software, © 2026 Benedikt Lehner, licensed under the GNU Affero General Public License v3.0 with two additional terms in NOTICE.
In short:
This summary is for convenience; the LICENSE and NOTICE files are what counts.
Built something with Workaddict? Please open an issue and tell me about it. That's a request, not a condition, but I'd love to see it. Suggestions and pull requests are welcome too.
github_pat_). GitHub shows it only once. If you lose it, create a new one.