geekbot-cli 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +517 -0
  3. package/package.json +50 -0
  4. package/scripts/postinstall.mjs +27 -0
  5. package/skills/geekbot/SKILL.md +281 -0
  6. package/skills/geekbot/check-cli.sh +36 -0
  7. package/skills/geekbot/cli-commands.md +382 -0
  8. package/skills/geekbot/error-recovery.md +95 -0
  9. package/skills/geekbot/manager-workflows.md +408 -0
  10. package/skills/geekbot/reporter-workflows.md +275 -0
  11. package/skills/geekbot/standup-templates.json +244 -0
  12. package/src/auth/keychain.ts +38 -0
  13. package/src/auth/resolver.ts +44 -0
  14. package/src/cli/commands/auth.ts +56 -0
  15. package/src/cli/commands/me.ts +34 -0
  16. package/src/cli/commands/poll.ts +91 -0
  17. package/src/cli/commands/report.ts +66 -0
  18. package/src/cli/commands/standup.ts +234 -0
  19. package/src/cli/commands/team.ts +40 -0
  20. package/src/cli/globals.ts +31 -0
  21. package/src/cli/index.ts +94 -0
  22. package/src/errors/cli-error.ts +16 -0
  23. package/src/errors/error-handler.ts +63 -0
  24. package/src/errors/exit-codes.ts +14 -0
  25. package/src/errors/not-found-helper.ts +86 -0
  26. package/src/handlers/auth-handlers.ts +152 -0
  27. package/src/handlers/me-handlers.ts +27 -0
  28. package/src/handlers/poll-handlers.ts +187 -0
  29. package/src/handlers/report-handlers.ts +87 -0
  30. package/src/handlers/standup-handlers.ts +534 -0
  31. package/src/handlers/team-handlers.ts +38 -0
  32. package/src/http/authenticated-client.ts +17 -0
  33. package/src/http/client.ts +138 -0
  34. package/src/http/errors.ts +134 -0
  35. package/src/output/envelope.ts +50 -0
  36. package/src/output/formatter.ts +12 -0
  37. package/src/schemas/common.ts +13 -0
  38. package/src/schemas/poll.ts +89 -0
  39. package/src/schemas/report.ts +124 -0
  40. package/src/schemas/standup.ts +64 -0
  41. package/src/schemas/team.ts +11 -0
  42. package/src/schemas/user.ts +70 -0
  43. package/src/types.ts +30 -0
  44. package/src/utils/constants.ts +24 -0
  45. package/src/utils/input-parsers.ts +234 -0
  46. package/src/utils/receipt.ts +94 -0
  47. package/src/utils/validation.ts +128 -0
