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.
- package/.agent/skills/work-chronicler-detect-projects/SKILL.md +11 -0
- package/.agent/skills/work-chronicler-detect-themes/SKILL.md +11 -0
- package/.agent/skills/work-chronicler-generate-resume-bullets/SKILL.md +8 -1
- package/.agent/skills/work-chronicler-mgmt-write-peer-review/skill.md +469 -0
- package/.agent/skills/work-chronicler-summarize-work/SKILL.md +11 -0
- package/.agent/skills/work-chronicler-update-resume/SKILL.md +8 -1
- package/.agent/skills/work-chronicler-write-self-review/SKILL.md +8 -1
- package/README.md +15 -2
- package/dist/cli/commands/fetch/all.d.ts.map +1 -1
- package/dist/cli/commands/fetch/all.js +5 -17
- package/dist/cli/commands/fetch/fetch-manager.utils.d.ts +20 -1
- package/dist/cli/commands/fetch/fetch-manager.utils.d.ts.map +1 -1
- package/dist/cli/commands/fetch/fetch-manager.utils.js +65 -0
- package/dist/cli/commands/fetch/github/index.d.ts.map +1 -1
- package/dist/cli/commands/fetch/github/index.js +5 -11
- package/dist/cli/commands/fetch/jira/index.d.ts.map +1 -1
- package/dist/cli/commands/fetch/jira/index.js +5 -13
- package/dist/cli/commands/init/index.js +12 -6
- package/dist/cli/commands/init/init.prompts.d.ts.map +1 -1
- package/dist/cli/commands/init/init.prompts.js +2 -2
- package/dist/cli/commands/init/init.utils.js +10 -1
- package/dist/core/types/manager.d.ts +31 -0
- package/dist/core/types/manager.d.ts.map +1 -1
- package/dist/core/types/manager.js +8 -0
- package/package.json +1 -1
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
|
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;
|
|
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
|
|
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
|
-
//
|
|
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 {
|
|
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;
|
|
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;
|
|
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
|
|
47
|
-
const
|
|
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
|
-
//
|
|
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;
|
|
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
|
|
47
|
-
const
|
|
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
|
-
//
|
|
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:
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
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 (
|
|
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
|
|
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