From sharepoint-client-agreement-organizer
SharePoint Client Agreement Organizer — Find, inventory, and organize client agreements
How this skill is triggered — by the user, by Claude, or both
Slash command
/sharepoint-client-agreement-organizer:sharepoint-agreement-organizerThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are running the SharePoint Client Agreement Organizer skill — it finds client agreements by filename pattern across your SharePoint vault, generates an inventory report showing which households have agreements and which are missing, and optionally copies agreements to a central folder with standardized names.
You are running the SharePoint Client Agreement Organizer skill — it finds client agreements by filename pattern across your SharePoint vault, generates an inventory report showing which households have agreements and which are missing, and optionally copies agreements to a central folder with standardized names.
CRITICAL: Never use cd in bash commands. All CLI commands use the absolute path prefix shown below.
CLI tool: node ${CLAUDE_SKILL_DIR}/../../scripts/cli.js <command> — all commands output JSON to stdout
${CLAUDE_SKILL_DIR} is automatically set to this skill's directory. The plugin root is two levels up.
Run these commands silently (do not display output to user). Ignore any errors — these are best-effort and must never block the flow.
git -C ${CLAUDE_SKILL_DIR}/../.. pull --ff-only 2>/dev/null || true
npm install --prefix ${CLAUDE_SKILL_DIR}/../../scripts 2>/dev/null || true
Then check setup status:
node ${CLAUDE_SKILL_DIR}/../../scripts/cli.js check-setup 2>/dev/null
Parse the JSON. Store registered, email, sharepoint_connected for routing.
registered AND sharepoint_connected → skip to Step 3registered but NOT sharepoint_connected → skip to Step 2registered → proceed to Step 1Display:
██╗ ███████╗ █████╗
██║ ██╔════╝██╔══██╗
██║ █████╗ ███████║
██║ ██╔══╝ ██╔══██║
███████╗███████╗██║ ██║
╚══════╝╚══════╝╚═╝ ╚═╝
SharePoint Client Agreement Organizer — A LEA Skill
What does it do? Finds client agreements (CAs, IMAs, IPSs, CEAs) across all household folders in your SharePoint vault. Generates a coverage report showing which clients have agreements and which are missing. Optionally copies agreements to a central folder with standardized filenames.
Who is this for? Wealth management firms that need to audit agreement coverage or find missing client agreements — especially during M&A transitions when verifying paperwork across merging books.
How it works:
| Step | What happens |
|---|---|
| Connect | Link your Microsoft 365 account |
| Pick location | Choose your SharePoint site, library, and client folder |
| Find agreements | Locate files matching agreement patterns (CA, IMA, IPS, CEA) |
| Report | Generate a coverage report — who has agreements, who's missing |
| Deduplicate | Flag duplicate agreements across households |
| Organize | Optionally copy agreements to a central folder with standardized names |
Credentials stored encrypted on LEA servers. All scanning runs locally — your files flow directly between your machine and SharePoint, never through LEA.
Use AskUserQuestion: "Ready to get started?"
If "Not now", stop.
IMPORTANT: Do NOT use AskUserQuestion for email or firm name. Just output the question as text and wait for the user to reply in the chat.
Output: "What's your work email?" — then STOP and wait for the user to type their email in the chat.
After they reply with their email, output: "And your firm name? (or just hit enter to skip)" — then STOP and wait again.
Run registration with whatever they provided:
node ${CLAUDE_SKILL_DIR}/../../scripts/cli.js register "USER_EMAIL" "FIRM_NAME" 2>/dev/null
If the response includes "returning": true, the user was already registered — display: "Welcome back! Token refreshed."
Otherwise display: "Registered! Now let's connect your SharePoint account."
This skill requires Microsoft 365 permissions (Files.ReadWrite.All, Sites.Read.All) that need an admin to approve the LEA app for your organization. This is a one-time step — once approved, everyone at the firm can connect.
Use AskUserQuestion: "Are you a Microsoft 365 admin at your firm? (Global Admin, Application Admin, or Cloud Application Admin)"
Display exactly this:
Great — when you sign in next, Microsoft will ask you to consent on behalf of your organization.
On the Microsoft sign-in page, look for a checkbox that says "Consent on behalf of your organization" — check it and click Accept. This grants the LEA app access to read SharePoint files and copy them within your vault for everyone at your firm.
The app only gets access to files each person can already see — it can't see anything beyond their existing SharePoint permissions.
Then proceed to Step 2b.
Display exactly this:
A Microsoft 365 admin at your firm needs to approve the LEA app first. This is a one-time step.
Send this to your admin:
Please approve the LEA Skills app for SharePoint access:
- Open this link:
https://login.microsoftonline.com/common/adminconsent?client_id=YOUR_MS_CLIENT_ID- Sign in with your admin account
- Review the permissions (SharePoint file access) and click Accept
This grants LEA access to read and copy SharePoint files. Each user can only access files they already have permissions for — nothing extra is exposed.
Use AskUserQuestion: "Let me know when your admin has approved the app."
If "Not yet", display exactly this:
No problem — run this skill again once the app is approved.
Then stop.
Get the OAuth URL:
node ${CLAUDE_SKILL_DIR}/../../scripts/cli.js auth-sharepoint 2>/dev/null
Parse the JSON. Extract auth_url and session_id.
Display exactly this:
Now let's connect your Microsoft 365 account.
I'll open a Microsoft sign-in page. Sign in with your work account and approve access.
Open the auth URL in the browser automatically:
open "AUTH_URL"
Display exactly this:
Sign in and approve access in the browser tab that just opened, then come back here.
Wait for OAuth completion (polls automatically for up to 2 minutes):
node ${CLAUDE_SKILL_DIR}/../../scripts/cli.js poll-sharepoint-wait SESSION_ID 2>/dev/null
status is "connected" → proceed to Step 3status is "failed", "expired", or "timeout" → show the error and ask to retry. If the error mentions "admin approval required" or "AADSTS65001", explain that an admin needs to approve the app first (see Step 2a).Display: "SharePoint connected!"
node ${CLAUDE_SKILL_DIR}/../../scripts/cli.js verify-sharepoint 2>/dev/null
Parse JSON. Show:
SharePoint Connected Logged in as: DISPLAY_NAME (MAIL)
node ${CLAUDE_SKILL_DIR}/../../scripts/cli.js load-config sharepoint-agreement-organizer 2>/dev/null
If config exists and has site_id, drive_id, folder_id, and site_name, library_name, folder_name:
Display:
Previously used location: Site: SITE_NAME → Library: LIBRARY_NAME → Folder: FOLDER_NAME
Use AskUserQuestion: "Use this location again?"
If "Yes", skip to Step 5 using the saved drive_id and folder_id.
Display: "Loading your SharePoint sites..."
node ${CLAUDE_SKILL_DIR}/../../scripts/cli.js list-sites 2>/dev/null
Display sites as a numbered list (show site names only, never show IDs to the user):
Your SharePoint sites:
- Site Name A
- Site Name B
Use AskUserQuestion: "Which site has your client documents?"
Important: Internally map the user's selection back to the site ID from the JSON response. Never display IDs.
node ${CLAUDE_SKILL_DIR}/../../scripts/cli.js list-libraries SELECTED_SITE_ID 2>/dev/null
Display libraries as a numbered list:
Document libraries in "SITE_NAME":
- Documents
- Client Files
If there is only one library, auto-select it and display: "Using library: LIBRARY_NAME"
Otherwise use AskUserQuestion: "Which library?"
node ${CLAUDE_SKILL_DIR}/../../scripts/cli.js list-folders SELECTED_DRIVE_ID 2>/dev/null
Display folders as a numbered list (folder names only):
Folders in "LIBRARY_NAME":
- Folder Name A
- Folder Name B
Use AskUserQuestion: "Which folder contains your client/household folders?"
Confirm by listing subfolders:
node ${CLAUDE_SKILL_DIR}/../../scripts/cli.js list-folders SELECTED_DRIVE_ID SELECTED_ITEM_ID 2>/dev/null
Folders inside "SELECTED_FOLDER_NAME":
(list first ~10 subfolder names)
These look like your client/household folders.
Use AskUserQuestion: "Scan this folder for agreements?"
After confirming the folder, save the location for next time:
node ${CLAUDE_SKILL_DIR}/../../scripts/cli.js save-config sharepoint-agreement-organizer '{"site_id": "SITE_ID", "site_name": "SITE_NAME", "drive_id": "DRIVE_ID", "library_name": "LIBRARY_NAME", "folder_id": "FOLDER_ID", "folder_name": "FOLDER_NAME"}' 2>/dev/null
Display exactly this:
Searching for client agreements... This takes around 30 seconds, depending on how many files you have.
Run a single command that scans and generates the HTML report:
node ${CLAUDE_SKILL_DIR}/../../scripts/cli.js scan-agreements DRIVE_ID FOLDER_ID --report ${CLAUDE_SKILL_DIR}/../../scripts/agreement-report.html 2>/dev/null
Do NOT show a summary table. Do NOT show stats, metrics, or agreement counts. The report has all of this. Just open the report immediately.
Open the HTML report in the browser:
open "${CLAUDE_SKILL_DIR}/../../scripts/agreement-report.html"
Display exactly this:
Your Agreement Coverage Report is open in your browser.
It includes agreement coverage stats, which households have agreements, which are missing, and a CSV export.
Use AskUserQuestion: "Want to copy these agreements to a central folder? (Originals stay in place — nothing is moved or deleted.)"
If "No", skip to Step 7.
Use AskUserQuestion: "How should the copied files be named?"
Doc type = inferred from original filename (CA, IMA, IPS, CEA). Date = from filename if present, otherwise file last modified date.
Build the organization plan from the scan data — for each agreement found, map to the new name based on the naming convention chosen. The household folder name typically contains the client name (e.g., "Anderson James & Linda"). Infer doc type from which pattern matched the filename (CEA, IMA, IPS, or CA). For date, extract from filename if present, otherwise use the file's lastModifiedDateTime date.
Display exactly this:
Copying agreements to "Client Agreements" folder...
Do NOT narrate what you're building or skip — just run the command silently and show the result.
node ${CLAUDE_SKILL_DIR}/../../scripts/cli.js organize-agreements 'JSON_PLAN' 2>/dev/null
Where JSON_PLAN is:
{
"drive_id": "DRIVE_ID",
"parent_folder_id": "ROOT_FOLDER_ID",
"create_target_folder": true,
"target_folder_name": "Client Agreements",
"agreements": [
{ "file_id": "abc123", "original_name": "cea.pdf", "new_name": "Anderson James - CEA - 2024-03-15.pdf" }
]
}
Parse the results. Show:
Organization Complete
Result Count Copied N Failed N Files copied to: Client Agreements folder in SharePoint
Use AskUserQuestion: "What next?"
If "Done":
Log usage:
node ${CLAUDE_SKILL_DIR}/../../scripts/cli.js log-usage sharepoint-agreement-organizer 2>/dev/null
Display:
Done! Got questions? Want more? [email protected]
success: false in any CLI response, show the error message and ask to retry or exit2>/dev/null)| Step | Command | When |
|---|---|---|
| 0 | git pull | Always (silent) |
| 0 | npm install | Always (silent) |
| 0 | check-setup | Always |
| 1 | register | First run only |
| 2a | (no CLI) | Admin consent — instructions only |
| 2b | auth-sharepoint | First run only |
| 2b | open | First run only (OAuth URL) |
| 2b | poll-sharepoint-wait | First run only |
| 3 | verify-sharepoint | Always |
| 4 | load-config | Check saved location |
| 4 | list-sites | Site selection |
| 4 | list-libraries | Library selection |
| 4 | list-folders | Folder selection (1-3 calls) |
| 4 | save-config | Save chosen location |
| 5 | scan-agreements | Main search |
| 5 | open | Open report |
| 6 | organize-agreements | Optional organization |
| 7 | log-usage | Usage tracking (only on Done) |
Total: 9-16 bash calls for full flow
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub lea-product-and-engineering/lea-wealth-plugins --plugin sharepoint-client-agreement-organizer