work-chronicler 0.2.2 → 0.3.1

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.
@@ -57,6 +57,17 @@ Analyze work history to identify major projects and group related work.
57
57
  - Consider temporal clustering (work in same 2-4 week period)
58
58
  - Use PR labels and repository patterns
59
59
 
60
+ ## Output Location
61
+
62
+ **IMPORTANT:** You must do BOTH of the following:
63
+
64
+ 1. **Respond in-thread** with the project summary (for immediate feedback and MCP integration)
65
+ 2. **Save to file**: `<profile-root>/outputs/projects-detected-YYYY-MM-DD.md`
66
+
67
+ Get the profile root with: `work-chronicler workspace root`
68
+
69
+ This ensures users have both immediate feedback AND a persistent file they can reference later.
70
+
60
71
  ## Project Summary Format
61
72
 
62
73
  For each project, gather:
@@ -77,6 +77,17 @@ Work data is stored in the workspace work-log directory:
77
77
  - PR titles and descriptions keywords
78
78
  - Timeline trends (what themes emerged when?)
79
79
 
80
+ ## Output Location
81
+
82
+ **IMPORTANT:** You must do BOTH of the following:
83
+
84
+ 1. **Respond in-thread** with the themes analysis (for immediate feedback and MCP integration)
85
+ 2. **Save to file**: `<profile-root>/outputs/themes-detected-YYYY-MM-DD.md`
86
+
87
+ Get the profile root with: `work-chronicler workspace root`
88
+
89
+ This ensures users have both immediate feedback AND a persistent file they can reference later.
90
+
80
91
  ## Output Format
81
92
 
