Skip to content
CLI Workflows

5 Miru CLI Workflows That Save Our Team Hours Every Week

Real shell scripts and automation patterns our team uses daily. Git hooks, cron invoicing, Slack integration, and more.

Vipul A M Vipul A M · · 6 min read
Teams
Miru team management screen with members and roles
This article is currently written in English. Navigation, dates, and calls to action follow your selected language.

1. Git Post-Commit Hook: Log Time When You Commit

Miru dashboard with CLI-tracked time entries

This is the one that captures hours that would otherwise vanish. Every time you commit, the hook asks if you want to log time. The commit message becomes the time entry description automatically.

#!/bin/bash
# Save as .git/hooks/post-commit and chmod +x

COMMIT_MSG=$(git log -1 --pretty=%s)
PROJECT=$(basename "$(git rev-parse --show-toplevel)")
PROJECT_ID=$(miru project list --search "$PROJECT" | jq -r '.projects[0].id')
BRANCH=$(git branch --show-current)

echo ""
echo "--- Miru Time Logger ---"
echo "Project: $PROJECT ($BRANCH)"
echo "Commit:  $COMMIT_MSG"
echo ""
read -p "Minutes spent (or 'skip'): " DURATION

if [ "$DURATION" != "skip" ] && [ -n "$DURATION" ]; then
  miru time create \
    --project-id "$PROJECT_ID" \
    --duration "$DURATION" \
    --date "$(date +%Y-%m-%d)" \
    --note "$COMMIT_MSG"
  echo "Logged ${DURATION} minutes to $PROJECT"
fi

The project name is pulled from the repo directory name. Match your Miru project names to your repo names and this is zero-config. The branch name is displayed so you know which feature you were on. You type a number and move on.

Our team captures an extra 3-5 hours per week per developer with this hook. That’s billable time that used to disappear into the void.


2. Monday Morning Invoice Generator

First of the month. Time to bill. This cron job creates the monthly retainer draft for one client; review it, then send.

#!/bin/bash
# miru-monthly-invoicing.sh
# Cron: 0 9 1 * * /opt/scripts/miru-monthly-invoicing.sh

LAST_MONTH_START=$(date -d "last month" +%Y-%m-01)
LAST_MONTH_END=$(date -d "$(date +%Y-%m-01) - 1 day" +%Y-%m-%d)
ISSUE_DATE=$(date +%Y-%m-%d)
DUE_DATE=$(date -d "+30 days" +%Y-%m-%d)
CLIENT_ID=7
INVOICE_NUMBER="INV-$(date +%Y%m)"

miru invoice create \
  --client-id "$CLIENT_ID" \
  --invoice-number "$INVOICE_NUMBER" \
  --issue-date "$ISSUE_DATE" \
  --due-date "$DUE_DATE" \
  --line-item "Monthly services|Unbilled work|$LAST_MONTH_END|150|960"

echo "Done. Review drafts: miru invoice list --status draft"

Add to cron:

crontab -e
# 0 9 1 * * /opt/scripts/miru-monthly-invoicing.sh >> /var/log/miru-invoicing.log 2>&1

The script creates one draft invoice. It does not send it automatically. Review the draft, make any adjustments, and send it with one command. Automation handles the tedious part. A human handles the judgment call.


3. Weekly Time Report to Slack

Every Friday at 4 PM, your time entries land in Slack. No one has to pull them manually.

#!/bin/bash
# miru-slack-weekly.sh
# Cron: 0 16 * * 5 /opt/scripts/miru-slack-weekly.sh

MONDAY=$(date -d "last monday" +%Y-%m-%d)
FRIDAY=$(date +%Y-%m-%d)
SLACK_WEBHOOK="https://hooks.slack.com/services/YOUR/WEBHOOK/URL"

REPORT=$(miru time list --from "$MONDAY" --to "$FRIDAY")
PAYLOAD=$(jq -n \
  --arg from "$MONDAY" \
  --arg to "$FRIDAY" \
  --arg report "$REPORT" \
  '{text: ("Weekly time entries: " + $from + " to " + $to + "\n```\n" + $report + "\n```")}')

curl -s -X POST -H 'Content-type: application/json' \
  --data "$PAYLOAD" "$SLACK_WEBHOOK"

Set up a Slack incoming webhook, paste the URL, add to cron. Your week’s entries, posted to the channel. It takes 30 seconds to scan. If your hours look off, you catch it on Friday instead of discovering it during month-end invoicing.


4. End-of-Day Unlogged Commit Checker

This script compares your git commits with your Miru time entries and tells you what you forgot to log. Run it before closing your laptop.

#!/bin/bash
# miru-unlogged-check.sh

echo "=== Unlogged Work Detector ==="
echo "Checking commits from today against Miru entries..."
echo ""

TODAY=$(date +%Y-%m-%d)
LOGGED_MINUTES=$(miru time list --from "$TODAY" --to "$TODAY" | \
  jq '[.entries[][] | select(.type == "timesheet") | .duration] | add // 0')
