qualia-framework 4.4.0 → 4.5.0

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.
@@ -154,21 +154,41 @@ PAYLOAD=$(
154
154
  REPORT_FILE="$REPORT_FILE" \
155
155
  node -e "
156
156
  const fs = require('fs');
157
+ const path = require('path');
158
+ const os = require('os');
159
+ const { spawnSync } = require('child_process');
160
+ const git = (args) => {
161
+ const r = spawnSync('git', args, { encoding: 'utf8', timeout: 3000 });
162
+ return r.status === 0 ? r.stdout.trim() : '';
163
+ };
164
+ const repoSlug = (remote) => (remote || '')
165
+ .replace(/^git@github\\.com:/, 'github.com/')
166
+ .replace(/^https?:\\/\\//, '')
167
+ .replace(/\\.git$/, '')
168
+ .split('/')
169
+ .filter(Boolean)
170
+ .pop();
171
+ let config = {};
172
+ try {
173
+ config = JSON.parse(fs.readFileSync(path.join(os.homedir(), '.claude/.qualia-config.json'), 'utf8'));
174
+ } catch {}
157
175
  const t = JSON.parse(fs.readFileSync('.planning/tracking.json', 'utf8'));
158
176
  const notes = fs.readFileSync(process.env.REPORT_FILE, 'utf8').substring(0, 60000);
159
177
  const commits = [];
160
178
  try {
161
- const { spawnSync } = require('child_process');
162
179
  const r = spawnSync('git', ['log', '--oneline', '--since=8 hours ago', '--format=%h'], { encoding: 'utf8', timeout: 3000 });
163
180
  if (r.stdout) commits.push(...r.stdout.trim().split('\n').filter(Boolean));
164
181
  } catch {}
182
+ const gitRemote = t.git_remote || git(['config', '--get', 'remote.origin.url']);
183
+ const projectKey = t.project_id || repoSlug(gitRemote) || require('path').basename(process.cwd());
165
184
  console.log(JSON.stringify({
166
185
  project: t.project || require('path').basename(process.cwd()),
167
- project_id: t.project_id || '',
168
- team_id: t.team_id || '',
169
- git_remote: t.git_remote || '',
186
+ project_id: projectKey,
187
+ team_id: t.team_id || 'qualia-solutions',
188
+ git_remote: gitRemote,
170
189
  client: t.client || '',
171
190
  client_report_id: process.env.CLIENT_REPORT_ID,
191
+ framework_version: config.version || '',
172
192
  milestone: t.milestone || 1,
173
193
  milestone_name: t.milestone_name || '',
174
194
  milestones: Array.isArray(t.milestones) ? t.milestones : [],
@@ -0,0 +1,64 @@
1
+ ---
2
+ name: zoho-workflow
3
+ description: Zoho Invoice and Mail operations - create invoices, send emails, manage contacts. Use when Fawzi mentions invoicing, email, or Zoho.
4
+ tags: [zoho, invoice, email, billing, crm]
5
+ ---
6
+
7
+ # Zoho Workflow
8
+
9
+ ## Route invoicing through the ERP first
10
+
11
+ The Qualia ERP at `https://portal.qualiasolutions.net` owns the canonical invoice workflow. **Use it before reaching for raw Zoho MCP tools.**
12
+
13
+ For any "invoice X" request, the order of preference is:
14
+
15
+ 1. **ERP MCP** (preferred): `mcp__qualia-erp__create_invoice_draft` + `mcp__qualia-erp__create_invoice_cover_email_draft`. These wrap Zoho with the right templates, terms, VAT treatment, and matching cover email. Templates: `monthly_retainer` (Underdog pattern — retainer + SEO + usage credit), `simple_service` (Maison Maud / Armenius pattern — single line), `project_deposit` (50% upfront, requires proposal ref), `project_balance` (final 50%).
16
+ 2. **ERP UI** (when Fawzi is at his desk): `https://portal.qualiasolutions.net/admin?tab=finance` → "New invoice from template" button.
17
+ 3. **Raw Zoho Books MCP** (`mcp__claude_ai_Zoho_Books__*`): only for things the ERP doesn't expose yet — voiding, editing existing invoices, recording payments, expenses, contact management.
18
+
19
+ The full handoff runbook lives in the qualia-erp repo: `docs/finance-runbook.md`. It covers once-per-client setup, the 4 templates, the bulk monthly batch, and common errors.
20
+
21
+ **Why this matters:** the ERP knows the client → Zoho contact_id mapping, the right tax treatment (Cyprus 19% / non-EU 0%), and the canonical terms templates. Calling Zoho directly bypasses all of that and reintroduces the manual hand-stitching the ERP was built to replace.
22
+
23
+ ## Zoho Invoice
24
+
25
+ - Create, edit, send, and void invoices
26
+ - List and search invoices by client, status, date
27
+ - Manage items, taxes, contacts, and expenses
28
+ - Mark invoices as sent/paid, send payment reminders
29
+ - Generate invoice PDFs and email them to clients
30
+ - Create recurring invoices and credit notes
31
+ - When Fawzi says "invoice [client]" — create the full invoice, don't just explain how
32
+ - Default sender org: Qualia Solutions
33
+
34
+ ## Zoho Mail
35
+
36
+ - Read inbox, sent, drafts, and folder contents
37
+ - Send emails and reply to threads
38
+ - Move, label, and organize messages
39
+ - Search emails by sender, subject, date
40
+ - When Fawzi says "email [someone]" or "check inbox" — do it directly
41
+ - Use Fawzi's primary Zoho Mail account
42
+
43
+ ## Email Formatting Rules (MANDATORY)
44
+
45
+ - Always append Fawzi's signature at the bottom of every email
46
+ - Read signature HTML from `~/.claude/knowledge/email-signature.html`
47
+ - Never use dashes (---) or horizontal separators
48
+ - Never use emojis
49
+ - Professional, direct tone
50
+ - Keep it concise and action-oriented
51
+
52
+ ## General Rules
53
+
54
+ - Always act, don't just describe. Execute operations directly.
55
+ - Fetch the organization ID first if needed (use the list/get org tools)
56
+ - If a tool call fails, debug it — check params, retry with fixes
57
+
58
+ ## Trigger Phrases
59
+
60
+ - "invoice [client]" → Create and send invoice
61
+ - "email [someone]" → Compose and send email
62
+ - "check inbox" → Read inbox
63
+ - "send reminder" → Payment reminder
64
+ - "create contact" → New Zoho contact