axis-crm 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +98 -74
- package/package.json +1 -1
- package/template/automations/client-research.json +1 -1
- package/template/automations/fireflies-to-crm.json +1 -1
- package/template/clients/acme-consulting/projects/web-redesign/{zadani.md → brief.md} +1 -1
- package/template/rules/structure.md +4 -4
- package/template/scripts/convert-to-client.sh +3 -3
- package/template/scripts/new-project.sh +8 -8
- package/template/templates/project/{zadani.md → brief.md} +1 -1
- /package/template/clients/acme-consulting/files/{faktury → contracts}/.gitkeep +0 -0
- /package/template/clients/acme-consulting/files/{nabidky → invoices}/.gitkeep +0 -0
- /package/template/clients/acme-consulting/files/{smlouvy → proposals}/.gitkeep +0 -0
- /package/template/templates/client/files/{faktury → contracts}/.gitkeep +0 -0
- /package/template/templates/client/files/{nabidky → invoices}/.gitkeep +0 -0
- /package/template/templates/client/files/{smlouvy → proposals}/.gitkeep +0 -0
package/README.md
CHANGED
|
@@ -2,90 +2,123 @@
|
|
|
2
2
|
|
|
3
3
|
A git-based CRM for freelancers and small teams.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Manage your clients, projects, meetings, contacts, rates, and files — all as Markdown in a git repo. No database, no SaaS, no vendor lock-in.
|
|
6
|
+
|
|
7
|
+
Works in any text editor. Optimized for [Obsidian](https://obsidian.md) with Dataview dashboards. Supports automation through n8n workflows.
|
|
8
|
+
|
|
9
|
+
## Quick Start
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npx axis-crm init
|
|
13
|
+
cd crm
|
|
14
|
+
git init && git add -A && git commit -m "init: axis-crm"
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
That's it. You have a working CRM. Open in Obsidian and open `CRM Dashboard.md`.
|
|
6
18
|
|
|
7
19
|
## Why
|
|
8
20
|
|
|
9
|
-
|
|
21
|
+
You're a freelancer. You have 5-10 clients. You need to know:
|
|
22
|
+
|
|
23
|
+
- Who are my contacts at each client?
|
|
24
|
+
- What projects am I working on and what's their status?
|
|
25
|
+
- What did we agree on in the last meeting?
|
|
26
|
+
- What's my hourly rate for this client?
|
|
27
|
+
- Where's the contract?
|
|
28
|
+
|
|
29
|
+
You don't need Salesforce, HubSpot, or a $50/month tool. You need a folder structure that makes sense, with version history and zero maintenance.
|
|
10
30
|
|
|
11
31
|
Axis CRM gives you:
|
|
12
|
-
- **Full ownership** — your data lives in a git repo, not someone else's server
|
|
13
|
-
- **Version history** — every change is a commit, every deleted lead is recoverable
|
|
14
|
-
- **Markdown-native** — works with Obsidian, VS Code, Vim, or any editor
|
|
15
|
-
- **Automation-ready** — n8n workflows for meeting transcripts and client research
|
|
16
|
-
- **AI-friendly** — CLAUDE.md included, works with Claude Code and other AI tools out of the box
|
|
17
32
|
|
|
18
|
-
|
|
33
|
+
- **One folder per client** — contacts, meetings, projects, communication, files, all in one place
|
|
34
|
+
- **Billing rates** — track hourly/daily rates per client in frontmatter
|
|
35
|
+
- **Meeting notes** — auto-saved from Fireflies via n8n (or add manually)
|
|
36
|
+
- **Project tracking** — scope, briefs, deliverables, timeline per project
|
|
37
|
+
- **Version history** — every change is a git commit, nothing is ever lost
|
|
38
|
+
- **Dashboards** — Obsidian Dataview queries show you everything at a glance
|
|
39
|
+
- **AI-ready** — CLAUDE.md included, works with Claude Code and Cursor out of the box
|
|
40
|
+
|
|
41
|
+
## What a Client Looks Like
|
|
19
42
|
|
|
20
43
|
```
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
44
|
+
clients/acme-consulting/
|
|
45
|
+
README.md # overview, status, rates, industry
|
|
46
|
+
contacts/
|
|
47
|
+
jana-novakova.md # name, role, email, phone, notes
|
|
48
|
+
tomas-dvorak.md
|
|
49
|
+
meetings/
|
|
50
|
+
2026-02-10-kickoff.md # agenda, notes, action items, transcript
|
|
51
|
+
2026-03-15-review.md
|
|
52
|
+
projects/
|
|
53
|
+
web-redesign/
|
|
54
|
+
README.md # scope, timeline, status, value
|
|
55
|
+
brief.md # client brief
|
|
56
|
+
deliverables/
|
|
57
|
+
notes/
|
|
58
|
+
communication/
|
|
59
|
+
2026-03-01-price-agreed.md # key decisions and agreements
|
|
60
|
+
files/
|
|
61
|
+
contracts/
|
|
62
|
+
proposals/
|
|
63
|
+
invoices/
|
|
37
64
|
```
|
|
38
65
|
|
|
39
|
-
|
|
66
|
+
Every file uses YAML frontmatter for structured data. Git gives you the history.
|
|
40
67
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
68
|
+
## Billing Rates
|
|
69
|
+
|
|
70
|
+
Track what each client pays you:
|
|
71
|
+
|
|
72
|
+
```yaml
|
|
73
|
+
# in clients/acme-consulting/README.md frontmatter
|
|
74
|
+
hourly_rate: 120
|
|
75
|
+
manday_rate: 960
|
|
76
|
+
currency: 'USD'
|
|
45
77
|
```
|
|
46
78
|
|
|
47
|
-
|
|
79
|
+
Query across all clients in Obsidian: "show me clients sorted by hourly rate" — just works with Dataview.
|
|
48
80
|
|
|
49
|
-
|
|
81
|
+
## Structure
|
|
50
82
|
|
|
51
|
-
Create your first lead:
|
|
52
|
-
```bash
|
|
53
|
-
./scripts/new-lead.sh "Acme Corp"
|
|
54
83
|
```
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
84
|
+
axis-crm/
|
|
85
|
+
clients/ # each client = a folder (the core of the CRM)
|
|
86
|
+
leads/ # potential clients (optional pipeline)
|
|
87
|
+
templates/ # templates for clients, contacts, meetings, projects
|
|
88
|
+
rules/ # field definitions, folder structure docs
|
|
89
|
+
scripts/ # shell scripts for common operations
|
|
90
|
+
automations/ # n8n workflow exports (meeting notes, research)
|
|
91
|
+
dashboards/ # Obsidian Dataview dashboards
|
|
92
|
+
CRM Dashboard.md # main overview
|
|
93
|
+
CLAUDE.md # AI agent instructions
|
|
59
94
|
```
|
|
60
95
|
|
|
61
96
|
## Scripts
|
|
62
97
|
|
|
63
|
-
| Script |
|
|
64
|
-
| --- | --- |
|
|
65
|
-
| `new-
|
|
66
|
-
| `
|
|
67
|
-
| `new-
|
|
68
|
-
| `
|
|
69
|
-
|
|
70
|
-
All scripts support `--help` or will prompt interactively when run without flags.
|
|
98
|
+
| Script | What it does |
|
|
99
|
+
| --- | --- |
|
|
100
|
+
| `new-project.sh` | Create a new project for a client |
|
|
101
|
+
| `validate.sh` | Check all clients for required fields and structure |
|
|
102
|
+
| `new-lead.sh` | Create a new lead (for the optional pipeline) |
|
|
103
|
+
| `convert-to-client.sh` | Convert a lead into a full client folder |
|
|
71
104
|
|
|
72
|
-
|
|
105
|
+
```bash
|
|
106
|
+
# Add a new project to a client
|
|
107
|
+
./scripts/new-project.sh acme-consulting "Mobile App"
|
|
73
108
|
|
|
74
|
-
|
|
75
|
-
|
|
109
|
+
# Validate your CRM data
|
|
110
|
+
./scripts/validate.sh
|
|
76
111
|
```
|
|
77
112
|
|
|
78
|
-
Each stage has required fields and a score threshold. Leads are scored 0-100 based on data completeness, industry fit, and engagement. Details in `rules/lifecycle.md` and `rules/scoring.md`.
|
|
79
|
-
|
|
80
113
|
## Automations
|
|
81
114
|
|
|
82
|
-
Two n8n workflows are included
|
|
115
|
+
Two optional n8n workflows are included:
|
|
83
116
|
|
|
84
|
-
|
|
117
|
+
**Meeting to CRM** — Fireflies records a meeting, webhook fires, AI (Claude) identifies the client, extracts a summary and action items, and commits the meeting notes to the right client folder. Automatically.
|
|
85
118
|
|
|
86
|
-
|
|
119
|
+
**Client Research** — Send a company name + website URL, get back a structured client profile with contacts, services, and business registry data.
|
|
87
120
|
|
|
88
|
-
Setup
|
|
121
|
+
Setup: [`automations/README.md`](automations/README.md)
|
|
89
122
|
|
|
90
123
|
## Dashboards
|
|
91
124
|
|
|
@@ -93,30 +126,21 @@ Requires Obsidian + [Dataview plugin](https://github.com/blacksmithgu/obsidian-d
|
|
|
93
126
|
|
|
94
127
|
| Dashboard | Shows |
|
|
95
128
|
| --- | --- |
|
|
96
|
-
| `CRM Dashboard.md` | Active clients,
|
|
97
|
-
| `dashboards/
|
|
98
|
-
| `dashboards/
|
|
99
|
-
| `dashboards/
|
|
129
|
+
| `CRM Dashboard.md` | Active clients, recent meetings, overview |
|
|
130
|
+
| `dashboards/client-overview.md` | All clients with status, priority, rates |
|
|
131
|
+
| `dashboards/pipeline.md` | Lead pipeline by stage (if using leads) |
|
|
132
|
+
| `dashboards/hot-leads.md` | High-score leads ready for outreach |
|
|
100
133
|
|
|
101
|
-
##
|
|
134
|
+
## Lead Pipeline (Optional)
|
|
102
135
|
|
|
103
|
-
|
|
136
|
+
If you also want to track potential clients before they become clients:
|
|
104
137
|
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
manday_rate: 800
|
|
108
|
-
currency: 'USD'
|
|
138
|
+
```
|
|
139
|
+
new → enriched → qualified → contacted → responded → opportunity → client
|
|
109
140
|
```
|
|
110
141
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
## Rules
|
|
114
|
-
|
|
115
|
-
- A lead is a file. A client is a folder. Conversion is one-way.
|
|
116
|
-
- Lead scoring: 0-100, thresholds define when a lead is ready for outreach.
|
|
117
|
-
- All records use YAML frontmatter. Required fields depend on the lifecycle stage.
|
|
118
|
-
- Details: [`rules/`](rules/)
|
|
142
|
+
Leads are scored 0-100. When a lead converts, run `convert-to-client.sh` and it becomes a full client folder. Details in `rules/`.
|
|
119
143
|
|
|
120
144
|
## License
|
|
121
145
|
|
|
122
|
-
MIT
|
|
146
|
+
MIT — use it, fork it, make it yours.
|
package/package.json
CHANGED
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"typeVersion": 2,
|
|
57
57
|
"position": [1050, 300],
|
|
58
58
|
"parameters": {
|
|
59
|
-
"jsCode": "const data = $input.first().json;\n\nconst prompt = `
|
|
59
|
+
"jsCode": "const data = $input.first().json;\n\nconst prompt = `Analyze the company and create a structured profile.\n\nCompany: ${data.companyName}\nWebsite: ${data.website}\nEmails found on website: ${data.extractedEmails.join(', ')}\nPhones found on website: ${data.extractedPhones.join(', ')}\n\nWebsite content (5000 chars):\n${data.textContent.substring(0, 5000)}\n\nRespond with ONLY valid JSON:\n{\n \"company_name\": \"Official name\",\n \"description\": \"1-2 sentences about what the company does\",\n \"industry\": \"industry\",\n \"services\": [\"service1\", \"service2\"],\n \"city\": \"city\",\n \"country\": \"CZ/SK/DE/AT/...\",\n \"size_estimate\": \"micro/small/medium/large\",\n \"contacts\": [{\"name\": \"Name\", \"role\": \"position\", \"email\": \"email\", \"phone\": \"phone\"}],\n \"social\": {\"linkedin\": \"\", \"facebook\": \"\"},\n \"web_quality\": \"modern/outdated/basic\",\n \"notes\": \"additional notes\"\n}`;\n\nreturn [{\n json: {\n ...data,\n aiRequestBody: JSON.stringify({\n model: 'claude-sonnet-4-20250514',\n max_tokens: 1024,\n messages: [{ role: 'user', content: prompt }]\n })\n }\n}];"
|
|
60
60
|
}
|
|
61
61
|
},
|
|
62
62
|
{
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"typeVersion": 2,
|
|
48
48
|
"position": [850, 300],
|
|
49
49
|
"parameters": {
|
|
50
|
-
"jsCode": "const data = $input.first().json;\n\nconst prompt = `
|
|
50
|
+
"jsCode": "const data = $input.first().json;\n\nconst prompt = `Analyze this meeting and identify which client it belongs to.\n\nMeeting: ${data.title}\nParticipants: ${data.participants.join(', ')}\nSummary: ${data.summary}\nTranscript (first 2000 chars):\n${data.transcript.substring(0, 2000)}\n\nRespond with ONLY valid JSON (no markdown code blocks):\n{\n \"client_slug\": \"company-name-lowercase-dashes-no-legal-suffix\",\n \"client_name\": \"Official company name\",\n \"is_new\": true,\n \"attendees\": [\"name1\", \"name2\"],\n \"summary\": \"2-3 sentences about what was discussed\",\n \"action_items\": [\"task1\", \"task2\"],\n \"topics\": [\"topic1\", \"topic2\"]\n}`;\n\nreturn [{\n json: {\n ...data,\n aiRequestBody: JSON.stringify({\n model: 'claude-sonnet-4-20250514',\n max_tokens: 1024,\n messages: [{ role: 'user', content: prompt }]\n })\n }\n}];"
|
|
51
51
|
}
|
|
52
52
|
},
|
|
53
53
|
{
|
|
@@ -13,7 +13,7 @@ clients/company-name/
|
|
|
13
13
|
contacts/ # people from the company
|
|
14
14
|
jan-novak.md # contact person
|
|
15
15
|
communication/ # key decisions and communication
|
|
16
|
-
2026-04-10-
|
|
16
|
+
2026-04-10-price-agreed.md
|
|
17
17
|
files/ # documents
|
|
18
18
|
contracts/ # signed contracts, NDAs, amendments
|
|
19
19
|
proposals/ # price quotes, proposals
|
|
@@ -23,7 +23,7 @@ clients/company-name/
|
|
|
23
23
|
projects/ # projects for the client
|
|
24
24
|
project-name/ # each project = folder
|
|
25
25
|
README.md # scope, status, timeline
|
|
26
|
-
|
|
26
|
+
brief.md # brief from the client
|
|
27
27
|
deliverables/ # outputs
|
|
28
28
|
notes/ # ongoing notes
|
|
29
29
|
```
|
|
@@ -43,7 +43,7 @@ Important decisions and communication. NOT every email — only what changes dir
|
|
|
43
43
|
|
|
44
44
|
- Filename format: `YYYY-MM-DD-description.md`
|
|
45
45
|
- Frontmatter: date, channel (email/call/chat), participants, decision
|
|
46
|
-
- Example: `2026-04-10-
|
|
46
|
+
- Example: `2026-04-10-price-agreed.md` — client approved the quote
|
|
47
47
|
|
|
48
48
|
### files/
|
|
49
49
|
|
|
@@ -69,7 +69,7 @@ Meeting notes.
|
|
|
69
69
|
Each project = its own folder.
|
|
70
70
|
|
|
71
71
|
- `README.md` — scope, status, timeline, deliverables
|
|
72
|
-
- `
|
|
72
|
+
- `brief.md` — original brief from the client
|
|
73
73
|
- `deliverables/` — final outputs
|
|
74
74
|
- `notes/` — ongoing notes, drafts
|
|
75
75
|
|
|
@@ -70,9 +70,9 @@ mkdir -p "$CLIENT_DIR/contacts"
|
|
|
70
70
|
mkdir -p "$CLIENT_DIR/projects"
|
|
71
71
|
mkdir -p "$CLIENT_DIR/meetings"
|
|
72
72
|
mkdir -p "$CLIENT_DIR/communication"
|
|
73
|
-
mkdir -p "$CLIENT_DIR/files/
|
|
74
|
-
mkdir -p "$CLIENT_DIR/files/
|
|
75
|
-
mkdir -p "$CLIENT_DIR/files/
|
|
73
|
+
mkdir -p "$CLIENT_DIR/files/contracts"
|
|
74
|
+
mkdir -p "$CLIENT_DIR/files/proposals"
|
|
75
|
+
mkdir -p "$CLIENT_DIR/files/invoices"
|
|
76
76
|
|
|
77
77
|
# Create README.md from template with lead data
|
|
78
78
|
sed -e "s|^title: ''|title: \"$TITLE\"|" \
|
|
@@ -51,19 +51,19 @@ sed -i '' \
|
|
|
51
51
|
-e "s|^start: ''|start: '$TODAY'|" \
|
|
52
52
|
"$PROJECT_DIR/README.md"
|
|
53
53
|
|
|
54
|
-
# Fill in
|
|
54
|
+
# Fill in brief.md
|
|
55
55
|
sed -i '' \
|
|
56
|
-
-e "s|^title: '
|
|
56
|
+
-e "s|^title: 'Brief — '|title: 'Brief — $PROJECT_NAME'|" \
|
|
57
57
|
-e "s|^created: ''|created: '$TODAY'|" \
|
|
58
|
-
"$PROJECT_DIR/
|
|
58
|
+
"$PROJECT_DIR/brief.md"
|
|
59
59
|
|
|
60
60
|
echo "Project created: $PROJECT_DIR/"
|
|
61
61
|
echo ""
|
|
62
62
|
echo " README.md — scope, status, timeline"
|
|
63
|
-
echo "
|
|
64
|
-
echo " deliverables/ —
|
|
65
|
-
echo " notes/ —
|
|
63
|
+
echo " brief.md — client brief"
|
|
64
|
+
echo " deliverables/ — outputs"
|
|
65
|
+
echo " notes/ — ongoing notes"
|
|
66
66
|
echo ""
|
|
67
67
|
echo "Next steps:"
|
|
68
|
-
echo " 1.
|
|
69
|
-
echo " 2.
|
|
68
|
+
echo " 1. Fill in brief.md with client requirements"
|
|
69
|
+
echo " 2. Add scope and timeline to README.md"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|