LOGGED_HOURS=$(awk -v minutes="$LOGGED_MINUTES" 'BEGIN { printf "%.2f", minutes / 60 }')
echo "Total logged today: ${LOGGED_HOURS}h"
echo ""

echo "Commits made today:"
for REPO_DIR in ~/code/*/; do
  if [ -d "$REPO_DIR/.git" ]; then
    REPO_NAME=$(basename "$REPO_DIR")
    COMMITS=$(git -C "$REPO_DIR" log --since=midnight --oneline --author="$(git config user.email)" 2>/dev/null)
    if [ -n "$COMMITS" ]; then
      echo ""
      echo "  $REPO_NAME:"
      echo "$COMMITS" | while read LINE; do
        echo "    $LINE"
      done
    fi
  fi
done

echo ""
if (( $(echo "$LOGGED_HOURS < 4" | bc -l) )); then
  echo "WARNING: Less than 4 hours logged today. Missing something?"
else
  echo "Looks good. ${LOGGED_HOURS}h logged."
fi

The script scans every repo in your code directory, finds today’s commits, and compares them against your logged hours. If you committed to three repos but only logged time on one, you’ll see it. If you logged under 4 hours on a full workday, it flags it.

This is a safety net, not a surveillance tool. Run it yourself, on your own machine. It never reports to anyone but you.


5. Expense Receipt Logger from the Terminal

Conference trip. Client dinner. Software subscription. Log the expense without opening a browser:

#!/bin/bash
# miru-expense.sh - Quick expense logging

echo "--- Quick Expense Logger ---"
read -p "Amount: $" AMOUNT
read -p "Category (software/travel/meals/equipment/other): " CATEGORY
read -p "Vendor: " VENDOR
read -p "Note: " NOTE
miru expense create --amount "$AMOUNT" --category "$CATEGORY" \
  --vendor "$VENDOR" --date "$(date +%Y-%m-%d)" --description "$NOTE"

echo ""
echo "Expense logged: \$$AMOUNT to $CATEGORY ($VENDOR)"

Save it as miru-expense.sh in your path. When you get back from lunch with a client:


6. Jira Day Summary to Miru Draft

Sometimes the fastest workflow is not a shell script. It is a precise prompt to your agent.

Use this when you want Jira work turned into Miru drafts without hand-writing every line:

Pull all work I did in Jira today, summarize it hour by hour when the issue history supports that, or collapse it into one full-day summary when it does not. Use `miru project list` to find the best matching Miru project, then draft the exact `miru time create` commands I should run. Do not submit anything until I approve the draft.

If you want a review-first agent flow that can submit after approval:

Pull all work I did in Jira today, summarize it hour by hour when the issue history supports that, or collapse it into one full-day summary when it does not. Match each block to the best Miru project, show me the draft first, and only after I approve it run the `miru time create` commands.

The key is that the workflow stays auditable:

  • Jira is the source of task history
  • Miru remains the source of billable time
  • the operator still approves the draft before it lands
miru-expense.sh
# Amount: $47.50
# Category: meals
# Vendor: Blue Bottle Coffee
# Note: Client lunch with Acme team
# Expense logged: $47.50 to meals (Blue Bottle Coffee)

Your bookkeeper sees the entry, amount, category, vendor, and description. No email forwarding. No scanning apps. No “I’ll do it later” that becomes “I forgot.”


The Compound Effect

None of these scripts is revolutionary. A git hook. A cron job. A Slack webhook. A shell script. Basic tools that have been around for decades.

But the compound effect is real. The git hook catches 3-5 hours per week. The cron invoicing saves half a day per month. The Slack report catches discrepancies before they become billing disputes. The unlogged checker closes the gap at the end of each day. The expense logger eliminates the “I lost the receipt” problem.

Stack all five together and you’re looking at 10-15 hours per month per team member that used to be wasted on admin overhead or lost to poor tracking. For a 10-person team billing at $100/hour, that’s $10,000-15,000/month in recovered productivity and captured revenue.

Install the CLI. Pick one workflow. Add it today.

curl -fsSL https://miru.so/install.sh | sh

Start with the git hook. Everything else can wait until next week.

Hard Stop

Run this loop for two weeks without skipping cleanup. The compounding effect is real.

Start with Miru or read the docs.

Share:
Vipul A M

Vipul A M

Co-founder at Saeloun. Building Miru. Rails contributor. Shipping from Pune, India.

Put it to work

Run one cleaner billing cycle in Miru.

If this article is about tracking time, billing clients, comparing tools, or automating work, Miru is the product version of that idea. Start for $1/member, invite the team, and send the next invoice from tracked work.

What you get

  • Time tracking, invoices, expenses, and payments in one place.
  • $1 per member per month. Free if you self-host.
  • Open source, with CLI, API, MCP, and self-hosting paths.
See Miru

The article is the argument. Miru is the workflow.

Track the work, approve the hours, send the invoice, and get paid without bolting together three separate tools.

Teams
Miru team management screen with members and roles
Team Miru