{"id":23611029,"url":"https://github.com/viccon/pulse","last_synced_at":"2025-12-27T12:10:03.512Z","repository":{"id":143869707,"uuid":"539621212","full_name":"viccon/pulse","owner":"viccon","description":"Like a fitness tracker for your coding sessions","archived":false,"fork":false,"pushed_at":"2024-12-21T07:37:50.000Z","size":11409,"stargazers_count":240,"open_issues_count":0,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-27T07:06:27.825Z","etag":null,"topics":["go","golang","neovim","rpc"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/viccon.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-09-21T18:02:12.000Z","updated_at":"2025-03-14T15:05:03.000Z","dependencies_parsed_at":null,"dependency_job_id":"7e8e4b0b-1c6c-4abc-8123-5bfa1b2a674a","html_url":"https://github.com/viccon/pulse","commit_stats":null,"previous_names":["creativecreature/pulse","viccon/pulse","creativecreature/code-harvest"],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viccon%2Fpulse","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viccon%2Fpulse/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viccon%2Fpulse/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viccon%2Fpulse/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/viccon","download_url":"https://codeload.github.com/viccon/pulse/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247142063,"owners_count":20890652,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang","neovim","rpc"],"created_at":"2024-12-27T16:07:37.899Z","updated_at":"2025-12-27T12:09:58.415Z","avatar_url":"https://github.com/viccon.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# `pulse`: like a fitness tracker for your coding sessions\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/viccon/pulse.svg)](https://pkg.go.dev/github.com/viccon/pulse)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/viccon/pulse/blob/master/LICENSE)\n[![Go Report Card](https://goreportcard.com/badge/github.com/viccon/pulse)](https://goreportcard.com/report/github.com/viccon/pulse)\n[![Test](https://github.com/viccon/pulse/actions/workflows/main.yml/badge.svg?branch=main)](https://github.com/viccon/pulse/actions/workflows/main.yml)\n\nThis repository contains all of the code I'm using to gather data for my\n[website.][1]\n\n![Screenshot of website][2]\n\n![Screenshot of website][3]\n\n# How it works\n\nAfter spending some time debugging different language servers in Neovim, I got\nthe idea to write my own RPC server that would simply parse metadata and\naggregate statistics about my coding sessions.\n\nI run the server from this repository as a daemon, and it receives remote\nprocedure calls from the neovim plugin pertaining to events such as the opening\nof buffers, windows gaining focus, the initiation of new `nvim` processes, etc.\n\nThese calls contains the path to the buffer, which the server parses and writes\nto a log-structured append-only key-value store. The store is a work in\nprogress, but it now includes some core features such as hash indexes,\nsegmentation, and compaction.\n\nThe server runs a background job which requests all of the buffers from the KV\nstore, and proceeds to aggregate them to a remote database. I did it this way\nprimarily because I wanted to avoid surpassing the limits set by the free tier\nfor the remote database. If you aren't concerned about costs you could use a\nmuch lower aggregation interval than me.\n\nThe only things that aren't included in this repository is the API which\nretrieves the data and the website that displays it. The website has been the\nmost challenging part so far. I wanted it to have a unique look and feel and to\nbuild all of the components from scratch. I'm in the process of making it open\nsource, but there are still a few things that I'd like to clean up first!\n\n# Running this project\n\n## 1. Download the binaries\nDownload and unpack the server **and** client binaries from the [releases](https://github.com/viccon/pulse/releases).\nNext, you'll want to make sure that they are reachable from your `$PATH`.\n\n## 2. Create a configuration file\nCreate a configuration file. It should be located at `$HOME/.pulse/config.yaml`\n\n```yml\nserver:\n  name: \"pulse-server\"\n  hostname: \"localhost\"\n  port: \"1122\"\n  aggregationInterval: \"15m\"\n  segmentationInterval: \"5m\"\n  segmentSizeKB: \"10\"\ndatabase:\n  address: \"redis-\u003cPORT\u003e.xxxxxxxx.redis-cloud.com:\u003cPORT\u003e\"\n  password: \"xxxxxxxx\"\n```\n\n## 3. Launch the server as a daemon\nOn linux, you can setup a systemd service to run the server, and on macOS you\ncan create a launch daemon.\n\nI'm using a Mac, and my launch daemon configuration looks like this:\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003c!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"\u003e\n\u003cplist version=\"1.0\"\u003e\n  \u003cdict\u003e\n\n    \u003ckey\u003eLabel\u003c/key\u003e\n    \u003cstring\u003edev.conner.pulse.plist\u003c/string\u003e\n\n    \u003ckey\u003eRunAtLoad\u003c/key\u003e\n    \u003ctrue/\u003e\n\n    \u003ckey\u003eStandardErrorPath\u003c/key\u003e\n\t\t\u003cstring\u003e/Users/conner/.pulse/logs/stderr.log\u003c/string\u003e\n\n    \u003ckey\u003eStandardOutPath\u003c/key\u003e\n\t\t\u003cstring\u003e/Users/conner/.pulse/logs/stdout.log\u003c/string\u003e\n\n    \u003ckey\u003eEnvironmentVariables\u003c/key\u003e\n    \u003cdict\u003e\n      \u003ckey\u003ePATH\u003c/key\u003e\n      \u003cstring\u003e\u003c![CDATA[/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin]]\u003e\u003c/string\u003e\n    \u003c/dict\u003e\n\n    \u003ckey\u003eWorkingDirectory\u003c/key\u003e\n    \u003cstring\u003e/Users/conner\u003c/string\u003e\n\n    \u003ckey\u003eProgramArguments\u003c/key\u003e\n    \u003carray\u003e\n\t\t\t\u003cstring\u003e/Users/conner/bin/pulse-server\u003c/string\u003e\n    \u003c/array\u003e\n\n\t\t\u003ckey\u003eKeepAlive\u003c/key\u003e\n    \u003ctrue/\u003e\n\n  \u003c/dict\u003e\n\u003c/plist\u003e\n```\n\n## 4. Install the neovim plugin\nHere is an example using lazy.nvim:\n\n```lua\nreturn {\n\t-- Does not require any configuration.\n\t{ \"viccon/pulse\" },\n}\n```\n\n[1]: https://conner.dev\n[2]: ./screenshots/website1.png\n[3]: ./screenshots/website2.png\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fviccon%2Fpulse","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fviccon%2Fpulse","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fviccon%2Fpulse/lists"}