| name | ag-copro |
| description | Ingest a French Assemblée Générale (AG) PDF and generate an interactive HTML report (Tailwind + Chart.js) with meeting info, résolutions, year-over-year budget, travaux progress, and a 5-point pre-vote briefing. Don't use for non-AG French docs (acte, bail), tax files, or non-French copropriété. |
| metadata | {"version":"1.3.0","author":"francais-skills"} |
ag-copro — Assemblée Générale assistant for French house owners
Helps a copropriétaire understand the annual AG convocation document: extract the meeting info, audit the budget, flag what needs attention before voting — and produce a single self-contained interactive HTML report the user can open in any browser. Then answers follow-up questions from that report.
When this skill triggers
- User shares a French AG PDF (e.g. "convocation assemblée générale", "ordre du jour", "résolutions").
- User asks "when is my AG meeting?", "what's the new budget?", "what am I voting on?", "explain résolution N°7", "compare last year vs next year budget".
- User asks for the HTML report / rapport interactif / export HTML of an AG they've already ingested.
- User invokes
/ag-copro with or without a path.
Do not trigger for: French legal documents that aren't AG convocations (acte de vente, bail, état des lieux), tax/fiscal documents, non-French copropriété files.
Output: one interactive HTML file
The skill writes a single self-contained HTML file to the user's current working directory:
./ag-<residence-slug>-<year>.html
That file:
- Renders with TailwindCSS (Play CDN) and Chart.js — open in any modern browser; no build, no server.
- Shows hero KPIs, a 5-point briefing, a filterable résolutions table, a Y-o-Y budget chart, top-variation account lines, travaux progress donut, and owner-specific cards.
- Embeds the full structured data as JSON inside
<script type="application/json" id="ag-data">…</script> — this is the source of truth for both the visualization AND for Query mode.
- Cites the source PDF: each résolution, budget figure, briefing point, and travaux entry carries a clickable
p. N chip that opens the original PDF at the right page (via the browser's built-in PDF viewer, #page=N deep link). A "PDF source" button in the header opens the whole file.
- Supports print to PDF (
Imprimer / PDF button hides interactive controls).
There is no separate markdown summary. The HTML is both the report and the storage format.
Workflow (single entry, two internal modes)
The skill has one entry point but two operating modes. Decide which by looking at inputs:
- No HTML report loaded yet → Ingest mode. Read the PDF, extract structured data, render the HTML, save it to CWD, then proceed to query mode with the JSON data in hand.
- HTML report loaded → Query mode. Answer the user's question from the embedded JSON. Never re-read the PDF unless the user explicitly asks ("re-extract", "re-ingest", "the report is wrong").
Routing — decide mode at start of every turn
1. Was a PDF path provided?
- Yes → compute output filename; if it exists in CWD and is fresh, jump to Query mode.
Otherwise enter Ingest mode.
2. Was an HTML report path or residence name provided?
- Yes → load that HTML, parse the embedded JSON, jump to Query mode.
3. Nothing provided?
- Glob CWD for `ag-*.html`.
- If 1+ reports exist: ask the user to pick one, OR provide a new PDF path.
- If none in CWD, also check `~/.ag-copro/summaries/` for legacy `*.md` files
and offer to re-render them as HTML.
- If both are empty: ask the user for a PDF path.
Storage
The report is written to the current working directory where the skill was invoked — ./ag-<slug>-<year>.html. CWD is the user's choice (cd to wherever you want output to land).
Filename slug rules:
- Strip accents (
é → e).
- Lowercase.
- Replace non-alphanumeric with hyphens; collapse consecutive hyphens.
- Truncate to 50 chars.
- Year is the meeting year (4 digits).
Examples:
- "LE VERGER À PALAISEAU", meeting 16/06/2026 →
ag-le-verger-a-palaiseau-2026.html
- "17 RUE PHILIPPE DE DANGEAU", meeting 14/05/2025 →
ag-17-rue-philippe-de-dangeau-2025.html
If a file with the same name already exists in CWD, ask before overwriting — the user may want to keep the old version for comparison.
The legacy folder ~/.ag-copro/summaries/ is no longer written to. If it exists with old .md files from previous skill versions, leave them alone unless the user explicitly asks to migrate.
Ingest mode — extracting the AG PDF
Full playbook: see references/ingest.md. Quick version:
- Read the PDF (use the
Read tool, paging through if >20 pages — most AGs run 30–60 pages). Track the page number every time you extract a fact — the reader returns 1-indexed page markers, store them on the matching JSON record.
- Identify the syndic (Immo de France, VPàt Immo, Foncia, Loiselet & Daigremont, etc.) so layout assumptions don't bite. Look for the logo block and the contract holder in the first 2 pages.
- Extract the data needed to fill the JSON schema (see
references/html-template.md for the schema):
- Meeting metadata — date, time, location, syndic, vote-by-correspondence deadline. Record
meeting.pages.
- Resolutions — every numbered item with its article-of-majority (Article 24/25/26/26-1) and "Sans vote" flag. Record
pages on each résolution (page of "PROJETS DE RESOLUTIONS" where the body sits).
- Financial Y-o-Y from Annexe N°3 — totals for exercise N (just closed), N+1 (current year, often re-voted), N+2 (next year, the main vote). Line items with >20 % swing or >500 € absolute change. Record
budget.pages (annexe totals) and pages on each notable budget line.
- Owner-specific data + travaux highlights — owner's tantièmes, debit/credit balance from Annexe N°6 if listed, big-ticket travaux (ravalement, toiture, fonds ALUR, devis >5 000 €). Record
owner.balance_pages, owner.fonds_alur_pages, and pages on each travaux entry.
- Briefing — 3 to 7 prioritized "à retenir avant de voter" items the user should actually read. Record the composite
pages (résolution body + supporting annexe row).
- Set
source.pdf_path to the absolute path of the source PDF. If you can derive a relative path from the report's CWD to the PDF (typically cd was somewhere near it), also set source.pdf_path_relative — that's what makes the deep links survive moves of the HTML+PDF as a pair.
- Read
references/html-template.html. Substitute {{AG_DATA_JSON}} (serialized JSON, 2-space indent), {{LANG}} (fr/en), {{YEAR}}, {{RESIDENCE_TITLE}}.
- Write the result to
./ag-<slug>-<year>.html in the user's CWD.
- Output the Step Completion Report (below), then briefly summarize the briefing (3–5 bullets max, since the report itself shows them in detail).
Cross-syndic note: layouts vary. Anchor on landmarks ("ORDRE DU JOUR", "RESOLUTION N°", "ANNEXE N°", "tantièmes", "vote par correspondance") rather than fixed page numbers when searching the PDF — but always record the page you landed on, into the relevant pages array, so each fact can be cited back to the source.
Query mode — answering follow-up questions
Full playbook: see references/query.md. Quick version:
- Read the HTML file. Extract the JSON between
<script type="application/json" id="ag-data"> and </script>. Parse it.
- Do not re-read the PDF unless the user explicitly asks.
- Match the question against the JSON sections:
- "when / where / deadline" →
meeting
- "vote / résolution / what am I voting on / article" →
resolutions
- "budget / dépense / coût / augmentation / variation" →
budget + budget_lines
- "tantièmes / solde / je dois / mon lot" →
owner
- "travaux / ravalement / chantier" →
travaux + the matching résolutions
- "what should I pay attention to" →
briefing
- Answer in the user's question language (French if asked in French, English if asked in English). Keep French legal terms intact (quitus, tantièmes, travaux, Article 25).
- Cite the résolution number or annexe reference when relevant.
- If the answer isn't in the JSON, say so explicitly — don't invent it. Offer to re-ingest.
- If the user asks to regenerate the report (new export, "refresh the HTML"), re-render the same JSON through the template without re-reading the PDF.
Output format
After ingest
◆ Ingest complete ([N] résolutions, [budget €] budget N+2)
··································································
Meeting date: √ [date] at [time] — [location]
Vote deadline: √ [date]
Syndic: √ [name]
Résolutions: √ [count] votables, [count] sans vote
Annexe N°3 budget: √ N: [x€] N+1: [y€] N+2: [z€] (Δ [pct])
Owner data: √ [name] — [tantièmes] tantièmes
Report saved to: √ ./ag-[slug]-[year].html
____________________________
Result: PASS
Ouvrez le fichier dans votre navigateur pour le rapport interactif.
[3–5 bullet recap of what to pay attention to — the HTML itself has the detail]
After query
Plain answer, 1–6 sentences, in the user's language. Cite résolution number / annexe / page when relevant. End with a one-line offer (e.g. "Want me to dig deeper into any résolution?") only if the answer was short and surface-level.
Constraints
- The JSON inside the HTML is the source of truth in Query mode. Treat it like the user's working memory. If you contradict it, the user will lose trust.
- Never invent numbers. If the AG document leaves a field blank (e.g.
Vote d'un budget de _____ €), record null and say "left blank in the convocation" in the corresponding summary or note.
- Keep French legal terms in French even when answering in English. Quote the original phrase in italics on first mention.
- Do not give legal advice. The skill explains the document; the user (or their conseil syndical / lawyer) decides how to vote.
- The HTML uses external CDNs (Tailwind, Chart.js, Google Fonts). Offline use will degrade the visualization but the JSON block remains intact and Query mode still works.
Reference files
references/ingest.md — full extraction playbook, per-block landmarks, multi-syndic notes.
references/query.md — full Q&A playbook with example question→JSON-field mappings.
references/html-template.md — JSON schema reference + template substitution recipe.
references/html-template.html — the actual HTML shell with placeholder {{AG_DATA_JSON}}.