Install
openclaw skills install normieclaw-freelancer-toolkitToggl wants you to click Start, remember to click Stop, then manually build a timesheet at month-end. Freelancer Toolkit works the way freelancers actually t...
openclaw skills install normieclaw-freelancer-toolkitAI-powered time tracking, client management, and project profitability for freelancers. Replaces Toggl Track + Harvest. One-time $9.99 via NormieClaw.
Freelancer Toolkit turns your OpenClaw agent into a personal freelance business manager. Track time by talking ("I worked 3 hours on the Acme redesign today"), manage clients and projects, monitor profitability, generate timesheets, and hand off invoices to InvoiceGen Pro — all through conversation.
No timers to click. No forms to fill. No apps to open. Just tell your agent what you did.
All data lives in JSON files under ~/.freelancer-toolkit/:
~/.freelancer-toolkit/
├── settings.json # Global config (default rate, categories, preferences)
├── clients.json # Client database
├── projects.json # Project database
├── time-entries.json # All time entries
├── timers.json # Active timers (start/stop tracking)
└── exports/ # Generated timesheets and reports
settings.json
{
"default_hourly_rate": 75,
"currency": "USD",
"currency_symbol": "$",
"week_start": "monday",
"billing_period": "monthly",
"categories": ["design", "development", "consulting", "meetings", "admin", "writing", "research"],
"non_billable_categories": ["admin", "internal"],
"weekly_summary_day": "monday",
"invoicegen_integration": true,
"rounding": "nearest_quarter"
}
clients.json — Array of client objects:
{
"id": "client_uuid",
"name": "Jane Smith",
"company": "Acme Corp",
"email": "jane@acmecorp.com",
"phone": "555-0123",
"default_rate": 85,
"payment_terms": "net_30",
"notes": "Prefers invoices on the 1st. Always pays on time.",
"status": "active",
"created_at": "2026-01-15T10:00:00Z",
"total_billed": 12400,
"total_paid": 9600,
"tags": ["design", "retainer"]
}
projects.json — Array of project objects:
{
"id": "proj_uuid",
"client_id": "client_uuid",
"name": "Website Redesign",
"description": "Full redesign of acmecorp.com",
"status": "active",
"billing_type": "fixed",
"quoted_price": 5000,
"hourly_rate": 85,
"estimated_hours": 60,
"hours_logged": 42.5,
"effective_rate": 117.65,
"budget_alert_threshold": 0.8,
"milestones": [
{"name": "Wireframes", "status": "completed", "due_date": "2026-02-01"},
{"name": "Visual Design", "status": "in_progress", "due_date": "2026-03-01"},
{"name": "Development", "status": "pending", "due_date": "2026-04-01"}
],
"created_at": "2026-01-10T10:00:00Z",
"completed_at": null,
"tags": ["web", "design"]
}
time-entries.json — Array of time entry objects:
{
"id": "entry_uuid",
"client_id": "client_uuid",
"project_id": "proj_uuid",
"date": "2026-03-10",
"hours": 3.0,
"description": "Logo concept exploration, 3 directions",
"category": "design",
"billable": true,
"invoiced": false,
"invoice_id": null,
"created_at": "2026-03-10T17:30:00Z"
}
timers.json — Active timer state:
{
"active": true,
"client_id": "client_uuid",
"project_id": "proj_uuid",
"description": "Working on homepage layout",
"category": "design",
"started_at": "2026-03-10T14:00:00Z",
"paused_at": null,
"accumulated_minutes": 0
}
On first use or when data files don't exist:
~/.freelancer-toolkit/ directorysettings.json from the skill's config/ directoryclients.json, projects.json, time-entries.jsontimers.json with {"active": false}exports/ directorymkdir -p ~/.freelancer-toolkit/exports
If settings.json already exists, never overwrite — the user may have customized it.
This is the flagship feature. Parse natural language into structured time entries.
Input patterns to recognize:
| User says | Parsed result |
|---|---|
| "I worked 3 hours on the Acme redesign today" | client: Acme, project: redesign, hours: 3, date: today |
| "Just finished 2.5 hours of consulting with BrightPath" | client: BrightPath, hours: 2.5, category: consulting, date: today |
| "Yesterday I spent 45 minutes on admin for Johnson & Co" | client: Johnson & Co, hours: 0.75, category: admin, date: yesterday |
| "4 hrs Acme, homepage wireframes" | client: Acme, hours: 4, description: homepage wireframes |
| "Logged 1 hour meeting with Sarah at Nova Labs" | client: Nova Labs, hours: 1, category: meetings |
| "6 hours last Friday on the BrightPath app" | client: BrightPath, hours: 6, date: last Friday |
Parsing rules:
clients.json. "Acme" matches "Acme Corp". If ambiguous, ask.non_billable_categories.settings.json.Always confirm before saving:
✅ Logged: 3.00 hrs — Acme Corp → Website Redesign
"Homepage wireframe revisions"
Date: March 10, 2026 | Billable | Rate: $85/hr ($255.00)
Unknown client/project: Offer to create on the fly. Ask for rate at minimum.
For users who prefer real-time tracking:
Starting a timer:
While running: Store state in timers.json. If user starts a new timer, stop and log the current one first.
Stopping: "Stop tracking" / "Stop timer" → Calculate elapsed, round per settings, confirm and log. Prompt for description.
Pausing: "Pause timer" saves accumulated time. "Resume" continues.
Adding a client:
Viewing clients:
Client detail view: Show contact info, rate, terms, active/completed project counts, total billed/paid/outstanding, and notes.
Editing: "Update Acme's rate to $95/hr", "Archive the Johnson account", etc.
Client memory: Proactively surface relevant context — last activity date, payment patterns ("BrightPath usually pays late"), average project size.
Creating a project:
Project fields:
billing_type: "fixed" (quoted price) or "hourly" (open-ended)status: "active", "paused", "completed"quoted_price and estimated_hourshours_logged and calculate effective_rateViewing projects:
Project detail view: Show status, billing type, hours vs estimate with percentage, effective rate, milestones with status, and recent time entries.
Updating: Support milestone completion, status changes (pause/complete), and scope adjustments. When marking complete, calculate final profitability and update client totals.
Per-project profitability (fixed-price projects):
Calculate effective_rate = quoted_price / hours_logged.
Budget alerts — proactive, triggered when logging time:
budget_alert_threshold (default 80%): ⚠️ warning with remaining hours, effective rate, and pace estimateCross-project analysis:
Summary format: List each active project with effective rate, status indicator (✅/⚠️/🚨), and weighted average across all projects vs target rate.
Generate timesheets on demand:
Markdown format: Table with Date, Client, Project, Hours, Description, Billable columns. Totals at bottom split by billable/non-billable with dollar amounts.
CSV export: Run scripts/export-timesheet.sh --start YYYY-MM-DD --end YYYY-MM-DD [--client "Name"]. Output to ~/.freelancer-toolkit/exports/. Columns: date,client,project,hours,description,category,billable,rate,amount.
Trigger invoice generation:
Process:
{
"client": {
"name": "Acme Corp",
"contact": "Jane Smith",
"email": "jane@acmecorp.com"
},
"payment_terms": "net_30",
"line_items": [
{
"description": "Website Redesign — Visual design concepts and revisions",
"hours": 12.5,
"rate": 85,
"amount": 1062.50
},
{
"description": "Website Redesign — Development and testing",
"hours": 8.0,
"rate": 85,
"amount": 680.00
}
],
"subtotal": 1742.50,
"total": 1742.50,
"period": "March 2026"
}
invoiced: true and store invoice_idtotal_billedIf InvoiceGen Pro is not installed: Export as JSON to ~/.freelancer-toolkit/exports/invoice-{client}-{period}.json and suggest installing it.
Delivered every Monday (or configured day). Contains:
Manual trigger: "Give me my weekly summary" or "How did last week look?"
The dashboard kit exposes these widgets via dashboard-kit/manifest.json:
Data sources: Read from ~/.freelancer-toolkit/*.json files.
See dashboard-kit/DASHBOARD-SPEC.md for full widget specifications.
These are conversational triggers, not slash commands. The agent recognizes intent.
| User intent | Example |
|---|---|
| Log time | "I worked 3 hours on Acme today" |
| Log with details | "2.5 hrs BrightPath, API integration and testing" |
| Log past date | "Yesterday I did 4 hours on Nova Labs brand guide" |
| Start timer | "Start tracking Acme redesign" |
| Stop timer | "Stop tracking" |
| Pause timer | "Pause timer" |
| Resume timer | "Resume" |
| Check timer | "How long have I been tracking?" |
| Edit entry | "Change today's Acme entry to 3.5 hours" |
| Delete entry | "Delete the Nova Labs entry from yesterday" |
| User intent | Example |
|---|---|
| Add client | "New client: Sarah Chen, Nova Labs, $95/hr, net 15" |
| List clients | "Show my clients" |
| Client details | "Tell me about Acme" |
| Update client | "Update Acme's rate to $100/hr" |
| Archive client | "Archive Johnson & Co" |
| User intent | Example |
|---|---|
| Create project | "New project for Acme: Logo Refresh, $2,000 fixed, ~25 hours" |
| List projects | "Show active projects" |
| Project status | "How's the Acme redesign going?" |
| Update milestone | "Mark Acme wireframes as done" |
| Complete project | "The BrightPath app is finished" |
| Pause project | "Pause the Nova Labs project" |
| User intent | Example |
|---|---|
| Weekly timesheet | "Show me last week's timesheet" |
| Monthly timesheet | "March timesheet" |
| Client timesheet | "Timesheet for Acme, February" |
| Export CSV | "Export March timesheet as CSV" |
| Generate invoice | "Invoice Acme for March" |
| Profitability | "How am I doing on profitability?" |
| Weekly summary | "Give me my weekly summary" |
| Client report | "Billing summary for BrightPath" |
*.backup, re-initialize, and alert the user.export-timesheet.sh scriptEdit ~/.freelancer-toolkit/settings.json to customize:
default_hourly_rate: Applied to new clients unless overridden (default: 75)currency / currency_symbol: Currency for display (default: "USD" / "$")week_start: "monday" or "sunday" (default: "monday")billing_period: "weekly", "biweekly", or "monthly" (default: "monthly")categories: List of time entry categoriesnon_billable_categories: Categories that default to non-billableweekly_summary_day: Day of week for auto-summary (default: "monday")invoicegen_integration: Enable InvoiceGen Pro handoff (default: true)rounding: "none", "nearest_quarter", "nearest_tenth", "round_up_quarter" (default: "nearest_quarter")| File | Path |
|---|---|
| Settings | ~/.freelancer-toolkit/settings.json |
| Clients | ~/.freelancer-toolkit/clients.json |
| Projects | ~/.freelancer-toolkit/projects.json |
| Time entries | ~/.freelancer-toolkit/time-entries.json |
| Active timer | ~/.freelancer-toolkit/timers.json |
| Exports | ~/.freelancer-toolkit/exports/ |
| Setup script | <skill_dir>/scripts/setup.sh |
| Export script | <skill_dir>/scripts/export-timesheet.sh |
| Report script | <skill_dir>/scripts/client-report.sh |