Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,19 @@ Install it, then authenticate with one of:
- **Pre‑obtained token:** set `GOOGLE_WORKSPACE_CLI_TOKEN=<access_token>`
- **Client app:** set `GOOGLE_WORKSPACE_CLI_CLIENT_ID` and `GOOGLE_WORKSPACE_CLI_CLIENT_SECRET`, then `gws auth login`

On your Google Cloud project, enable the **Sheets**, **Drive**, and **Docs** APIs.
On your Google Cloud project, enable the **Sheets**, **Drive**, **Docs**, and
**Forms** APIs.

**OAuth scopes.** The ops skills *read and write* Sheets/Drive (clone, rebrand,
clean) and read Form responses, so grant **read-write** scopes — read-only access
passes the verify step below but then fails on the first write:

- `https://www.googleapis.com/auth/spreadsheets` — read/write the intake sheet
- `https://www.googleapis.com/auth/drive` — copy, create, and update Drive files
(chapter/series asset clones)
- `https://www.googleapis.com/auth/forms.body` — read/edit the intake form
- `https://www.googleapis.com/auth/forms.responses.readonly` — read form responses

Verify with:

```bash
Expand Down
3 changes: 2 additions & 1 deletion scripts/check_frontmatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@


def check(path: str) -> list[str]:
text = open(path, encoding="utf-8").read()
with open(path, encoding="utf-8") as f:
text = f.read()
m = FRONTMATTER.match(text)
if not m:
return [f"{path}: no `---` YAML frontmatter block at the top of the file"]
Expand Down
2 changes: 1 addition & 1 deletion skills/aaif-announcement-post/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
name: aaif-announcement-post
description: Write the LinkedIn launch/announcement post for an AAIF meetup when RSVPs open. Use when asked to draft the announcement, launch post, or "RSVPs are open" post for an AAIF event.
argument-hint: [event title / paste tracker entry]
argument-hint: '[event title / paste tracker entry]'
---

# AAIF Event Announcement (LinkedIn)
Expand Down
2 changes: 1 addition & 1 deletion skills/aaif-attendee-reminder/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
name: aaif-attendee-reminder
description: Write the pre-event reminder to people who RSVP'd to an AAIF meetup (sent ~1 week out and the morning of). Use when asked to draft the attendee reminder / "see you tomorrow" note for an AAIF event.
argument-hint: [event title / paste tracker entry]
argument-hint: '[event title / paste tracker entry]'
---

# AAIF Attendee Reminder
Expand Down
2 changes: 1 addition & 1 deletion skills/aaif-carousel-copy/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
name: aaif-carousel-copy
description: Write copy for a 6-slide LinkedIn carousel announcing an AAIF meetup. Use when asked to draft carousel slides/copy for an AAIF event (built from the LinkedIn Carousel template).
argument-hint: [event title / paste tracker entry]
argument-hint: '[event title / paste tracker entry]'
---

# AAIF LinkedIn Carousel Copy
Expand Down
2 changes: 1 addition & 1 deletion skills/aaif-clean-data/scripts/clean.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ def L(name):
# (it must not turn the row bright red). It's surfaced by `scan` instead.
parts = []
if email:
parts.append(f'IF(ISNUMBER(SEARCH("@",${email}2:${email})),"","missing/bad email; ")')
parts.append(f'IF(REGEXMATCH(${email}2:${email},"^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$"),"","missing/bad email; ")')
if link:
parts.append(f'IF(REGEXMATCH(LOWER(${link}2:${link}),"linkedin\\.com/"),"","bad LinkedIn; ")')
concat = "&".join(parts) if parts else '""'
Expand Down
2 changes: 1 addition & 1 deletion skills/aaif-dayof-slides/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
name: aaif-dayof-slides
description: Turn an event's tracker entry into the slide text for the AAIF "Day of Event" deck. Use when asked to fill/write the day-of slides or event deck for an AAIF meetup.
argument-hint: [event title / paste tracker entry]
argument-hint: '[event title / paste tracker entry]'
---

# AAIF Day-of Slides (from the tracker)
Expand Down
2 changes: 1 addition & 1 deletion skills/aaif-luma-description/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
name: aaif-luma-description
description: Write the Luma event-page description for an AAIF in-person meetup. Use when asked to draft the Luma description / event page copy for an AAIF event.
argument-hint: [event title / paste tracker entry]
argument-hint: '[event title / paste tracker entry]'
---

# AAIF Luma Event Description
Expand Down
2 changes: 1 addition & 1 deletion skills/aaif-recap-post/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
name: aaif-recap-post
description: Write the post-event LinkedIn recap for an AAIF meetup (posted within 48 hours, with photos). Use when asked to draft the recap, thank-you, or wrap-up post after an AAIF event.
argument-hint: [event title / paste tracker entry]
argument-hint: '[event title / paste tracker entry]'
---

# AAIF Post-Event Recap (LinkedIn)
Expand Down
2 changes: 1 addition & 1 deletion skills/aaif-speaker-bio/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
name: aaif-speaker-bio
description: Write a speaker bio (a 60-80 word bio + a one-liner) for an AAIF in-person meetup speaker. Use when asked to draft/write a speaker bio for an AAIF event or chapter.
argument-hint: [speaker name / paste their tracker row]
argument-hint: '[speaker name / paste their tracker row]'
---

# AAIF Speaker Bio
Expand Down
2 changes: 1 addition & 1 deletion skills/aaif-speaker-invite/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
name: aaif-speaker-invite
description: Write a short, warm speaker-invite DM or email for an AAIF in-person meetup. Use when asked to draft a speaker invite, outreach DM, or ask-someone-to-speak message for an AAIF event.
argument-hint: [speaker name + event / paste tracker entry]
argument-hint: '[speaker name + event / paste tracker entry]'
---

# AAIF Speaker Outreach / Invite
Expand Down
8 changes: 7 additions & 1 deletion skills/aaif-triage-intake/scripts/intake.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,13 @@ def fetch(tab):
sys.exit(f"gws error reading {tab}: {out.stderr.strip()}")
# gws prints a keyring banner line before the JSON; find the JSON start.
txt = out.stdout
data = json.loads(txt[txt.index("{"):])
start = txt.find("{")
if start < 0:
sys.exit(f"gws returned no JSON for {tab} (got: {txt.strip()[:200]!r})")
try:
data = json.loads(txt[start:])
except json.JSONDecodeError as e:
sys.exit(f"gws returned invalid JSON for {tab}: {e}")
vals = data.get("values", [])
if not vals:
return [], []
Expand Down
Loading