
office-repair
Handle a hand-edited Office artefact that is now the authoritative version: repair a feature-rich Excel workbook in place through COM (broken slicers or dropdowns, REF!, circular reference warnings), or promote a generated .docx/.pptx/.xlsx to canonical hand-edited source and retire its generator. Use when Ane reports a damaged workbook or declares an edited file the source of truth. Distinct from office-review-pass (Word review cycle), the anepackage.reporting builders (generate new branded files), and check-deliverable (read-only QA verdict on prose).
- Installs
- 120
- Last 24h
- —
- Trending rank
- —
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/gasserane/personal-skills --skill office-repair- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads office-repair automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
/office-repair — fix a workbook in place, or hand a generated file over to Ane
One job: an Office file Ane already owns needs work, and the version on disk is the one that counts.
All Office surgery lives in ane_package.officeops. This skill contributes judgement, not plumbing. If a mode needs a capability officeops lacks, add it to officeops and test it there — office-review-pass is the worked example of that rule holding, and Wave 3 added five capabilities that way rather than growing its own. references/officeops-excel-api.md carries the exact call signatures; read it before writing any code.
The line, so it does not get relitigated: anything that opens an Office file belongs in officeops. Diffing two lists of strings, spotting an autocorrect flip and rewriting a .py generator are not Office operations, so they live in scripts/office_repair.py and are tested there.
Mode routing
- repair — an Excel workbook Ane maintains is broken or needs a change, and it carries features a naive write would destroy.
- canonical — a generated artefact has been hand-edited, and the generator is now the stale copy.
The two meet when a repaired workbook also has a generator behind it. Run repair first, then canonical to retire the generator.
Shared rules — both modes
- Ane's file is the baseline. Apply mel_wiki/wiki/concepts/edit-preservation-protocol.md when target file exists. Read what is on disk, change only what was asked, leave everything else byte-identical. This skill exists because that rule is hardest to keep on binaries, where a loss is both silent and unrecoverable.
- Never write an Office file with openpyxl when it carries features openpyxl cannot see. Slicers have no openpyxl representation at all: load and save, and
xl/slicers/is simply gone, the workbook still opens, and nothing reports anything. Scanning is read-only for that reason, not only for safety. - Verify on the written file, against what it had before.
workbook_inventorybefore,assert_inventory_unchangedafter. A save that returned proves nothing. - Never invent a fact. Cell addresses, sheet names, figures, formulas. If it is not in the scan or in loaded context, ask.
- Report in the EDIT-PRESERVATION DELIVERY format: what changed, what was left alone, and out-of-scope observations listed but not acted on.
repair mode
The workbook has slicers, charts, protection, structured references and spill formulas. All of them are invisible to the tools that would be quickest, which is why this mode is a sequence rather than a call.
-
Diagnose first, read-only.
python scripts/office_repair.py scan <workbook>This reports structure, ListObject coverage, cached error cells with the formula behind each one, fragmented data-validation ranges, and the feature inventory. Nothing is written and the workbook may be open in Excel while it runs.Add
--comto also ask Excel for circular references. That pass needs Excel and opens the file read-only. It is worth running whenever Ane reports a warning dialog on open or zeros where numbers belong: a circular reference lives in the dependency graph Excel builds at calculation time and not in the stored XML, so no amount of reading the file will find it. -
Read the scan honestly. Two results look like good news and are not:
- No cached errors in a workbook Excel has never opened. The file caches the last calculated result, so a library-written workbook caches nothing. Empty means "nothing cached", not "nothing wrong".
- Fragmented validation ranges. A dropdown applied to a column arrives as one area. Row insertion shatters it into single-row areas, and the rule then holds on some rows and not others. Nothing errors, because a missing dropdown shows as an empty cell.
-
Agree the fix list with Ane before writing. Name each cell, its current value and its new one. The scan gives you the current values; do not describe a change you have not read the current state of.
-
Build the payload and apply it. Write a JSON list of
{sheet, cell, old, new}and runpython scripts/office_repair.py repair <workbook> --edits edits.jsonoldis a guard, not documentation: the current formula is read first and the edit is skipped when it does not match. Five rails come with it — a timestamped backup, the per-cell guard, sheet protection captured and re-applied exactly as found, one save at the very end, and a throw before that save so a partial repair is discarded rather than written. -
A skipped cell is a failure, not a no-op. It means the payload is stale or the address is wrong. The command exits non-zero and says so. Re-scan rather than re-running with
--no-strict, which writes what matched and leaves the rest — useful only for a deliberate second pass. -
Verify against the backup.
python scripts/office_repair.py verify <workbook> --baseline <workbook>.backup-1.xlsxThe backup is the only honest record of what the workbook had before, which is why the assertion compares against it rather than against a remembered count.
Why COM and not openpyxl. Not preference. Slicers, sheet protection and ListObject geometry have no openpyxl equivalent Excel then honours. The COM path costs an Excel launch and about a minute; an openpyxl write costs a workbook.
Writing a date through COM: assign the serial, not a date object. COM refuses a datetime.date outright (TypeError: must be a pywintypes time object), and the obvious fix, passing a datetime, is the one that corrupts quietly: the value is converted through UTC, so on a UTC+2 machine 16.09.2026 00:00 is stored as 15.09.2026 22:00 and a dd.mm.yyyy cell renders the day before. Nothing raises, the write reports success, and the column looks plausible. Write the Excel date serial to .Value2 instead, then restore the cell's NumberFormat, because assigning a bare number drops the date format:
EXCEL_EPOCH = datetime.date(1899, 12, 30) # day 0 of the 1900 date system
fmt = ws.Cells(r, c).NumberFormat
ws.Cells(r, c).Value2 = (the_date - EXCEL_EPOCH).days
ws.Cells(r, c).NumberFormat = fmt
A serial carries no timezone, so what is written is what is stored. Verify by reopening the saved file and comparing the dates, never by the write returning without error — the off-by-one is invisible in the COM session that produced it and visible only on the round trip (proven 2026-09-23 on a real scoring workbook, where every completion date came out a day early).
Excel Tables and layout via COM — gotchas
Six traps met converting ranges to Tables on a finished results workbook (2026-10-23, evidence in agent-improvements/handoffs/2025-en-results-excel-tables-spec.md, 13:53 and 14:40 updates). Each one passed silently; each fix is one line.
ListObjects.Addauto-fits column widths and turns header wrap off. Fix: record every column width before the call, restore them after, and setWrapText = Trueon the header row again.- A one-character font-size write does not take. Setting size on a single character read back as 11 pt. Fix: set size per run with
cell.GetCharacters(start, length).Font.Size = 10, covering the whole run. Font.SizereadingNonedoes not mean mixed sizes. A cell reportsNonewhen its runs differ in any way, yet every run can still be 9 pt. Fix: read the size run by run withGetCharacters, never from the cell.AutoFitignores merged cells. A merged, wrapped source line keeps its old row height. Fix: copy the text into a spare helper column set to the merged width, AutoFit that row, take the height, then clear the helper.- Text sorts above every number in a descending Table sort. Numbers stored as text, and text values such as
17 of 58, land at the top. Fix: convert them to real numbers (moving the words to a label or note) before converting the range to a Table. - A verify that cannot fail proves nothing. Fix: run every verify script once on the unchanged file and confirm it FAILS before you trust a PASS.
canonical mode
Ane has edited a generated file in Word, PowerPoint or Excel. From now on her file is the source and the generator is the stale copy. The job is to make that true in the file system, not just in the conversation.
-
Extract and compare.
python scripts/office_repair.py diff <edited> --against <generated>Extraction recurses into grouped shapes and table cells. That matters more than it sounds: a flat pass over a .pptx returns every slide title and not one bullet, because python-pptx reports a group as a single shape with no text and the bullets live on its children. A deck that comes back as headings only is the extraction failing, not the deck. -
Separate her edits from Word's. The command flags four things it thinks Office did rather than Ane: diacritics silently stripped, smart-quote and dash autocorrection, a space landing inside a URL, and a near-identical rewording that reads like a stray keystroke. None of these is a verdict — put each in front of her. The asymmetry is what justifies asking: propagating an autocorrect flip into the canonical version makes it permanent and invisible, while asking about a deliberate edit costs one line of reply.
It also flags structurally when the edited file has less than half the text blocks of the generated one. That is the 2026-07-22 signature of a redesign that dropped the body layer and left titles.
-
Report her changes as a change list, grouped and in her terms — what the document now says, not which block index moved. Confirm the flagged artefacts one at a time.
-
Sync the
.mdmirror where one exists, and add a note naming the Office file as canonical and the date. Where no mirror exists, do not create one. -
Retire the generator.
python scripts/office_repair.py archive <generator>.py --canonical <edited file>This prepends a guard that refuses to run without--force, and under--forcerestores the canonical file byte-for-byte if the run touches it. It is code rather than a comment because a comment does not stop anyone, and the failure being prevented is a future session runningpython gen_x.pyin good faith. Running it twice changes nothing.
Do not fold her edits back into the generator. It is the obvious move and it is wrong: a generator can reproduce text but not the formatting-level changes Ane made in Word, so folding in produces a script that looks current and silently regenerates a worse file. Archive it instead. Where a change genuinely belongs in the generator because it will be generated again for a different document, say so and make that a separate piece of work.
Verification plan
Every mode states its check before it works, and the check reopens the written file:
| Mode | What gets asserted |
|---|---|
| scan | Read-only — nothing written. Report the feature inventory and the counts found. |
| repair | Replacement outcome per cell read back from Excel, then assert_inventory_unchanged against the pre-repair inventory, then verify --baseline against the backup: tables cover their rows, no cached errors, no feature lost. |
| diff | Read-only. Report block counts both sides and every flagged artefact explicitly, including the ones Ane confirms were deliberate. |
| archive | Run the archived generator. It must exit non-zero and leave the canonical file byte-identical. Asserting on the guard's source text tests the wrong thing — a refusal that only exists in a docstring is the failure this mode exists to prevent. |
python scripts/test_office_repair.py checks the driver itself: the change list, the artefact heuristics, and the generator guard actually refusing as a subprocess. Office behaviour is covered by tests/test_officeops.py in the work folder.
Scope boundary
- A Word review cycle — reading comments, tracked changes, a glossary and source annex — is
office-review-pass. This skill is Excel repair and the canonical handover. - Producing a new branded file is
ane_package.reporting; building a ToR istor-procurement; a read-only QA verdict on prose ischeck-deliverable. - Both COM paths need Windows, Excel installed, and PowerShell 5.1 — never pwsh 7, whose null-method handling breaks the Excel path.
win32comis not installed in this Python and is not the route. PackageNotFoundErrormeans an open handle in Excel, not a corrupt file. Test withzipfilebefore telling Ane her workbook is damaged.- On a web container the
diffandarchivepaths still work;scan --comandrepairdo not.
FAQ
What does the office-repair skill do?
Handle a hand-edited Office artefact that is now the authoritative version: repair a feature-rich Excel workbook in place through COM (broken slicers or dropdowns, REF!, circular reference warnings), or promote a generated .docx/.pptx/.xlsx to canonical hand-edited source and retire its generator. Use when Ane reports a damaged workbook or declares an edited file the source of truth. Distinct from office-review-pass (Word review cycle), the anepackage.reporting builders (generate new branded files), and check-deliverable (read-only QA verdict on prose).
How do I install office-repair?
Run npx skills add https://github.com/gasserane/personal-skills --skill office-repair in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/office-repair/ (personal) or .claude/skills/office-repair/ (project).
Which AI agents can use office-repair?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is office-repair safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains office-repair?
It is published by gasserane in gasserane/personal-skills. It has 120 recorded installs.
More from gasserane/personal-skills
journal-reflection
gasserane/personal-skills
Guide Ane through structured reflection at end of day, end of week, after a decision, or after new learning material, producing Obsidian-compatible markdown and writing to the vault journal when the path is reachable. Use on 'journal', 'reflect on today', 'weekly review', 'after-action review', or asks that reference writing to the Obsidian vault. For a quick 4-line post-deliverable capture use /learned instead.
evidence-synthesis
gasserane/personal-skills
Conduct a rigorous rapid evidence assessment or systematic-lite literature review for MEL/SRHR questions. Use when Ane asks for "evidence review", "literature review", "evidence synthesis", "REA", "what does the evidence say", "what do we know about", or similar. Produces a structured brief with question framing, method, findings by theme, confidence grading, and implications for programme or evaluation design. Does not invent citations.
daily-brief
gasserane/personal-skills
Produce a scannable morning briefing for Ane (Senior MEL/SRHR Specialist at IPPF). Use when the user asks for "daily brief", "morning briefing", "start of day", "what's on today", "plan my day", or similar. Assembles today's priority, calendar, overdue items, pending decisions, and an energy check. Operates on user-provided inputs by default; richer when calendar/email MCP servers are connected.
decision-memo
gasserane/personal-skills
Draft a structured decision memo for Ane. Use when the user asks for a "decision memo", "decision doc", "options paper", "recommendation brief", or equivalent. Produces a scannable document with context, options, recommendation, risks, and reversibility. Applies Ane's CLAUDE.md writing style automatically.
video-content-analysis
gasserane/personal-skills
Convert FGD/webinar/SBCC video files into a structured artefact pack (transcript, frames, manifest, Tier 1 BLUF summary) the existing MEL specialists can consume. Use when Ane asks to "analyse a video", "transcribe a focus group", "process a webinar recording", "summarise a meeting recording", or runs /analyze-video . Tiered transcription (local Whisper for sensitive; M365 Stream for internal/public). Privacy + consent validated by construction. Per-run feedback prompt feeds the self-improvement loop.
power-bi-build
gasserane/personal-skills
Build IPPF-branded Power BI artefacts from analytical input. Use when Ane asks to build, scaffold, or update a Power BI dashboard, semantic model, DAX measures, or .pbip project. Applies IPPF Visual Identity 2025 brand, MEL-standard DAX measures, and three standard page recipes (indicator dashboard, equity disaggregation, methodology card). Requires the pbi CLI (pbi-cli-tool, command name pbi) installed and Power BI Desktop running with a .pbip open.
Popular docs & writing skills
grill-with-docs
mattpocock/skills
A relentless interview to sharpen a plan or design, which also creates docs (ADR's and glossary) as we go.
lark-markdown
open.feishu.cn
飞书 Markdown:查看、创建、上传、编辑和比较飞书中的原生 Markdown 文件。当用户要操作飞书 Markdown 文件,或比较其远端版本及本地草稿时使用。纯本地 Markdown 文件操作不触发本 skill。不负责将 Markdown 导入为飞书在线文档,也不负责文件搜索、权限、评论、移动、删除等云空间管理操作。
writing-beats
mattpocock/skills
Writing, exploit; assemble raw material into a journey of beats, grounding each term before a beat leans on it.
writing-shape
mattpocock/skills
Writing, exploit: shape raw material into an article, paragraph by paragraph.
writing-fragments
mattpocock/skills
Writing, explore: mine raw fragments, no structure yet.
writing-for-agents
mattpocock/skills
Writing documents for agents. Use when creating or editing skills, or modifying AGENTS.md or CLAUDE.md.