sbdc-workshops
Skill1 starsChanged 3 months agoMITView on GitHub
rebuild a workshop or class (sbdc, vboc, wbc or any small business center; maryland sbdc's "winning that government contracting award" series is the worked example) the new way - html deck in your organization's colors and logo with click-by-click reveal, a google form worksheet behind qr checkpoints, an automatic branded follow-up email with the attendee's own answers plus the handout and slides attached, a pdf of the deck, and a run sheet. first run asks a few questions and saves your organization's brand to org.json. use when the user says "sbdc workshops", "do the next session", "set up workshops for my center", "rebuild the class for wednesday/friday", or hands over an old deck/script for a workshop.
In this repository14 other files it gives its agents.
- business-model-canvas-helperSkill
- business-service-provider-referral-engineSkill
- client-follow-up-and-reengagementSkill
- mdsbdc-debt-helperSkill
- proposal-buddySkill
- sbdc-grant-advisorSkill
- sbdc-marketing-plan-generatorSkill
- sbdc-success-storySkill
- sbdc-training-newsletterSkill
- sbdc-underwriter-and-capital-coachSkill
- tam-sam-somSkill
- transcript-to-action-plan-client-emailSkill
- transcript-to-meeting-notesSkill
- transcript-to-sopSkill
The file
We split this skill into the rules it gives an agent
6 rules. About 0 are common, 1 is distinctive, and 5 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 58
Put the live link into build.py (engine.setup(<link>)) and rebuild.
- Very specific: line 68
Check page count = slide count and render 2 pages with PyMuPDF (fitz) to confirm every reveal step prints.
- Very specific: line 70
Close out: Commit the class build.py and .gs copies (explicit paths only), prepend the HANDOFF-LOG entry via handoff_prepend.py, push.
- Very specific: line 73
Every slide screenshotted once at 1280x720 in the Browser pane: no overlap, no text past the frame.
- Very specific: line 76
Test email received, and each attachment's filename matches its attachedLabel (read the [TEST] thread with get_thread.
- Distinctive: line 85
Do not push binaries into Drive by base64 through tool calls (transcription errors).
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
SBDC Workshops
One class = five deliverables, built the same way every time. Session 1 (Business Development Lifecycle, 2026-09-28, Maryland SBDC) is the worked example; everything here was proven on it. "BRANDON" below means the presenter, whoever runs the class; Maryland paths, people and dates are the example setup.
| # | Deliverable | Where it comes from |
| 1 | Deck: single HTML file, 16:9 stage, Maryland SBDC design, one bullet/graphic per click, P = presenter notes + timer, prints to PDF | scripts/deck/engine.py + a class file copied from scripts/deck/session1_example.py |
| 2 | Worksheet: Google Form, page 1 intake + one section per checkpoint slide + before-you-leave + staying-in-touch | copy of the Session 1 form + scripts/apps-script/form_builder.gs |
| 3 | Follow-up email: sent on submit, their answers, links, advising button, handout + slides PDF attached | scripts/apps-script/followup_email.gs in the same bound script |
| 4 | Deck PDF (for the email attachment) | headless Edge, see step 6 |
| 5 | Run sheet artifact: tonight / 20-min-before checklists, run of show, chat message for Diane, after-class steps | adapt assets/run-sheet-example.html, publish with the Artifact tool |
Output folder per class: Claude Playground\sbdc-advising\outputs\<YYYY-MM-DD>-govcon-s<N>\. Commit the class .py, .gs copies and any .md; the generated .html/.png are gitignored there.
The series (source scripts are read-only in sbdc-advising\raw\training-materials\GOVCON WORKSHOP APRIL 2026\)
| Session | When (Zoom, host Diane McFarland) | Source script |
| 1 Business Development Lifecycle | Mon Sep 28, 10:00-11:30 | 2026-04-28-session-1-business-development-lifecycle.md (done) |
| 2 Team Roles and Responsibilities | Wed Sep 30, 10:00-11:30 | 2026-04-29-session-2-team-roles-and-responsibilities.md |
| 3 How to Read an RFP | Fri Oct 2, 10:00-11:30 | 2026-04-30-session-3-how-to-read-an-rfp.md |
| 4 Basics of Proposal Writing | Mon Oct 5, 10:00-11:30 | 2026-05-01-session-4-basics-of-proposal-writing.md |
Confirm the date and Zoom link on the UMD calendar before trusting this table. Handouts for each session sit in FINAL DRAFT PRESENTATIONS AND HANDOUTS\.
Step 0: set up your organization (first run only, about 10 minutes)
Look for org.json in the user's workshop folder (the class folder or up to three folders above it; the deck engine searches the same way). Found it: skip to step 1. Not found and the user is Maryland SBDC: copy org.example.json there as org.json and go on. Otherwise ask these, one at a time, and write org.json with the same fields as org.example.json:
- Your organization's short name (goes in the slide footer and email band) and full name. Example: "Mid-Atlantic VBOC" / "Mid-Atlantic Veterans Business Outreach Center".
- Presenter name and the email attendees should reply to.
- Two brand colors as hex codes: a dark primary (footer, headings) and a bright accent (bars, highlights). No codes? Ask for the website and read them from its CSS, then confirm.
- Your logo, the white or reversed version for dark backgrounds, as a PNG. Save it next to
org.jsonand put the filename inlogo. - The link attendees use to sign up for one-on-one help, and how to show it on a slide (short form, no https://).
- The sign-up question on the form (e.g. "Would you like free one-on-one counseling from Mid-Atlantic VBOC?") and the "already a client" answer.
- Your service area: the label ("County", "State", "Region") and the list of choices.
- Certifications to list on the intake page (8(a), VOSB / SDVOSB, WOSB, state programs...).
- The funding acknowledgment your grant requires, word for word, and your accommodations line.
Then build one test slide set from scripts/deck/session1_example.py and show the user the title slide and one light slide before any real class. When pasting form_builder.gs and followup_email.gs in steps 3 and 4, fill each file's ORG block from org.json first; Apps Script cannot read the file. Everything else (slides, LINKS, the Maryland series below) is class content the user supplies per class.
Steps (about 2-3 hours of Claude time; Brandon's hands-on time is about 10 minutes, marked BRANDON)
- Read the session's source script (slides + speaker notes + graphic suggestions) and the calendar event. Run
py learnings.py list --grep workshopand--skill sbdc-workshopsfirst. - Deck. Copy
scripts/deck/session1_example.pyinto the class output folder asbuild.py. Keep the header lines andengine.render(...); replace every slide between them. Rules that make it match:- Speaker notes come from the script; slide text is short (1-3 lines or 4-6 bullets). Turn each "Graphic Suggestion" into a real layout from the engine's CSS vocabulary:
tiers,stairs,timeline,phases,colorflow,four,gng,split,tiles,funnel,roles,stat,curve,compare,callout,cols2,card. Readsession1_example.pyfor how each is used. - Structure: title (QR) -> scan slide -> agenda -> section dividers per part -> 2 or 3
checkpoint("Section A", ...)slides at natural pauses -> takeaways -> "Submit your worksheet" -> Questions (signup QR + SBA notice). Checkpoint names must match the form sections (A, B, ...), and the last content slide points to the before-you-leave section. - Footer text:
"Session N · <Title>". Title slide eyebrow:"Winning That Government Contracting Award · Session N of 4", date spelled out. - Contact on slides is
bwmason@umd.edu(the April decks said bw@fnxpearl.com - do not carry that over). - Build with a placeholder form URL first (
engine.setup("https://forms.gle/REPLACE-ME")), then rebuild after step 3.
- Speaker notes come from the script; slide text is short (1-3 lines or 4-6 bullets). Turn each "Graphic Suggestion" into a real layout from the engine's CSS vocabulary:
- Form. In Brandon's Chrome (claude-in-chrome, signed in as bwmason@umd.edu): open the Session 1 form editor
https://docs.google.com/forms/d/1fktLVyhvAlNcZtlDmwSIRHHyYo83DyJ829kXfnFQH-A/edit-> More -> Make a copy -> Make a copy. It opens in a new tab. Close the tab holding the original so nothing edits it. In the copy: More -> Apps Script. The copy brings along Session 1's bound script (the email code with Session 1 settings); its trigger does not copy, so nothing sends yet. Replace the whole file withscripts/apps-script/form_builder.gs, editCLASS(title, session, checkpoints that match the deck, remaining series sessions), save, runbuildWorksheet. BRANDON: approve the permission prompt (Review permissions -> bwmason@umd.edu -> Allow) - never click it yourself.- The run publishes the form. Verify from PowerShell:
Invoke-WebRequest <viewform link>returns 200 and contains "Your name" (no sign-in wall). - Put the live link into
build.py(engine.setup(<link>)) and rebuild. Label stays "Link is in the Zoom chat".
- The run publishes the form. Verify from PowerShell:
- Email. Delete
buildWorksheet/addItem_/CLASSfrom the bound script (the form is built; a rerun over live responses would orphan them - the builder also refuses once responses exist). Pastescripts/apps-script/followup_email.gs, editEMAIL(subject, heading, subline,rows= [label, exact form question title],next, file IDs), save, runinstallTrigger, thensendTestEmail. BRANDON approves the second permission prompt (mail, Drive, triggers). - Handout ID. BRANDON drags the session handout (xlsx/pdf) into Drive and pastes the link; put the ID in
EMAIL.templateFileId. Before wiring any pasted ID, read its Drive title (get_file_metadata) and confirm it is the file the label names. Session 2 shipped the capture template labeled as the compliance matrix because the pasted link was the wrong file. - Deck PDF. Headless Edge, fresh profile, write to %TEMP% then copy (Edge will not write into the outputs folder, and a PDF open in a viewer silently does not get overwritten - use a new filename):
Check page count = slide count and render 2 pages with PyMuPDF ($edge="C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"; $tmp="$env:TEMP\deck-$(Get-Random).pdf" $src="file:///" + ((Resolve-Path "<deck>.html").Path -replace '\\','/' -replace ' ','%20') Start-Process $edge -ArgumentList @('--headless','--disable-gpu','--no-pdf-header-footer','--virtual-time-budget=4000',"--user-data-dir=$env:TEMP\edgepdf-$(Get-Random)","--print-to-pdf=$tmp",$src) -Wait -WindowStyle Hidden Copy-Item $tmp ".\Session-N-<Title>-slides.pdf"fitz) to confirm every reveal step prints. BRANDON uploads it to Drive and pastes the link ->EMAIL.deckFileId. Once a real submission exists, runsendLatestToMeso Brandon sees the exact attendee email. - Run sheet. Adapt
assets/run-sheet-example.html(dates, Zoom link from the calendar event, run of show with checkpoint rows shaded, chat message with the live link, handout path, next session) and publish it as a private artifact. Apply every rule in "Delivery rules" below; for Session 2 onward, also read the previous session's Zoom transcript + chat and its responses sheet, and add a "Last session's leftovers" block (unanswered chat questions, promised follow-ups) as a 4-minute row right after the welcome. - Close out. Commit the class
build.pyand.gscopies (explicit paths only), prepend the HANDOFF-LOG entry viahandoff_prepend.py, push.
Verification (do all of it; it is what "same criteria" means)
- Every slide screenshotted once at 1280x720 in the Browser pane: no overlap, no text past the frame. Drive slides with
javascript_tool(dispatchEvent(new KeyboardEvent('keydown',{key:'ArrowRight'}))); real key presses in the pane break on thedata:URL. - Reveal: step counts per slide look sane (roughly 3-11), back arrow lands on the fully built slide, dark/scan slides show everything at once (QR never hidden).
- Form opens publicly; question titles match
EMAIL.rowsexactly. - Test email received, and each attachment's filename matches its
attachedLabel(read the [TEST] thread withget_thread; a count of 2 is not enough). - PDF complete.
Apps Script editor mechanics (learned the hard way)
- Set code with
monaco.editor.getModels()[0].setValue(code)viajavascript_toolon the editor tab. Pass code throughString.rawwith a template literal; the code must contain no backticks or${. - Save with the "Save project to Drive" button (find it by name). Ctrl+S often does not register. An account popup ("You're currently signed in as...") can swallow the click; press its OK first.
- The function dropdown ignores clicks on options. It defaults to the first function in the file, so put the function you need to run first - or temporarily append
yourFn(); // TEMPinside the selected function, run, then remove it and save again. - Reading another project's source (e.g. the VOSBTC
Code.gs) throughjavascript_toolis blocked by the safety classifier. Do not try to route around it; these templates replace it. - The Make a copy dialog ignores a typed name and Drive renames through the browser tools fail. Rename the copy with the Google Drive connector instead (
update_filewith a newtitle, e.g. "How to Read a Federal RFP — Class Worksheet"; worked 2026-09-30). The respondent-facing title still comes fromCLASS.title. - Do not push binaries into Drive by base64 through tool calls (transcription errors); Brandon drags files in and pastes links.
Delivery rules (from the Session 1 and 2 audits, 2026-09-28 / 09-30)
Session 1 ran 15 minutes over. Both checkpoints were skipped, the chat link landed 19 minutes in, and only 1 of 3 worksheets came back complete. Bake these into every deck and run sheet:
- Link in chat at minute 0. The run sheet's 20-minutes-before list ends with "At 10:00, paste the chat message yourself, before you say hello."
- "Don't hit Submit until the last slide" goes in the chat message, the slide 1 speaker note, and every checkpoint note. The follow-up email fires on submit, so an early submit mails the attendee a near-empty worksheet.
- Checkpoints are the last thing cut. The run sheet's "behind?" note names the content slides to drop, and says to pause the full 2-3 minutes at each checkpoint.
- Hard stop 5 minutes before the end. The run sheet carries "At :20 go straight to takeaways and Submit."
- Leftovers row: Session 2 onward opens with 4 minutes on the previous session's unanswered chat questions (see step 7).
- Term check: it is a compliance matrix, not a "capability matrix."
- Fact-check the speaker notes for thresholds and program rules before the build, and put the checked number in the note. Session 1 misstated on air: the EDWOSB net-worth cap ($850K; $6.5M is the assets cap), who certifies Maryland MBEs (since Oct 1, 2025: the Office of Minority Business Enterprise inside the Department of Social and Economic Mobility, DoSEM; not MDOT), the Maryland MBE goal (29%), and the OSDBU name.
- One question per form field. "Which hat are you skipping, and who could cover it" got answered as "Sub" and "Contractor" (Session 2). Split two-part prompts into two fields.
- Checkpoints need a script, not a mention. Session 2 named checkpoint B and kept talking. The run sheet says the literal line ("Take three minutes, I'll wait") and to watch the Responses tab until names move.
- Call Submit at :20, then take questions. Session 2 called it at :27 and Q&A vanished. Collect the forms while people ask.
- Leftovers stay at 4 minutes; personal stories go elsewhere. Say weekdays on air, never "tomorrow," in a Mon/Wed/Fri series.
- After class: run the audit. Inputs are the Zoom
.transcript.vtt+ chat.txtfrom Downloads, the responses (a copied form has no linked sheet; the sent follow-up emails in Gmail carry each attendee's answers), and the deck. Check what the follow-up emails actually attached. Output isoutputs/<class>/audit-session-N.md: plan vs actual, form signals, open loops owed, facts to fix, and changes for the next session.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