@@ -0,0 +1,95 @@
1
+ # Error Recovery Guide
2
+
3
+ How to handle CLI failures gracefully. The CLI's structured error responses
4
+ make most failures recoverable without user intervention.
5
+
6
+ ## Error Response Structure
7
+
8
+ Every error produces a valid JSON envelope:
9
+
10
+ ```json
11
+ {
12
+ "ok": false,
13
+ "data": null,
14
+ "error": {
15
+ "code": "standup_not_found",
16
+ "message": "Standup 999 not found",
17
+ "retryable": false,
18
+ "suggestion": "Available standups: 123 (Daily Standup), 456 (Weekly Sync). Run `geekbot standup list` to see all."
19
+ },
20
+ "metadata": { "timestamp": "2026-03-17T10:15:00.000Z" }
21
+ }
22
+ ```
23
+
24
+ The `suggestion` field is the agent's best friend — it contains actionable
25
+ recovery instructions, often including valid resource IDs.
26
+
27
+ ## Recovery Behaviors by Exit Code
28
+
29
+ Exit codes and their meanings are in `SKILL.md`. This section focuses on
30
+ **what the agent should do** for each failure type.
31
+
32
+ ### Exit 3: NOT_FOUND — Self-correct from suggestion
33
+
34
+ This is the most common recoverable error. Parse `error.suggestion` to
35
+ extract valid IDs and names, present alternatives to the user, and re-run
36
+ with the correct ID. Don't ask the user to find the right ID manually.
37
+
38
+ ### Exit 4: AUTH — Stop and guide, never retry
39
+
40
+ Auth errors are never transient. Recommend `geekbot auth setup` (OS keychain)
41
+ as the simplest path. Also mention `GEEKBOT_API_KEY` env var and `--api-key`
42
+ flag as alternatives.
43
+
44
+ ### Exit 5: FORBIDDEN — Check role, explain permissions
45
+
46
+ Check the user's role via `geekbot me show` → `data.role`. If non-admin,
47
+ suggest contacting their team admin. For `standup list --admin`, suggest
48
+ trying without `--admin`.
49
+
50
+ ### Exit 6: VALIDATION — Fix input and retry
51
+
52
+ Show the specific error from `error.message` and help fix it. Common fixes:
53
+ - Dates: ISO 8601 (`2026-03-17`) or unix timestamp
54
+ - Times: 24-hour `HH:MM`
55
+ - Timezone: IANA format (`Europe/Athens`, not `EET`)
56
+ - JSON: check for unescaped quotes, missing brackets
57
+ - Days: comma-separated, capitalised (`Mon,Tue,Wed`)
58
+
59
+ ### Exit 7: NETWORK — Conditional retry
60
+
61
+ If `retryable: true`: retry once silently after 2 seconds. If the retry
62
+ also fails, report the error. If `retryable: false`: report immediately.
63
+
64
+ ### Exit 8: CONFLICT — Explain and suggest resolution
65
+
66
+ Typically a duplicate name or concurrent modification. For duplicate names,
67
+ suggest a different name. For concurrent modification, re-fetch and retry.
68
+
69
+ ### Exit 9 with `schema_validation_error` — API response mismatch
70
+
71
+ If the error code is `schema_validation_error`, the API returned data in an
72
+ unexpected format that doesn't match the CLI's schema. This is **not** a user
73
+ input problem — don't ask the user to change their command.
74
+
75
+ Report the error clearly and suggest:
76
+ - The CLI version may be outdated (suggest updating)
77
+ - The Geekbot API may have changed
78
+ - If persistent, report it as a bug
79
+
80
+ Do **not** retry — the same response will fail the same way.
81
+
82
+ ### Exits 1, 2, 9 — Report clearly
83
+
84
+ Report `error.message` to the user. For exit 2 (usage), check the command
85
+ against `cli-commands.md` and rebuild with correct syntax. For exit 9
86
+ (API error), suggest checking https://status.geekbot.com/ if persistent.
87
+
88
+ ## General Principles
89
+
90
+ 1. **Always parse JSON** — even errors produce valid envelopes. Don't parse
91
+ stderr or raw text.
92
+ 2. **Use the suggestion field** — it's there specifically for agent recovery.
93
+ 3. **Never retry non-retryable errors** — check `error.retryable` first.
94
+ 4. **Be transparent about retries** — if a network retry also fails, tell
95
+ the user. Don't silently loop.
@@ -0,0 +1,408 @@
1
+ # Manager Workflows
2
+
3
+ Detailed multi-step guides for manager operations. The SKILL.md provides
4
+ the overview; this document covers the full orchestration with edge cases.
5
+
6
+ ## Table of Contents
7
+
8
+ 1. [Standup Creation Wizard](#standup-creation-wizard)
9
+ 2. [Poll Creation Flow](#poll-creation-flow)
10
+ 3. [Analytics Playbook](#analytics-playbook)
11
+
12
+ ---
13
+
14
+ ## Standup Creation Wizard
15
+
16
+ The most complex manager operation. This wizard adapts to how much the user
17
+ already knows about what they want.
18
+
19
+ ### Step 1: Assess intent specificity
20
+
21
+ **Vague request** ("set up a standup") → offer templates
22
+ **Moderate** ("create a daily standup for engineering") → use Daily Standup
23
+ template, confirm with user
24
+ **Specific** ("create a standup in #backend, Mon/Wed/Fri at 9am Athens
25
+ time, with these 3 questions...") → build directly from their spec
26
+
27
+ ### Step 2: Template selection (when applicable)
28
+
29
+ Load `standup-templates.json`. Present 3-4 relevant options based
30
+ on the user's language:
31
+
32
+ | User says | Suggest |
33
+ |-----------|---------|
34
+ | "daily standup", "daily check-in" | Daily Standup, Quick Check-in |
35
+ | "retro", "retrospective", "sprint review" | Retrospective |
36
+ | "sales", "pipeline", "deals" | Sales Report |
37
+ | "check-in", "how's everyone doing" | Quick Check-in, Well-being Check-in |
38
+ | "1-on-1", "confidential", "private" | Confidential Check-in |
39
+ | "meeting notes", "meeting recap" | Meeting Notes |
40
+ | "ideas", "brainstorm" | I Have an Idea |
41
+ | "changelog", "releases" | Product Changelog |
42
+ | "incidents", "outages" | Incident Log |
43
+
44
+ Present each template with its name, questions, and default schedule.
45
+ Let the user pick one or say "I want something custom."
46
+
47
+ Example presentation format:
48
+ ```
49
+ Here are some templates that might fit:
50
+
51
+ 1. **Daily Standup** — Mon–Fri at 10:00
52
+ Questions: What did you do? What will you do? Any blockers? How do you feel?
53
+
54
+ 2. **Quick Check-in** — Mon–Fri at 09:00
55
+ Questions: Main focus today? How are you feeling? Any blockers?
56
+
57
+ Which one works, or would you prefer something custom?
58
+ ```
59
+
60
+ ### Step 3: Gather required fields
61
+
62
+ For template-based creation, many fields have defaults. Only ask about
63
+ what's missing:
64
+
65
+ | Field | Template provides? | Action if missing |
66
+ |-------|-------------------|-------------------|
67
+ | Name | Yes (suggestive) | Let user customise or accept |
68
+ | Channel | No | Must ask — "Which Slack/Teams channel?" |
69
+ | Questions | Yes | Show them, let user add/remove/edit |
70
+ | Time | Yes (default) | Offer to change: "The default is 10:00 — does that work?" |
71
+ | Timezone | No | Infer from `geekbot me show` → `data.timezone`. Confirm. |
72
+ | Days | Yes (default) | Show the default, let user adjust |
73
+ | Users | No | Ask if they want to add members now or later |
74
+
75
+ For custom standups, gather all fields conversationally. Don't ask all
76
+ at once — lead with name + channel, then questions, then schedule.
77
+
78
+ ### Step 4: Confirm and execute
79
+
80
+ Present the full configuration in a clear summary:
81
+
82
+ ```
83
+ Standup: Sprint Retro
84
+ Channel: #engineering
85
+ Schedule: Fridays at 15:00 (Europe/Athens)
86
+ Questions:
87
+ 1. What went well?
88
+ 2. What could improve?
89
+ 3. What should we try next?
90
+
91
+ Ready to create?
92
+ ```
93
+
94
+ On confirmation, build and execute the CLI command:
95
+
96
+ ```bash
97
+ geekbot standup create \
98
+ --name "Sprint Retro" \
99
+ --channel "#engineering" \
100
+ --time "15:00" \
101
+ --timezone "Europe/Athens" \
102
+ --days "Fri" \
103
+ --questions '[{"text":"What went well?"},{"text":"What could improve?"},{"text":"What should we try next?"}]'
104
+ ```
105
+
106
+ ### Step 5: Post-creation
107
+
108
+ After success:
109
+ 1. Confirm with the created standup's ID and details
110
+ 2. If users weren't specified: "Want to add members now?"
111
+ - If yes: run `geekbot team list` to show teams with members and their IDs.
112
+ Let the user pick who to include, then:
113
+ `geekbot standup update <id> --users "U123,U456"`
114
+ - To find a specific person's ID: names appear alongside IDs in team list output
115
+ 3. Mention: "You can trigger it immediately with `geekbot standup start <id>`"
116
+
117
+ ### Edge cases
118
+
119
+ - **User doesn't know channel name**: Suggest they check Slack/Teams, or
120
+ just type the channel name without # (the CLI handles both)
121
+ - **User wants to edit questions after creation**: Use `standup update`
122
+ or `standup replace` depending on scope of changes
123
+ - **Questions with special characters**: Ensure JSON is properly escaped.
124
+ Single quotes inside questions need escaping in the shell command.
125
+
126
+ ---
127
+
128
+ ## Poll Creation Flow
129
+
130
+ Simpler than standups because polls have fewer moving parts.
131
+
132
+ ### Pre-check: Slack only
133
+
134
+ Polls require Slack. If you're unsure of the team's platform, try the
135
+ command — the CLI will return a descriptive platform error. Inform the
136
+ user and suggest using a standup with multiple-choice questions as an
137
+ alternative for Teams users.
138
+
139
+ ### Gather fields
140
+
141
+ All four fields are required:
142
+
143
+ 1. **Name** — what to call the poll
144
+ 2. **Channel** — where to post it
145
+ 3. **Question** — the poll question (single string)
146
+ 4. **Choices** — JSON array of answer options
147
+
148
+ ### Confirm and execute
149
+
150
+ ```bash
151
+ geekbot poll create \
152
+ --name "Team Lunch" \
153
+ --channel "#general" \
154
+ --question "Where should we eat?" \
155
+ --choices '["Pizza", "Sushi", "Tacos"]'
156
+ ```
157
+
158
+ ### Viewing results
159
+
160
+ ```bash
161
+ geekbot poll votes <id>
162
+ geekbot poll votes <id> --after "2026-03-01" # filter by date range
163
+ ```
164
+
165
+ Present results as a summary: total votes, per-choice breakdown, winner
166
+ (or tie). For polls with many responses over time, a bar chart helps.
167
+
168
+ ---
169
+
170
+ ## Analytics Playbook
171
+
172
+ Analytics in this skill are computed from report data fetched via the CLI.
173
+ The skill does the computation; the CLI provides raw data.
174
+
175
+ ### Data Fetching Strategy
176
+
177
+ Always scope data fetches to be useful but not excessive:
178
+
179
+ - **Last week**: `--after <monday> --before <today>` — good for "this week"
180
+ - **Last month**: `--after <30 days ago>` with `--limit 200`
181
+ - **Trend analysis**: multiple fetches, bucketed by week or month
182
+ - **Always use `--standup-id`** to scope results. Without it, you get
183
+ reports across all standups, which is rarely what the user wants.
184
+
185
+ ### Common Analysis Patterns
186
+
187
+ #### 1. Response Rate
188
+
189
+ **Question the user asks:** "How engaged is my team?" / "What's our response rate?"
190
+
191
+ **Method:**
192
+ 1. Fetch standup details: `geekbot standup get <id>` → get member count
193
+ 2. Fetch reports for the period: `geekbot report list --standup-id <id> --after <start>`
194
+ 3. Count the active days in the period — days that match the standup's `days`
195
+ field. For a Mon–Fri standup over 30 calendar days, that's ~22 working
196
+ days. Don't count weekends or days outside the schedule.
197
+ 4. Count actual reports submitted
198
+ 5. Response rate = reports submitted ÷ (members × active days)
199
+
200
+ **Resolving user IDs to names:** Report data uses user IDs (like `U08LXSA31BJ`).
201
+ To show human-readable names in analytics output, cross-reference with
202
+ `geekbot team list` which returns member names alongside IDs.
203
+
204
+ **Presentation:** Single percentage for the period, plus per-member breakdown
205
+ if the user wants details.
206
+
207
+ #### 2. Participation Gaps
208
+
209
+ **Question:** "Who hasn't posted?" / "Who's missing from standups?"
210
+
211
+ **Method:**
212
+ 1. Fetch member list from `geekbot standup get <id>`
213
+ 2. Fetch reports: `geekbot report list --standup-id <id> --after <start>`
214
+ 3. Extract unique `user_id` from reports
215
+ 4. Diff: members not in report submitters = gaps
216
+
217
+ **Presentation:** List the missing members by name. If some members are
218
+ partially missing (posted 2 of 5 days), note the frequency.
219
+
220
+ #### 3. Blocker Frequency
221
+
222
+ **Question:** "What are the common blockers?" / "Who's blocked most often?"
223
+
224
+ **Method:**
225
+ 1. Fetch reports: `geekbot report list --standup-id <id> --after <start> --limit 100`
226
+ 2. For each report, scan answers for blocker-related questions
227
+ (identify by question text containing "block", "stuck", "help", "impediment")
228
+ 3. Categorise: no blockers vs has blockers
229
+ 4. Track per-user blocker frequency
230
+ 5. Extract common themes from blocker text (group similar phrases)
231
+
232
+ **Presentation:** Narrative summary of most common blockers, who reports
233
+ them most, and whether they persist across reports.
234
+
235
+ #### 4. Trend Analysis
236
+
237
+ **Question:** "How has engagement changed?" / "Show me the trend"
238
+
239
+ **Method:**
240
+ 1. Fetch reports over a longer period (2-3 months)
241
+ 2. Bucket by week or month
242
+ 3. Compute response rate per bucket
243
+ 4. Show the trajectory: improving, stable, or declining
244
+
245
+ **Presentation:** Use a visualisation — a line chart or bar chart showing
246
+ response rate over time. Always include a narrative interpretation:
247
+ "Response rate improved from 62% to 85% over the last 6 weeks."
248
+
249
+ #### 5. Answer Quality / Length Trends
250
+
251
+ **Question:** "Are reports getting shorter?" / "Is engagement declining?"
252
+
253
+ **Method:**
254
+ 1. Fetch reports over time
255
+ 2. Track average answer length per report (character or word count)
256
+ 3. Track per week/month
257
+
258
+ **Presentation:** This is a leading indicator — declining answer length
259
+ often predicts disengagement before response rates drop.
260
+
261
+ #### 6. Cross-Referencing with Connected MCP Servers
262
+
263
+ **Question:** "Is the team actually delivering?" / "How does standup reporting
264
+ correlate with actual output?"
265
+
266
+ This pattern is only available when MCP servers for source code or project
267
+ management tools are connected. It goes beyond "who posted" to "what was
268
+ actually shipped."
269
+
270
+ **Entities to combine:**
271
+
272
+ | From Geekbot (CLI) | From source code MCP (GitHub/GitLab) | From project mgmt MCP (Jira/Linear/Asana) |
273
+ |---------------------|--------------------------------------|-------------------------------------------|
274
+ | Standup reports per member | Merged PRs per member | Completed tickets per member |
275
+ | Reported accomplishments (text) | Commit count, lines changed | Ticket status transitions |
276
+ | Reported blockers | Stale PRs, review-requested PRs | Blocked/on-hold tickets |
277
+
278
+ **What to look for:**
279
+ - Do reported accomplishments match actual deliverables? ("Shipped feature X"
280
+ should correlate with merged PRs or completed tickets)
281
+ - Are there team members who are delivering (merged PRs, closed tickets)
282
+ but not posting standups? They may need a nudge on reporting.
283
+ - Are there stale tickets or PRs that keep appearing as "working on it"
284
+ in reports? This signals genuine blockers worth escalating.
285
+ - Is some work not being tracked? If reports mention work that doesn't
286
+ appear in any tool, the team may have a tracking gap.
287
+
288
+ **Matching members across tools:** Geekbot uses Slack-style user IDs while
289
+ GitHub/Jira use their own identifiers. Match by email address when available
290
+ (from `geekbot team list` and the external MCP server's user data). If the
291
+ mapping is ambiguous, show the manager what you found and ask them to confirm.
292
+ Cache the mapping for the conversation.
293
+
294
+ **Presentation:** Be careful with framing — this is not a surveillance tool.
295
+ Frame as "finding gaps between reported work and tracked work so the team
296
+ can improve communication," not "catching people who aren't working." Focus
297
+ on systemic patterns (e.g., "the team reports more work than shows up in
298
+ Jira — maybe some work isn't being tracked") rather than calling out
299
+ individuals.
300
+
301
+ ### Tips for Analytics Conversations
302
+
303
+ - **Start with the question, not the data.** Ask what the user wants to
304
+ understand, then fetch only the data needed.
305
+ - **Scope appropriately.** "Last 2 weeks" is more actionable than "all time."
306
+ - **Always offer to drill deeper.** After a summary, ask if they want
307
+ per-member breakdowns or a longer time range.
308
+ - **Don't overstate precision.** If you're counting reports and dividing by
309
+ expected count, say "approximately 78%" not "78.26%".
310
+ - **Check for connected MCP servers.** If GitHub, Jira, or other MCP servers
311
+ are connected, mention that cross-referencing is available: "I can also
312
+ pull delivery data from GitHub to give a fuller picture — want me to?"
313
+
314
+ ---
315
+
316
+ ## Team Member Summary
317
+
318
+ The most common manager question: "What has X been up to?" / "Prep me
319
+ for my 1-1 with X." This workflow resolves a person, fetches their recent
320
+ reports, and synthesizes a narrative summary.
321
+
322
+ ### When to use
323
+
324
+ Trigger on: "what has X been up to", "X's reports", "1-1 prep for X",
325
+ "summarize X's work", "what did X report", "Jenny's recent standups",
326
+ "catch me up on X".
327
+
328
+ ### Step 1: Resolve the person
329
+
330
+ ```bash
331
+ geekbot team search <name>
332
+ ```
333
+
334
+ This returns matching team members with their IDs. If multiple matches,
335
+ show them and ask which one. If exactly one, proceed.
336
+
337
+ ### Step 2: Determine the time range
338
+
339
+ Map the user's language to a concrete date range:
340
+
341
+ | User says | Translate to |
342
+ |-----------|-------------|
343
+ | "lately", "recently" | Last 3 weeks |
344
+ | "this week" | Since Monday |
345
+ | "this month" | Since 1st of current month |
346
+ | "last 2 weeks" | 14 days ago |
347
+ | Explicit date | Use as-is |
348
+ | No time qualifier | Default to last 3 weeks |
349
+
350
+ ### Step 2.5: Find their standups (optional but recommended)
351
+
352
+ ```bash
353
+ geekbot standup list --member <id> --brief
354
+ ```
355
+
356
+ This shows which standups the person participates in. Use this to pick
357
+ the right standup for report fetching (typically the "Daily" or "status"
358
+ standup). This avoids fetching reports across all standups which can
359
+ fail on certain API response shapes.
360
+
361
+ ### Step 3: Fetch reports
362
+
363
+ ```bash
364
+ geekbot report list --standup-id <sid> --user-id <id> --after <date> --limit 20
365
+ ```
366
+
367
+ Use the standup ID from Step 2.5 (prefer the daily/status standup for
368
+ the most complete work picture).
369
+
370
+ If the result set is large (15+ reports), prioritize the most recent
371
+ and scan older ones for patterns rather than listing every detail.
372
+
373
+ ### Step 4: Synthesize
374
+
375
+ Group the report answers into themes:
376
+
377
+ 1. **Identify major work streams** — recurring project names, tasks, or
378
+ initiatives that span multiple reports
379
+ 2. **Track progress arcs** — things that started, progressed, and completed
380
+ 3. **Note blockers and sentiment** — persistent blockers, mood patterns,
381
+ health mentions (handle sensitively)
382
+ 4. **Spot context switches** — if the person bounced between many unrelated
383
+ tasks, note that as a possible discussion point
384
+
385
+ ### Step 5: Present
386
+
387
+ Structure the output as:
388
+
389
+ 1. **High-level summary** (2-3 sentences) — what they've been focused on
390
+ and any notable accomplishments
391
+ 2. **Work streams** — bullet points organized by theme, not chronologically.
392
+ Each stream should show what happened and current status.
393
+ 3. **Blockers / waiting on** — anything unresolved from recent reports
394
+ 4. **Suggested 1-1 talking points** (if the user mentioned 1-1 prep):
395
+ - Acknowledge completed milestones
396
+ - Ask about persistent blockers or waiting items
397
+ - Discuss workload balance if context-switching is high
398
+ - Check in on wellbeing if sentiment patterns warrant it
399
+
400
+ ### Presentation tips
401
+
402
+ - **Lead with themes, not dates.** "Jenny drove the software certification
403
+ to completion" is more useful than a chronological list of daily reports.
404
+ - **Be sensitive with health/sentiment data.** If reports mention illness
405
+ or pain, note it factually as context but don't frame it as a performance
406
+ issue.
407
+ - **Keep it scannable.** The manager wants to walk into the 1-1 prepared,
408
+ not read an essay. Aim for a summary that takes 30 seconds to read.