82
93
  ```markdown
@@ -66,7 +66,14 @@ Work data is stored in the workspace work-log directory:
66
66
 
67
67
  ## Output Location
68
68
 
69
- Save generated documents to `generated/resume-bullets-YYYY-MM-DD.md` in the workspace root.
69
+ **IMPORTANT:** You must do BOTH of the following:
70
+
71
+ 1. **Respond in-thread** with the resume bullets (for immediate feedback and MCP integration)
72
+ 2. **Save to file**: `<profile-root>/outputs/resume-bullets-YYYY-MM-DD.md`
73
+
74
+ Get the profile root with: `work-chronicler workspace root`
75
+
76
+ This ensures users have both immediate feedback AND a persistent file they can reference later.
70
77
 
71
78
  ## Bullet Point Format
72
79
 
@@ -0,0 +1,469 @@
1
+ ---
2
+ name: work-chronicler-mgmt-write-peer-review
3
+ description: Write peer reviews for colleagues. Use when writing peer feedback, 360 reviews, or colleague evaluations. Supports both evidence-based reviews (with work-log data) and narrative reviews (notes-only).
4
+ user-invocable: true
5
+ disable-model-invocation: true
6
+ ---
7
+
8
+ # Write Peer Review
9
+
10
+ Write peer reviews for colleagues. Adapts to available data - works with full work-log evidence or just manager/peer notes.
11
+
12
+ ## Quick Review vs Full Mode
13
+
14
+ **Quick mode** (no report needed):
15
+ - For one-off peer reviews
16
+ - Interactive questions only (no work-log data or supporting documents)
17
+ - Saves to `outputs/peer-review-{name}-{date}.md` in your current profile
18
+ - Works in any profile (IC or manager mode)
19
+
20
+ **Full mode** (with report):
21
+ - Track peer over time with notes, work-log, past reviews
22
+ - **Requires manager mode and adding them as a report** (even if they don't report to you)
23
+ - Saves to `reports/{report-id}/outputs/peer-review-{date}.md`
24
+ - Use this if you want to:
25
+ - Reference their work-log data (PRs, tickets)
26
+ - Add notes about them over time
27
+ - Include past peer reviews or performance reviews
28
+ - Build evidence-based reviews with specific examples
29
+
30
+ > **Important:** If you want to use work-log data or additional supporting artifacts (notes, past reviews, etc.), you MUST add them as a report in manager mode. Quick mode is interactive-only with no data references.
31
+
32
+ ## Workspace
33
+
34
+ **Active profile:** !`work-chronicler workspace profile`
35
+ **Manager root:** !`work-chronicler workspace root`
36
+
37
+ > **For non-Claude tools:** Run `work-chronicler workspace root` to get your manager profile path.
38
+
39
+ ## User Input
40
+
41
+ **Optional:**
42
+ - **Report ID**: The kebab-case identifier if using full mode (e.g., "alice-smith")
43
+ - See available reports: `work-chronicler reports list`
44
+ - If not provided, skill will ask if this is a quick review or if you want to add them as a report
45
+
46
+ **Also Optional:**
47
+ - **Review period**: Time range if relevant (e.g., "Q4 2025", "2025 annual")
48
+ - **Review template**: Company-specific questions or format to follow
49
+ - **Focus areas**: Specific themes, projects, or competencies to address
50
+
51
+ **Example invocations:**
52
+
53
+ *Full mode (with report):*
54
+ - `/work-chronicler-mgmt-write-peer-review alice-smith`
55
+ - `/work-chronicler-mgmt-write-peer-review bob-jones Q4-2025`
56
+
57
+ *Quick mode (no report):*
58
+ - `/work-chronicler-mgmt-write-peer-review` → Will ask if quick review or add report
59
+
60
+ **When user provides a template:**
61
+
62
+ If the template includes structured rating questions (e.g., "Rarely/Sometimes/Consistently"), automatically offer interactive mode:
63
+
64
+ > "I see your template has rating questions. Would you like me to guide you through each question interactively, collect your answers, and synthesize them into a polished narrative review?"
65
+
66
+ If they say yes, proceed to Interactive Mode (step 3a in Instructions).
67
+ If they say no, use the template as-is and ask them to provide their overall thoughts.
68
+
69
+ **Template parsing:**
70
+ - Extract all competency statements (e.g., "They easily adapt to change")
71
+ - Note the rating scale (Rarely/Sometimes/Consistently, or Poor/Good/Excellent, etc.)
72
+ - Identify any open-ended questions at the end
73
+ - Preserve any company-specific sections or requirements
74
+
75
+ ## Data Location
76
+
77
+ **Quick mode** (no supporting data):
78
+ ```
79
+ <profile-root>/
80
+ └── outputs/ # Generated peer reviews
81
+ └── peer-review-{name}-{date}.md
82
+ ```
83
+
84
+ **Full mode** (with report in manager mode):
85
+ ```
86
+ <manager-root>/
87
+ └── reports/
88
+ └── <report-id>/
89
+ ├── work-log/ # Optional - may not exist for peers
90
+ │ ├── pull-requests/ # Evidence if available
91
+ │ └── jira/ # Evidence if available
92
+ ├── analysis/ # Optional - only if work-log exists
93
+ │ ├── stats.json
94
+ │ ├── projects.json
95
+ │ └── timeline.json
96
+ ├── notes/ # IMPORTANT: Your observations and collaboration notes
97
+ ├── peer-reviews/ # Optional: Feedback from others about this person
98
+ ├── performance-reviews/ # Optional: Past reviews for context
99
+ └── outputs/ # Generated peer reviews
100
+ ```
101
+
102
+ ## Instructions
103
+
104
+ 1. **Determine mode (quick vs full)**:
105
+
106
+ **If user provided a report ID:**
107
+ - Validate it exists in manager config
108
+ - Use exact report ID provided by user
109
+ - If invalid, show available reports via `work-chronicler reports list`
110
+ - Proceed with full mode (skip to step 2)
111
+
112
+ **If NO report ID provided:**
113
+
114
+ Ask the user:
115
+ > "Is this a quick peer review, or would you like to add them as a report to track over time?"
116
+
117
+ **If they choose "Quick peer review":**
118
+ - Ask: "What is the person's name?"
119
+ - Store name for output filename (convert to kebab-case: "Alice Smith" → "alice-smith")
120
+ - Skip to step 2 (no data to check, will use interactive mode only)
121
+ - **Save location:** `<profile-root>/outputs/peer-review-{name}-{date}.md`
122
+
123
+ **If they choose "Add as report":**
124
+ - Explain: "Adding them as a report lets you track work-log data, notes, and past reviews for evidence-based peer reviews. Even if they don't report to you, this is how you include supporting data."
125
+ - Show them: "To add them as a report, run these commands:"
126
+ ```bash
127
+ work-chronicler init --mode manager # If not already in manager mode
128
+ work-chronicler reports add <their-id> --skip-fetch
129
+
130
+ # Then optionally add supporting data:
131
+ # - Add notes: reports/<their-id>/notes/observations.md
132
+ # - Fetch their PRs: work-chronicler fetch github --report <their-id>
133
+ # - Fetch their tickets: work-chronicler fetch jira --report <their-id>
134
+ ```
135
+ - Ask: "Have you added them as a report? If so, what's the report ID?"
136
+ - If they provide ID, validate and proceed with full mode
137
+ - If they say no, offer to continue with quick mode instead
138
+
139
+ 2. **Ask about template FIRST**:
140
+
141
+ ⚠️ **ALWAYS start by asking this question:**
142
+
143
+ > "Does your company provide a peer review template or specific questions you need to answer? If so, please paste it now."
144
+
145
+ **If they provide a template:**
146
+ - Parse it for structured rating questions (Rarely/Sometimes/Consistently, etc.)
147
+ - Note any open-ended questions
148
+ - Preserve company-specific format requirements
149
+ - Proceed to step 3 with template context
150
+
151
+ **If they say no template:**
152
+ - Use standard competency questions (defined in step 4a)
153
+ - Proceed to step 3
154
+
155
+ 3. **Check what data is available** (full mode only, skip in quick mode):
156
+
157
+ **If quick mode:**
158
+ - Skip this step - no data to check
159
+ - Proceed directly to step 2 (ask about template)
160
+
161
+ **If full mode (with report):**
162
+ - Look for `work-log/pull-requests/` and `work-log/jira/` directories
163
+ - Check if `analysis/` exists
164
+ - Always check `notes/` directory (critical for peer reviews)
165
+ - Check `peer-reviews/` and `performance-reviews/` for additional context
166
+
167
+ 4. **Determine review mode**:
168
+
169
+ **If user provided a template with structured questions:**
170
+ - Ask: "Would you like to answer these questions interactively, or provide your own notes?"
171
+ - If interactive → proceed to Interactive Mode (step 4a)
172
+ - If notes → skip to step 5
173
+
174
+ **If minimal/no notes and no template:**
175
+ - Suggest interactive mode: "I don't see many notes. Would you like me to guide you through some peer review questions?"
176
+ - Offer to use standard competency questions (see below)
177
+
178
+ 4a. **Interactive Mode** (when selected):
179
+
180
+ **Common template format** (example):
181
+ ```
182
+ They easily adapt to change.
183
+ □ Rarely □ Sometimes □ Consistently
184
+
185
+ They welcome perspectives different from their own.
186
+ □ Rarely □ Sometimes □ Consistently
187
+
188
+ They commit to tasks and see them through to completion.
189
+ □ Rarely □ Sometimes □ Consistently
190
+
191
+ [etc.]
192
+
193
+ Additional feedback: [open text field]
194
+ ```
195
+
196
+ **For each question/competency:**
197
+
198
+ 1. **Present the competency statement**
199
+ - Example: "They easily adapt to change"
200
+
201
+ 2. **Ask for the rating**
202
+ - "How would you rate this? (Rarely / Sometimes / Consistently)"
203
+ - Accept their response
204
+
205
+ 3. **Ask for context/examples**
206
+ - "Would you like to share specific examples or context for this rating?"
207
+ - If they say yes, collect their examples
208
+ - If they say no or their answer is vague, prompt: "Can you think of a specific situation that illustrates this?"
209
+
210
+ 4. **Move to next question**
211
+ - Repeat for all competencies in template
212
+
213
+ 5. **Ask for additional open feedback**
214
+ - "Is there anything else you'd like to mention about working with [Name]?"
215
+ - "Any other strengths or growth areas to highlight?"
216
+
217
+ **Standard competency questions** (use if no template provided):
218
+ - "They adapt to change" (Rarely/Sometimes/Consistently) + Examples?
219
+ - "They welcome different perspectives" (Rarely/Sometimes/Consistently) + Examples?
220
+ - "They commit to tasks and see them through" (Rarely/Sometimes/Consistently) + Examples?
221
+ - "They are open to feedback" (Rarely/Sometimes/Consistently) + Examples?
222
+ - "They take initiative" (Rarely/Sometimes/Consistently) + Examples?
223
+ - "They communicate effectively" (Rarely/Sometimes/Consistently) + Examples?
224
+ - "They demonstrate technical excellence" (Rarely/Sometimes/Consistently) + Examples?
225
+
226
+ **After gathering all answers:**
227
+
228
+ **DO NOT** output a bullet list of ratings. Instead:
229
+
230
+ 1. **Synthesize into narrative prose**
231
+ - Convert ratings and examples into natural paragraphs
232
+ - Group related competencies together
233
+ - Use their specific examples as evidence
234
+
235
+ 2. **Example synthesis:**
236
+
237
+ ❌ **Bad (don't do this):**
238
+ ```
239
+ - Adapts to change: Consistently
240
+ - Welcomes different perspectives: Sometimes
241
+ - Commits to tasks: Consistently
242
+ ```
243
+
244
+ ✅ **Good (do this):**
245
+ ```
246
+ Alice demonstrates strong adaptability and commitment to her work.
247
+ She consistently adapts to change - for example, when we pivoted
248
+ the auth migration approach mid-sprint, she quickly adjusted her
249
+ implementation and helped the team understand the new direction.
250
+ She also commits fully to tasks and sees them through; I've never
251
+ seen her drop a commitment, even when priorities shift.
252
+
253
+ In terms of collaboration, Alice sometimes struggles to welcome
254
+ perspectives different from her own. During design reviews, I've
255
+ noticed she can be defensive about her approach initially, though
256
+ she generally comes around after discussion. This is an area where
257
+ continued growth would strengthen her impact on the team.
258
+ ```
259
+
260
+ 3. **Organization tips:**
261
+ - Group "Consistently" items together as strengths
262
+ - Address "Sometimes" or "Rarely" items as growth opportunities
263
+ - Use their specific examples to make it concrete
264
+ - Balance positive and constructive feedback
265
+ - Write in first person ("I've observed", "In my experience working with them")
266
+
267
+ 5. **Read supporting documents** (critical context):
268
+ - `notes/` - YOUR observations about working with this person
269
+ - `peer-reviews/` - What others have said about them
270
+ - `performance-reviews/` - Past review language and format (if available)
271
+
272
+ 6. **Adapt approach based on available data**:
273
+
274
+ **If quick mode (no data):**
275
+ - Use interactive mode exclusively
276
+ - Rely entirely on template questions or standard competencies
277
+ - Synthesize user's responses into prose
278
+
279
+ **If full mode with work-log data:**
280
+ - Read `analysis/stats.json`, `projects.json`, `timeline.json`
281
+ - Focus on flagship and major impact work
282
+ - Cross-reference with notes for collaboration context
283
+ - Use evidence-based structure (see below)
284
+
285
+ **If full mode with only notes:**
286
+ - Focus entirely on qualitative observations from notes
287
+ - Organize by themes from notes
288
+ - Supplement with interactive questions if notes are minimal
289
+ - Use narrative structure (see below)
290
+
291
+ 7. **Structure the review**:
292
+
293
+ **Evidence-based format** (when work-log exists):
294
+ ```markdown
295
+ # Peer Review: [Name]
296
+ **Review Period:** [Period]
297
+ **Reviewed by:** [Your name from context]
298
+ **Date:** [Current date]
299
+
300
+ ## Summary
301
+ [2-3 sentences on overall collaboration and impact]
302
+
303
+ ### Technical Contributions
304
+ - **[Project/Area]**: [What they did, impact, your observations]
305
+ - **[Project/Area]**: [What they did, impact, your observations]
306
+
307
+ ### Collaboration & Communication
308
+ - [How they work with others]
309
+ - [Communication effectiveness]
310
+ - [Cross-team work examples]
311
+
312
+ ### Strengths
313
+ - [What they excel at]
314
+ - [Skills that stand out]
315
+
316
+ ### Growth Opportunities
317
+ - [Areas for development]
318
+ - [Constructive feedback]
319
+ ```
320
+
321
+ **Narrative format** (when only notes exist):
322
+ ```markdown
323
+ # Peer Review: [Name]
324
+ **Review Period:** [Period]
325
+ **Reviewed by:** [Your name from context]
326
+ **Date:** [Current date]
327
+
328
+ ## Summary
329
+ [2-3 sentences on your working relationship and overall assessment]
330
+
331
+ ### What I've Observed
332
+
333
+ #### Strengths
334
+ - [Specific observations from notes]
335
+ - [Examples of excellent work or collaboration]
336
+
337
+ #### Areas of Impact
338
+ - [Projects or areas where they've made a difference]
339
+ - [How they've helped you or the team]
340
+
341
+ #### Collaboration Style
342
+ - [How they communicate]
343
+ - [How they work with others]
344
+ - [Team dynamics]
345
+
346
+ ### Constructive Feedback
347
+ - [Growth areas]
348
+ - [Development opportunities]
349
+
350
+ ### Overall Assessment
351
+ [Final thoughts on working with this person]
352
+ ```
353
+
354
+ **Interactive mode format** (synthesized from template questions):
355
+ ```markdown
356
+ # Peer Review: [Name]
357
+ **Review Period:** [Period]
358
+ **Reviewed by:** [Your name from context]
359
+ **Date:** [Current date]
360
+
361
+ ## Summary
362
+ [2-3 sentences highlighting key strengths and overall impression]
363
+
364
+ ## Work Style & Collaboration
365
+
366
+ [Synthesized narrative from "adapt to change", "welcome perspectives",
367
+ "open to feedback" responses. Group "Consistently" ratings together as
368
+ strengths, weave in specific examples provided during interactive mode]
369
+
370
+ Example:
371
+ Alice consistently demonstrates strong adaptability and openness to
372
+ feedback. When we pivoted our auth migration approach mid-sprint, she
373
+ quickly adjusted her implementation without complaint and helped onboard
374
+ others to the new direction. She's also receptive to feedback - during
375
+ code reviews, I've seen her thoughtfully incorporate suggestions and
376
+ explain her reasoning when she disagrees, leading to better outcomes.
377
+
378
+ ## Reliability & Initiative
379
+
380
+ [Synthesized narrative from "commit to tasks", "take initiative"
381
+ responses]
382
+
383
+ Example:
384
+ I can consistently count on Alice to follow through on commitments. She
385
+ takes initiative when problems arise - for instance, when we discovered
386
+ a security gap in our API, she proactively researched solutions and
387
+ presented options to the team before being asked.
388
+
389
+ ## Areas for Growth
390
+
391
+ [Synthesized narrative from "Sometimes" or "Rarely" ratings, with
392
+ constructive framing and specific examples]
393
+
394
+ Example:
395
+ One area where Alice could grow is in welcoming perspectives different
396
+ from her own. During design discussions, I've noticed she can initially
397
+ be defensive about her approach, though she generally comes around after
398
+ further discussion. Actively seeking out alternative viewpoints earlier
399
+ in the process could strengthen her designs and team collaboration.
400
+
401
+ ## Additional Feedback
402
+
403
+ [Any open-ended thoughts provided during interactive mode]
404
+ ```
405
+
406
+ 8. **Template adaptation**:
407
+ - If user provided a template (from step 2), use that structure exactly
408
+ - Map available data and interactive responses to template questions
409
+ - Note where you don't have information to answer specific questions
410
+
411
+ ## Output Location
412
+
413
+ **Quick mode** (no report ID):
414
+ ```
415
+ <profile-root>/outputs/peer-review-{name}-YYYY-MM-DD.md
416
+ ```
417
+
418
+ Example: `~/.work-chronicler/profiles/default/outputs/peer-review-alice-smith-2026-02-13.md`
419
+
420
+ Use the person's name in kebab-case (e.g., "Alice Smith" → "alice-smith").
421
+
422
+ **Full mode** (with report ID):
423
+ ```
424
+ <manager-root>/reports/<report-id>/outputs/peer-review-YYYY-MM-DD.md
425
+ ```
426
+
427
+ Example: `~/.work-chronicler/profiles/manager/reports/alice-smith/outputs/peer-review-2026-02-13.md`
428
+
429
+ Use the exact report ID in the path.
430
+
431
+ **Important:** Ensure the document clearly indicates this is PEER REVIEW feedback:
432
+ - Filename must include `peer-review-` prefix (and person's name in quick mode)
433
+ - Document title should say "Peer Review" or "Peer Feedback"
434
+ - Use first-person language ("I observed", "Working with them")
435
+ - This distinguishes it from manager performance reviews
436
+
437
+ ## Important Constraints
438
+
439
+ - ✅ Be specific and honest
440
+ - ✅ Balance positive feedback with constructive growth areas
441
+ - ✅ Focus on observable behaviors and outcomes
442
+ - ❌ No rankings or numerical scores
443
+ - ❌ No comparisons with other team members
444
+ - ❌ Don't make up evidence - only cite what you have
445
+
446
+ ## Tips
447
+
448
+ - **If notes are minimal**: Ask the user if they want to add more observations before generating
449
+ - **For evidence-based reviews**: Connect code contributions to team/business impact
450
+ - **For narrative reviews**: Use specific examples from notes rather than vague praise
451
+ - **Tone**: Professional but authentic - this is peer feedback, not a formal manager review
452
+ - **Balance**: Include both strengths and growth areas in every review
453
+ - **Be specific**: "Great communicator" is weak; "Proactively documented the auth migration in Confluence, making it easy for others to contribute" is strong
454
+ - **Use first person**: "I observed...", "Working with them on...", "I appreciated..."
455
+
456
+ ## Adding Notes Before Generating
457
+
458
+ If you don't have enough notes to write a meaningful review, suggest the user add observations first:
459
+
460
+ ```bash
461
+ # Create a notes file
462
+ echo "Observations about Alice:
463
+ - Led the auth migration, clear communication
464
+ - Great at explaining complex systems
465
+ - Sometimes moves too fast, could involve team more in decisions
466
+ " > reports/alice-smith/notes/collaboration.md
467
+ ```
468
+
469
+ Then re-run the skill.
@@ -65,6 +65,17 @@ Generate a summary including:
65
65
  - **Timeline**: Busiest periods, activity trends
66
66
  - **Notable Contributions**: Largest PRs, most complex changes
67
67
 
68
+ ## Output Location
69
+
70
+ **IMPORTANT:** You must do BOTH of the following:
71
+
72
+ 1. **Respond in-thread** with the work summary (for immediate feedback and MCP integration)
73
+ 2. **Save to file**: `<profile-root>/outputs/work-summary-YYYY-MM-DD.md`
74
+
75
+ Get the profile root with: `work-chronicler workspace root`
76
+
77
+ This ensures users have both immediate feedback AND a persistent file they can reference later.
78
+
68
79
  ## Example Output
69
80
 
70
81
  ```markdown
@@ -104,7 +104,14 @@ Work data is stored in the workspace work-log directory:
104
104
 
105
105
  ## Output Location
106
106
 
107
- Save generated documents to `generated/resume-updated-YYYY-MM-DD.md` in the workspace root.
107
+ **IMPORTANT:** You must do BOTH of the following:
108
+
109
+ 1. **Respond in-thread** with the resume updates (for immediate feedback and MCP integration)
110
+ 2. **Save to file**: `<profile-root>/outputs/resume-updated-YYYY-MM-DD.md`
111
+
112
+ Get the profile root with: `work-chronicler workspace root`
113
+
114
+ This ensures users have both immediate feedback AND a persistent file they can reference later.
108
115
 
109
116
  ## Output Format
110
117
 
@@ -75,7 +75,14 @@ Work data is stored in the workspace work-log directory:
75
75
 
76
76
  ## Output Location
77
77
 
78
- Save generated documents to `generated/self-review-YYYY-MM-DD.md` in the workspace root.
78
+ **IMPORTANT:** You must do BOTH of the following:
79
+
80
+ 1. **Respond in-thread** with the self-review (for immediate feedback and MCP integration)
81
+ 2. **Save to file**: `<profile-root>/outputs/self-review-YYYY-MM-DD.md`
82
+
83
+ Get the profile root with: `work-chronicler workspace root`
84
+
85
+ This ensures users have both immediate feedback AND a persistent file they can reference later.
79
86
 
80
87
  ## Output Format
81
88
 
package/README.md CHANGED
@@ -17,7 +17,9 @@ But you didn't take notes, and now you're scrolling through months of PRs trying
17
17
 
18
18
  ### For Managers
19
19
 
20
- Manager mode extends work-chronicler for people managers tracking multiple direct reports. Collect work history for your team, generate evidence-based performance reviews, and maintain team visibility across projects. See the [Manager Mode Guide](docs/manager-mode.md) for details.
20
+ Manager mode extends work-chronicler for people managers tracking multiple direct reports. Collect work history for your team, generate evidence-based performance reviews, and maintain team visibility across projects.
21
+
22
+ **📚 See the [Manager Mode Guide](documentation/manager-mode.md) for complete documentation.**
21
23
 
22
24
  ## Quick Start
23
25
 
@@ -273,7 +275,15 @@ See [work-chronicler.example.yaml](work-chronicler.example.yaml) for a complete
273
275
 
274
276
  ### GitHub Token
275
277
 
276
- Create a personal access token at https://github.com/settings/tokens with the `repo` scope (or `public_repo` for public repos only).
278
+ Create a personal access token at https://github.com/settings/tokens with the following scopes:
279
+
280
+ **Required:**
281
+ - `repo` (for private repos) or `public_repo` (for public repos only)
282
+
283
+ **Required for auto-discovery with organizations:**
284
+ - `read:org` - Needed to query organization repositories during `init` auto-discovery
285
+
286
+ Without `read:org`, you can still use work-chronicler by entering repos manually during setup.
277
287
 
278
288
  ### JIRA Token
279
289
 
@@ -327,9 +337,12 @@ After installation, these skills are available as slash commands in your AI codi
327
337
  | Skill | Description |
328
338
  |-------|-------------|
329
339
  | `/work-chronicler-mgmt-write-review-packet` | Generate evidence-based performance review for a direct report |
340
+ | `/work-chronicler-mgmt-write-peer-review` | Write peer reviews for colleagues (works with or without work-log data) |
330
341
  | `/work-chronicler-mgmt-quarterly-highlights` | Create concise quarterly summary for 1:1s and calibration |
331
342
  | `/work-chronicler-mgmt-team-summary` | Generate team-level overview for leadership and calibration |
332
343
 
344
+ **📚 For detailed skill documentation, see [Available Skills Guide](documentation/available-skills.md)**
345
+
333
346
  ### Supported AI Tools
334
347
 
335
348
  Skills can be installed to:
@@ -1 +1 @@
1
- {"version":3,"file":"all.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/fetch/all.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwMpC,eAAO,MAAM,UAAU,SA2BnB,CAAC"}
1
+ {"version":3,"file":"all.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/fetch/all.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA8LpC,eAAO,MAAM,UAAU,SA2BnB,CAAC"}
@@ -10,7 +10,7 @@ import { isManagerMode } from '../../../core/workspace/resolver.js';
10
10
  import chalk from 'chalk';
11
11
  import { Command } from 'commander';
12
12
  import { resolveCacheBehavior } from './fetch.utils.js';
13
- import { getReportById, resolveReportIds, resolveReportOutputDir, } from './fetch-manager.utils.js';
13
+ import { buildReportConfig, getReportById, loadManagerConfigForFetch, resolveReportIds, resolveReportOutputDir, } from './fetch-manager.utils.js';
14
14
  import { fetchGitHubPRs } from './github/github.utils.js';
15
15
  import { fetchJiraTickets } from './jira/jira.utils.js';
16
16
  /**
@@ -89,28 +89,16 @@ async function fetchAllICMode(options) {
89
89
  async function fetchAllManagerMode(options) {
90
90
  const reportIds = await resolveReportIds(options);
91
91
  console.log(chalk.blue(`\n📥 Fetching all data for ${reportIds.length} report(s)...\n`));
92
- // Load config once outside loop (for efficiency)
93
- const baseConfig = await loadConfig(options.config);
92
+ // Load manager config once outside loop (for efficiency)
93
+ const managerConfig = loadManagerConfigForFetch();
94
94
  for (let i = 0; i < reportIds.length; i++) {
95
95
  const reportId = reportIds[i];
96
96
  const report = getReportById(reportId);
97
97
  console.log(chalk.blue(`\n=== Fetching data for ${report.name} (${i + 1}/${reportIds.length}) ===\n`));
98
98
  try {
99
99
  const outputDir = resolveReportOutputDir(reportId);
100
- // Override config with report's credentials
101
- const reportConfig = {
102
- ...baseConfig,
103
- github: {
104
- ...baseConfig.github,
105
- username: report.github, // Use report's GitHub username
106
- },
107
- jira: baseConfig.jira
108
- ? {
109
- ...baseConfig.jira,
110
- email: report.email, // Use report's Jira email
111
- }
112
- : undefined,
113
- };
100
+ // Build IC-compatible config from manager config + report
101
+ const reportConfig = buildReportConfig(managerConfig, report);
114
102
  // Determine cache behavior - prompt if data exists and --cache not specified
115
103
  const useCache = await resolveCacheBehavior({
116
104
  outputDir,
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * Manager mode fetch utilities
3
3
  */
4
- import type { ReportConfig } from '../../../core/types/manager.js';
4
+ import type { Config } from '../../../core/config/schema.js';
5
+ import type { ManagerConfig, ReportConfig } from '../../../core/types/manager.js';
5
6
  /**
6
7
  * Resolve report ID(s) for fetch operation
7
8
  *
@@ -26,4 +27,22 @@ export declare function getReportById(reportId: string): ReportConfig;
26
27
  * @returns Absolute path to report's work-log directory
27
28
  */
28
29
  export declare function resolveReportOutputDir(reportId: string): string;
30
+ /**
31
+ * Load and return the manager config for the active profile.
32
+ *
33
+ * @returns Manager config validated against ManagerConfigSchema
34
+ */
35
+ export declare function loadManagerConfigForFetch(): ManagerConfig;
36
+ /**
37
+ * Build an IC-compatible Config from a manager config and a specific report.
38
+ *
39
+ * The fetch utilities (fetchGitHubPRs, fetchJiraTickets, linkPRsToTickets)
40
+ * all expect a Config (IC schema). This function bridges the gap by
41
+ * constructing one from the manager config + per-report overrides.
42
+ *
43
+ * @param managerConfig - The manager profile config
44
+ * @param report - The specific report to build the config for
45
+ * @returns A Config object compatible with IC fetch utilities
46
+ */
47
+ export declare function buildReportConfig(managerConfig: ManagerConfig, report: ReportConfig): Config;
29
48
  //# sourceMappingURL=fetch-manager.utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-manager.utils.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/fetch/fetch-manager.utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAOtD;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAyDpB;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,CAa5D;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAG/D"}
1
+ {"version":3,"file":"fetch-manager.utils.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/fetch/fetch-manager.utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAOrE;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAyDpB;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,CAa5D;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAG/D;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,IAAI,aAAa,CAGzD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,aAAa,EAAE,aAAa,EAC5B,MAAM,EAAE,YAAY,GACnB,MAAM,CA+CR"}
@@ -81,3 +81,68 @@ export function resolveReportOutputDir(reportId) {
81
81
  const activeProfile = getActiveProfile();
82
82
  return getReportWorkLogDir(activeProfile, reportId);
83
83
  }
84
+ /**
85
+ * Load and return the manager config for the active profile.
86
+ *
87
+ * @returns Manager config validated against ManagerConfigSchema
88
+ */
89
+ export function loadManagerConfigForFetch() {
90
+ const activeProfile = getActiveProfile();
91
+ return loadManagerConfig(activeProfile);
92
+ }
93
+ /**
94
+ * Build an IC-compatible Config from a manager config and a specific report.
95
+ *
96
+ * The fetch utilities (fetchGitHubPRs, fetchJiraTickets, linkPRsToTickets)
97
+ * all expect a Config (IC schema). This function bridges the gap by
98
+ * constructing one from the manager config + per-report overrides.
99
+ *
100
+ * @param managerConfig - The manager profile config
101
+ * @param report - The specific report to build the config for
102
+ * @returns A Config object compatible with IC fetch utilities
103
+ */
104
+ export function buildReportConfig(managerConfig, report) {
105
+ // Build GitHub orgs array from manager org + report repos
106
+ const orgs = [
107
+ {
108
+ name: managerConfig.github.org,
109
+ repos: report.repos.length > 0 ? report.repos : ['*'],
110
+ },
111
+ ];
112
+ // Build JIRA instances from manager's JIRA config + report's projects
113
+ const jira = managerConfig.jira && report.jiraProjects.length > 0
114
+ ? {
115
+ instances: [
116
+ {
117
+ name: managerConfig.jira.host,
118
+ url: managerConfig.jira.host.startsWith('https://')
119
+ ? managerConfig.jira.host
120
+ : `https://${managerConfig.jira.host}`,
121
+ email: report.email,
122
+ token: managerConfig.jira.token,
123
+ projects: report.jiraProjects,
124
+ },
125
+ ],
126
+ }
127
+ : undefined;
128
+ return {
129
+ github: {
130
+ username: report.github,
131
+ token: managerConfig.github.token,
132
+ orgs,
133
+ },
134
+ jira,
135
+ output: { directory: './work-log' },
136
+ fetch: {
137
+ since: managerConfig.fetch.since,
138
+ until: managerConfig.fetch.until,
139
+ },
140
+ analysis: {
141
+ thresholds: {
142
+ minor: { maxLines: 20, maxFiles: 3 },
143
+ major: { minLines: 200, minFiles: 8 },
144
+ flagship: { minLines: 500, minFiles: 15 },
145
+ },
146
+ },
147
+ };
148
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/fetch/github/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAcH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwHpC,eAAO,MAAM,aAAa,SA0BtB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/fetch/github/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAcH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoHpC,eAAO,MAAM,aAAa,SA0BtB,CAAC"}
@@ -11,7 +11,7 @@ import { getActiveProfile } from '../../../../core/workspace/global-config.js';
11
11
  import { isManagerMode } from '../../../../core/workspace/resolver.js';
12
12
  import chalk from 'chalk';
13
13
  import { Command } from 'commander';
14
- import { getReportById, resolveReportIds, resolveReportOutputDir, } from '../fetch-manager.utils.js';
14
+ import { buildReportConfig, getReportById, loadManagerConfigForFetch, resolveReportIds, resolveReportOutputDir, } from '../fetch-manager.utils.js';
15
15
  import { fetchGitHubPRs } from './github.utils.js';
16
16
  /**
17
17
  * Fetch GitHub PRs in IC mode
@@ -43,22 +43,16 @@ async function fetchGitHubICMode(options) {
43
43
  async function fetchGitHubManagerMode(options) {
44
44
  const reportIds = await resolveReportIds(options);
45
45
  console.log(chalk.blue(`\n📥 Fetching GitHub PRs for ${reportIds.length} report(s)...\n`));
46
- // Load base config
47
- const baseConfig = await loadConfig(options.config);
46
+ // Load manager config
47
+ const managerConfig = loadManagerConfigForFetch();
48
48
  for (let i = 0; i < reportIds.length; i++) {
49
49
  const reportId = reportIds[i];
50
50
  const report = getReportById(reportId);
51
51
  console.log(chalk.blue(`\nFetching data for ${report.name} (${i + 1}/${reportIds.length})...`));
52
52
  try {
53
53
  const outputDir = resolveReportOutputDir(reportId);
54
- // Override github.username with report's username
55
- const reportConfig = {
56
- ...baseConfig,
57
- github: {
58
- ...baseConfig.github,
59
- username: report.github, // Use report's GitHub username, not manager's
60
- },
61
- };
54
+ // Build IC-compatible config from manager config + report
55
+ const reportConfig = buildReportConfig(managerConfig, report);
62
56
  // Determine cache behavior - prompt if data exists and --cache not specified
63
57
  let useCache = options.cache;
64
58
  if (!options.cache) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/fetch/jira/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAcH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA2HpC,eAAO,MAAM,WAAW,SA0BpB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/fetch/jira/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAcH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqHpC,eAAO,MAAM,WAAW,SA0BpB,CAAC"}
@@ -11,7 +11,7 @@ import { getActiveProfile } from '../../../../core/workspace/global-config.js';
11
11
  import { isManagerMode } from '../../../../core/workspace/resolver.js';
12
12
  import chalk from 'chalk';
13
13
  import { Command } from 'commander';
14
- import { getReportById, resolveReportIds, resolveReportOutputDir, } from '../fetch-manager.utils.js';
14
+ import { buildReportConfig, getReportById, loadManagerConfigForFetch, resolveReportIds, resolveReportOutputDir, } from '../fetch-manager.utils.js';
15
15
  import { fetchJiraTickets } from './jira.utils.js';
16
16
  /**
17
17
  * Fetch Jira tickets in IC mode
@@ -43,24 +43,16 @@ async function fetchJiraICMode(options) {
43
43
  async function fetchJiraManagerMode(options) {
44
44
  const reportIds = await resolveReportIds(options);
45
45
  console.log(chalk.blue(`\n📥 Fetching Jira tickets for ${reportIds.length} report(s)...\n`));
46
- // Load base config (will be overridden per-report)
47
- const baseConfig = await loadConfig(options.config);
46
+ // Load manager config
47
+ const managerConfig = loadManagerConfigForFetch();
48
48
  for (let i = 0; i < reportIds.length; i++) {
49
49
  const reportId = reportIds[i];
50
50
  const report = getReportById(reportId);
51
51
  console.log(chalk.blue(`\nFetching data for ${report.name} (${i + 1}/${reportIds.length})...`));
52
52
  try {
53
53
  const outputDir = resolveReportOutputDir(reportId);
54
- // Override jira.email with report's email (if Jira is configured)
55
- const reportConfig = {
56
- ...baseConfig,
57
- jira: baseConfig.jira
58
- ? {
59
- ...baseConfig.jira,
60
- email: report.email, // Use report's email, not manager's
61
- }
62
- : undefined,
63
- };
54
+ // Build IC-compatible config from manager config + report
55
+ const reportConfig = buildReportConfig(managerConfig, report);
64
56
  // Determine cache behavior - prompt if data exists and --cache not specified
65
57
  let useCache = options.cache;
66
58
  if (!options.cache) {
@@ -404,7 +404,9 @@ async function initManagerProfile(cliProfileName) {
404
404
  process.exit(1);
405
405
  }
406
406
  console.log(chalk.cyan('\nManager Mode Configuration\n'));
407
- // Step 2: GitHub configuration
407
+ // Step 2: Time range
408
+ const { since, until } = await promptTimeRange();
409
+ // Step 3: GitHub configuration
408
410
  const githubOrg = await input({
409
411
  message: 'GitHub organization:',
410
412
  validate: (value) => {
@@ -415,7 +417,7 @@ async function initManagerProfile(cliProfileName) {
415
417
  },
416
418
  });
417
419
  const githubToken = await promptGitHubTokenForManager();
418
- // Step 3: Optional JIRA configuration
420
+ // Step 4: Optional JIRA configuration
419
421
  const useJira = await confirm({
420
422
  message: 'Configure JIRA?',
421
423
  default: false,
@@ -462,16 +464,20 @@ async function initManagerProfile(cliProfileName) {
462
464
  tokens.jiraToken = jiraToken;
463
465
  tokens.jiraEmail = jiraEmail.trim();
464
466
  }
465
- // Step 4: Create manager config
467
+ // Step 5: Create manager config
466
468
  const config = {
467
469
  mode: 'manager',
468
470
  github: {
469
471
  org: githubOrg.trim(),
470
472
  },
471
473
  jira: jiraConfig,
474
+ fetch: {
475
+ since,
476
+ until,
477
+ },
472
478
  reports: [],
473
479
  };
474
- // Step 5: Create profile directories
480
+ // Step 6: Create profile directories
475
481
  ensureProfileDirs(profileName);
476
482
  // Save manager config as YAML
477
483
  const configPath = getProfileConfigPath(profileName);
@@ -485,7 +491,7 @@ async function initManagerProfile(cliProfileName) {
485
491
  // Set as active profile
486
492
  initializeWorkspaceWithProfile(profileName);
487
493
  console.log(chalk.green(`\nManager profile '${profileName}' created successfully!`));
488
- // Step 6: Add reports?
494
+ // Step 7: Add reports?
489
495
  const addReportsNow = await confirm({
490
496
  message: 'Add reports now?',
491
497
  default: true,
@@ -516,7 +522,7 @@ async function initManagerProfile(cliProfileName) {
516
522
  */
517
523
  async function promptGitHubTokenForManager() {
518
524
  console.log(chalk.dim('\nCreate a token at: https://github.com/settings/tokens'));
519
- console.log(chalk.dim('Required scopes: repo or public_repo\n'));
525
+ console.log(chalk.dim('Required scopes: repo or public_repo, read:org for orgs\n'));
520
526
  return await password({
521
527
  message: 'GitHub token:',
522
528
  validate: (value) => {
@@ -1 +1 @@
1
- {"version":3,"file":"init.prompts.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/init/init.prompts.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE3C;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAC;AAEtE;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC;AAE5D;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,WAAW,SAAY,GACtB,OAAO,CAAC,MAAM,CAAC,CAiBjB;AAED;;GAEG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAgB/D;AAED;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,SAAS,CAAC;CACtB,CAAC,CAkED;AAcD;;GAEG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC,CAU5D;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CA8B1D;AAED;;GAEG;AACH,wBAAsB,yBAAyB,CAC7C,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,mBAAmB,CAAC,CAyB9B;AAED;;GAEG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,eAAe,CAAC,CActE;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA4BtE;AAED;;GAEG;AACH,wBAAsB,4BAA4B,CAChD,KAAK,EAAE,MAAM,EAAE,GACd,OAAO,CAAC,KAAK,GAAG,IAAI,GAAG,MAAM,CAAC,CAiBhC;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAKxE;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAWzE;AAED;;GAEG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,MAAM,CAAC,CAU9D;AAED;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CAqBrD;AAED;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAavD;AAED;;GAEG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CA0B5D;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,UAAU,EAAE,GACpB,OAAO,CAAC,OAAO,CAAC,CAuBlB;AAED;;GAEG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC,CAUzD;AAED;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAUvD;AAED;;GAEG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC,CAKvD"}
1
+ {"version":3,"file":"init.prompts.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/init/init.prompts.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE3C;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAC;AAEtE;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC;AAE5D;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,WAAW,SAAY,GACtB,OAAO,CAAC,MAAM,CAAC,CAiBjB;AAED;;GAEG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAgB/D;AAED;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,SAAS,CAAC;CACtB,CAAC,CAkED;AAcD;;GAEG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC,CAU5D;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CA8B1D;AAED;;GAEG;AACH,wBAAsB,yBAAyB,CAC7C,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,mBAAmB,CAAC,CAyB9B;AAED;;GAEG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,eAAe,CAAC,CActE;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA4BtE;AAED;;GAEG;AACH,wBAAsB,4BAA4B,CAChD,KAAK,EAAE,MAAM,EAAE,GACd,OAAO,CAAC,KAAK,GAAG,IAAI,GAAG,MAAM,CAAC,CAiBhC;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAKxE;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAWzE;AAED;;GAEG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,MAAM,CAAC,CAU9D;AAED;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CAqBrD;AAED;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAavD;AAED;;GAEG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CA0B5D;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,UAAU,EAAE,GACpB,OAAO,CAAC,OAAO,CAAC,CA2BlB;AAED;;GAEG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC,CAUzD;AAED;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAUvD;AAED;;GAEG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC,CAKvD"}
@@ -172,7 +172,7 @@ export async function promptRepoDiscoveryMethod(org) {
172
172
  {
173
173
  name: 'Auto-discover',
174
174
  value: 'auto',
175
- description: 'Find repos where you have PRs (slow for large orgs, may miss old contributions)',
175
+ description: 'Find repos where you have PRs (requires read:org scope for orgs, slow for large orgs)',
176
176
  },
177
177
  {
178
178
  name: 'All repos (slowest)',
@@ -357,7 +357,7 @@ export async function promptTokensReady(sources) {
357
357
  console.log('Create your tokens at:');
358
358
  if (sources.includes('github')) {
359
359
  console.log(chalk.dim(' GitHub: https://github.com/settings/tokens'));
360
- console.log(chalk.dim(' (Required scopes: repo or public_repo)'));
360
+ console.log(chalk.dim(' (Required scopes: repo or public_repo, read:org for orgs)'));
361
361
  }
362
362
  if (sources.includes('jira')) {
363
363
  console.log(chalk.dim(' JIRA: https://id.atlassian.com/manage-profile/security/api-tokens'));
@@ -173,7 +173,16 @@ async function checkIfOrganization(graphqlWithAuth, login) {
173
173
  });
174
174
  return response.organization !== null;
175
175
  }
176
- catch {
176
+ catch (error) {
177
+ // Check if this is an INSUFFICIENT_SCOPES error for read:org
178
+ if (error && typeof error === 'object' && 'errors' in error) {
179
+ const errors = error.errors;
180
+ if (errors?.some((e) => e.type === 'INSUFFICIENT_SCOPES')) {
181
+ throw new Error(`GitHub token is missing the 'read:org' scope, which is required to query organizations.\n` +
182
+ `Please add this scope at: https://github.com/settings/tokens`);
183
+ }
184
+ }
185
+ // For other errors, assume it's a user (not an org)
177
186
  return false;
178
187
  }
179
188
  }
@@ -30,6 +30,19 @@ export declare const ReportConfigSchema: z.ZodObject<{
30
30
  jiraProjects?: string[] | undefined;
31
31
  }>;
32
32
  export type ReportConfig = z.infer<typeof ReportConfigSchema>;
33
+ /**
34
+ * Manager fetch configuration schema
35
+ */
36
+ export declare const ManagerFetchConfigSchema: z.ZodObject<{
37
+ since: z.ZodString;
38
+ until: z.ZodDefault<z.ZodNullable<z.ZodString>>;
39
+ }, "strip", z.ZodTypeAny, {
40
+ since: string;
41
+ until: string | null;
42
+ }, {
43
+ since: string;
44
+ until?: string | null | undefined;
45
+ }>;
33
46
  /**
34
47
  * Manager profile configuration schema
35
48
  */
@@ -58,6 +71,16 @@ export declare const ManagerConfigSchema: z.ZodObject<{
58
71
  host: string;
59
72
  token?: string | undefined;
60
73
  }>>;
74
+ fetch: z.ZodObject<{
75
+ since: z.ZodString;
76
+ until: z.ZodDefault<z.ZodNullable<z.ZodString>>;
77
+ }, "strip", z.ZodTypeAny, {
78
+ since: string;
79
+ until: string | null;
80
+ }, {
81
+ since: string;
82
+ until?: string | null | undefined;
83
+ }>;
61
84
  reports: z.ZodDefault<z.ZodArray<z.ZodObject<{
62
85
  /** Display name (e.g., "Alice Smith") */
63
86
  name: z.ZodString;
@@ -94,6 +117,10 @@ export declare const ManagerConfigSchema: z.ZodObject<{
94
117
  org: string;
95
118
  token?: string | undefined;
96
119
  };
120
+ fetch: {
121
+ since: string;
122
+ until: string | null;
123
+ };
97
124
  mode: "manager";
98
125
  jira?: {
99
126
  email: string;
@@ -105,6 +132,10 @@ export declare const ManagerConfigSchema: z.ZodObject<{
105
132
  org: string;
106
133
  token?: string | undefined;
107
134
  };
135
+ fetch: {
136
+ since: string;
137
+ until?: string | null | undefined;
138
+ };
108
139
  mode: "manager";
109
140
  reports?: {
110
141
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../src/core/types/manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;GAEG;AAEH;;GAEG;AACH,eAAO,MAAM,kBAAkB;IAC7B,yCAAyC;;IAEzC,sBAAsB;;IAEtB,wCAAwC;;IAExC,qCAAqC;;IAErC,6BAA6B;;;;;;;;;;;;;;EAE7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D;;GAEG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;QAhB9B,yCAAyC;;QAEzC,sBAAsB;;QAEtB,wCAAwC;;QAExC,qCAAqC;;QAErC,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsB7B,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,gCAAgC;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,sBAAsB;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,iCAAiC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,gBAAgB,EAAE,MAAM,CAAC;IACzB,sCAAsC;IACtC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB"}
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../src/core/types/manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;GAEG;AAEH;;GAEG;AACH,eAAO,MAAM,kBAAkB;IAC7B,yCAAyC;;IAEzC,sBAAsB;;IAEtB,wCAAwC;;IAExC,qCAAqC;;IAErC,6BAA6B;;;;;;;;;;;;;;EAE7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D;;GAEG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;EAGnC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAxB9B,yCAAyC;;QAEzC,sBAAsB;;QAEtB,wCAAwC;;QAExC,qCAAqC;;QAErC,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+B7B,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,gCAAgC;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,sBAAsB;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,iCAAiC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,gBAAgB,EAAE,MAAM,CAAC;IACzB,sCAAsC;IACtC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB"}
@@ -17,6 +17,13 @@ export const ReportConfigSchema = z.object({
17
17
  /** Jira projects to fetch */
18
18
  jiraProjects: z.array(z.string()).default([]),
19
19
  });
20
+ /**
21
+ * Manager fetch configuration schema
22
+ */
23
+ export const ManagerFetchConfigSchema = z.object({
24
+ since: z.string(),
25
+ until: z.string().nullable().default(null),
26
+ });
20
27
  /**
21
28
  * Manager profile configuration schema
22
29
  */
@@ -33,5 +40,6 @@ export const ManagerConfigSchema = z.object({
33
40
  token: z.string().optional(), // Token stored in .env, not config
34
41
  })
35
42
  .optional(),
43
+ fetch: ManagerFetchConfigSchema,
36
44
  reports: z.array(ReportConfigSchema).default([]),
37
45
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "work-chronicler",
3
- "version": "0.2.2",
3
+ "version": "0.3.1",
4
4
  "description": "Gather, analyze, and summarize your work history from GitHub PRs and JIRA tickets for performance reviews and resumes",
5
5
  "type": "module",
6
6
  "main": "dist/cli/index.js",