@olegkoval/agent-skills 1.8.0 → 1.9.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.
Files changed (72) hide show
  1. package/.claude-plugin/plugin.json +4 -2
  2. package/.cursor-plugin/index.json +10 -0
  3. package/.kiro/steering/obsidian-pr-sync.md +137 -0
  4. package/.kiro/steering/obsidian-task-rollover.md +180 -0
  5. package/.windsurf/rules/obsidian-pr-sync.md +136 -0
  6. package/.windsurf/rules/obsidian-task-rollover.md +179 -0
  7. package/README.md +4 -2
  8. package/catalog/skills.json +44 -0
  9. package/package.json +1 -1
  10. package/packages/marketing/search-console-indexing-audit/SKILL.md +1 -0
  11. package/packages/marketing/search-console-indexing-audit/adapters/claude/skills/search-console-indexing-audit/SKILL.md +1 -0
  12. package/packages/marketing/search-console-indexing-audit/adapters/cursor/skills/search-console-indexing-audit/SKILL.md +1 -0
  13. package/packages/marketing/viral-launch/SKILL.md +1 -0
  14. package/packages/marketing/viral-launch/adapters/claude/skills/viral-launch/SKILL.md +1 -0
  15. package/packages/marketing/viral-launch/adapters/cursor/skills/viral-launch/SKILL.md +1 -0
  16. package/packages/music/fill-music-player/SKILL.md +1 -0
  17. package/packages/music/fill-music-player/adapters/claude/skills/fill-music-player/SKILL.md +1 -0
  18. package/packages/music/fill-music-player/adapters/cursor/skills/fill-music-player/SKILL.md +1 -0
  19. package/packages/photography/gallery/SKILL.md +1 -0
  20. package/packages/photography/gallery/adapters/claude/skills/gallery/SKILL.md +1 -0
  21. package/packages/photography/gallery/adapters/cursor/skills/gallery/SKILL.md +1 -0
  22. package/packages/software-development/add-to-my-skills/SKILL.md +1 -0
  23. package/packages/software-development/add-to-my-skills/adapters/claude/skills/add-to-my-skills/SKILL.md +1 -0
  24. package/packages/software-development/add-to-my-skills/adapters/cursor/skills/add-to-my-skills/SKILL.md +1 -0
  25. package/packages/software-development/ai-tools-setup/SKILL.md +1 -0
  26. package/packages/software-development/ai-tools-setup/adapters/claude/skills/ai-tools-setup/SKILL.md +1 -0
  27. package/packages/software-development/ai-tools-setup/adapters/cursor/skills/ai-tools-setup/SKILL.md +1 -0
  28. package/packages/software-development/changelog-generator/SKILL.md +1 -0
  29. package/packages/software-development/changelog-generator/adapters/claude/skills/changelog-generator/SKILL.md +1 -0
  30. package/packages/software-development/changelog-generator/adapters/cursor/skills/changelog-generator/SKILL.md +1 -0
  31. package/packages/software-development/cloudflare-block-countries/SKILL.md +1 -0
  32. package/packages/software-development/cloudflare-block-countries/adapters/claude/skills/cloudflare-block-countries/SKILL.md +1 -0
  33. package/packages/software-development/cloudflare-block-countries/adapters/cursor/skills/cloudflare-block-countries/SKILL.md +1 -0
  34. package/packages/software-development/docs-index-keeper/SKILL.md +1 -0
  35. package/packages/software-development/docs-index-keeper/adapters/claude/skills/docs-index-keeper/SKILL.md +1 -0
  36. package/packages/software-development/docs-index-keeper/adapters/cursor/skills/docs-index-keeper/SKILL.md +1 -0
  37. package/packages/software-development/gh-cli/SKILL.md +1 -0
  38. package/packages/software-development/gh-cli/adapters/claude/skills/gh-cli/SKILL.md +1 -0
  39. package/packages/software-development/gh-cli/adapters/cursor/skills/gh-cli/SKILL.md +1 -0
  40. package/packages/software-development/git-commit/SKILL.md +1 -0
  41. package/packages/software-development/git-commit/adapters/claude/skills/git-commit/SKILL.md +1 -0
  42. package/packages/software-development/git-commit/adapters/cursor/skills/git-commit/SKILL.md +1 -0
  43. package/packages/software-development/obsidian-pr-sync/SKILL.md +152 -0
  44. package/packages/software-development/obsidian-pr-sync/adapters/claude/plugin.json +5 -0
  45. package/packages/software-development/obsidian-pr-sync/adapters/claude/skills/obsidian-pr-sync/SKILL.md +155 -0
  46. package/packages/software-development/obsidian-pr-sync/adapters/cursor/plugin.json +6 -0
  47. package/packages/software-development/obsidian-pr-sync/adapters/cursor/skills/obsidian-pr-sync/SKILL.md +155 -0
  48. package/packages/software-development/obsidian-pr-sync/adapters/kiro/steering/obsidian-pr-sync.md +137 -0
  49. package/packages/software-development/obsidian-pr-sync/adapters/windsurf/rules/obsidian-pr-sync.md +136 -0
  50. package/packages/software-development/obsidian-task-rollover/SKILL.md +196 -0
  51. package/packages/software-development/obsidian-task-rollover/adapters/claude/plugin.json +5 -0
  52. package/packages/software-development/obsidian-task-rollover/adapters/claude/skills/obsidian-task-rollover/SKILL.md +199 -0
  53. package/packages/software-development/obsidian-task-rollover/adapters/cursor/plugin.json +6 -0
  54. package/packages/software-development/obsidian-task-rollover/adapters/cursor/skills/obsidian-task-rollover/SKILL.md +199 -0
  55. package/packages/software-development/obsidian-task-rollover/adapters/kiro/steering/obsidian-task-rollover.md +180 -0
  56. package/packages/software-development/obsidian-task-rollover/adapters/windsurf/rules/obsidian-task-rollover.md +179 -0
  57. package/packages/software-development/open-source-publisher/SKILL.md +1 -0
  58. package/packages/software-development/open-source-publisher/adapters/claude/skills/open-source-publisher/SKILL.md +1 -0
  59. package/packages/software-development/open-source-publisher/adapters/cursor/skills/open-source-publisher/SKILL.md +1 -0
  60. package/packages/software-development/product-builder/SKILL.md +1 -0
  61. package/packages/software-development/product-builder/adapters/claude/skills/product-builder/SKILL.md +1 -0
  62. package/packages/software-development/product-builder/adapters/cursor/skills/product-builder/SKILL.md +1 -0
  63. package/packages/software-development/promptctl/SKILL.md +1 -0
  64. package/packages/software-development/promptctl/adapters/claude/skills/promptctl/SKILL.md +1 -0
  65. package/packages/software-development/promptctl/adapters/cursor/skills/promptctl/SKILL.md +1 -0
  66. package/packages/software-development/semantic-release-beta/SKILL.md +1 -0
  67. package/packages/software-development/semantic-release-beta/adapters/claude/skills/semantic-release-beta/SKILL.md +1 -0
  68. package/packages/software-development/semantic-release-beta/adapters/cursor/skills/semantic-release-beta/SKILL.md +1 -0
  69. package/packages/software-development/starter-rules/SKILL.md +1 -0
  70. package/packages/software-development/starter-rules/adapters/claude/skills/starter-rules/SKILL.md +1 -0
  71. package/packages/software-development/starter-rules/adapters/cursor/skills/starter-rules/SKILL.md +1 -0
  72. package/scripts/build-adapters.sh +11 -2
@@ -0,0 +1,155 @@
1
+ <!-- Generated by scripts/build-adapters.sh. Do not edit directly. -->
2
+
3
+ ---
4
+ name: obsidian-pr-sync
5
+ description: >
6
+ Fetch open GitHub PRs where the user is an assignee or review-requested reviewer,
7
+ then write or refresh a "## PRs to review" section in today's Obsidian daily note.
8
+ Use this skill whenever the user asks to sync PRs to Obsidian, update their daily note
9
+ with GitHub reviews, check what PRs need attention, or run a morning PR sync routine.
10
+ Also suitable for scheduled/automated runs — fully idempotent (re-running replaces
11
+ the section, never appends).
12
+ license: MIT
13
+ allowed-tools: Bash, Read, Write, Edit
14
+ compatibility: Codex, Claude Code, Cursor, GitHub Copilot, Windsurf, Kiro, and other Agent Skills compatible tools. Requires the GitHub CLI (`gh`) authenticated and a daily note vault.
15
+ metadata:
16
+ targets: ["claude"]
17
+ author: Oleg Koval
18
+ tags:
19
+ - github
20
+ - obsidian
21
+ - daily-note
22
+ - pull-requests
23
+ - productivity
24
+ - morning-routine
25
+ ---
26
+
27
+ # Obsidian PR Sync
28
+
29
+ Fetch all open PRs where the user is assigned or requested as reviewer, filter out
30
+ noise (bots, drafts, self-authored), and write a clean grouped section into today's
31
+ daily note.
32
+
33
+ ## Configuration
34
+
35
+ Before running, confirm:
36
+ - `VAULT_DAILY` — absolute path to the daily notes folder (e.g. `/Users/you/obsidian/vault/Lead/Daily`)
37
+ - `GH_USERNAME` — GitHub login to exclude self-authored PRs (e.g. `oleg-koval`)
38
+ - `ORG_PREFIX` — org name to group as "Work" (e.g. `Teifi-Digital`); everything else goes to "Personal"
39
+
40
+ If not specified by the user, infer from context (git config, existing vault files).
41
+
42
+ ## Step 1 — Fetch PRs
43
+
44
+ Run two `gh` queries and merge results, deduplicating by URL:
45
+
46
+ ```bash
47
+ # Review-requested
48
+ gh search prs --review-requested=@me --state=open \
49
+ --json title,url,repository,author,createdAt,isDraft --limit 50
50
+
51
+ # Assigned
52
+ gh search prs --assignee=@me --state=open \
53
+ --json title,url,repository,author,createdAt,isDraft --limit 50
54
+ ```
55
+
56
+ Merge both lists, deduplicate by `url`. The union is what needs attention.
57
+
58
+ ## Step 2 — Filter
59
+
60
+ Discard entries where:
61
+ - `isDraft` is `true`
62
+ - `author.login` matches any bot pattern: `dependabot`, `copilot`, `renovate`, `github-actions`, or `author.is_bot` is `true`
63
+ - `author.login` equals `GH_USERNAME` — self-authored PRs are not reviews; they're your own work
64
+
65
+ ## Step 3 — Enrich authors
66
+
67
+ For each unique author login, resolve a display name for the Obsidian wiki-link:
68
+
69
+ ```bash
70
+ gh api /users/<login> --jq '.name // .login'
71
+ ```
72
+
73
+ If the API returns a name, use it (e.g. `Rutger Klaassen`). If it returns null, fall
74
+ back to the login with first letter uppercased. This gives `[[Rutger Klaassen]]` or
75
+ `[[Merlijnmacgillavry]]`.
76
+
77
+ Batch these lookups — run them in parallel if possible to keep the sync fast.
78
+
79
+ ## Step 4 — Calculate age
80
+
81
+ For each PR: `days_old = (today - createdAt).days`. Use today's date in local time.
82
+
83
+ ## Step 5 — Build the section
84
+
85
+ Format the section exactly as:
86
+
87
+ ```markdown
88
+ ## PRs to review
89
+
90
+ ### Work (<ORG_PREFIX>)
91
+ - [ ] [TITLE](url) by [[Author Name]] (N days old)
92
+
93
+ ### Personal
94
+ - [ ] [TITLE](url) by [[Author Name]] (N days old)
95
+ ```
96
+
97
+ Rules:
98
+ - **Work**: `repository.nameWithOwner` starts with `<ORG_PREFIX>/`
99
+ - **Personal**: everything else
100
+ - Within each group, sort by `createdAt` ascending (oldest first — most overdue at top)
101
+ - If a group has no PRs, omit that subsection entirely (don't render an empty `### Work` header)
102
+ - If there are zero PRs total, write: `## PRs to review\n\n_No open PRs — clear queue! 🎉_`
103
+ - Add `⚠️` after the age if `days_old >= 7`
104
+
105
+ **Example line:**
106
+ ```
107
+ - [ ] [RSL-108] Image sync from InRiver by [[Merlijn Mac Gillavry]] (12 days old ⚠️)
108
+ ```
109
+
110
+ ## Step 6 — Write to today's daily note
111
+
112
+ **Find today's note:**
113
+ ```bash
114
+ TODAY=$(date +%Y-%m-%d)
115
+ NOTE="${VAULT_DAILY}/${TODAY}.md"
116
+ ```
117
+
118
+ If the file doesn't exist, create it with standard daily template frontmatter first,
119
+ then append the section. If the file exists:
120
+
121
+ **Replacement logic (idempotent):**
122
+ - If `## PRs to review` already exists: replace everything from that line up to (but not
123
+ including) the next `## ` heading or end-of-file with the newly built section.
124
+ - If it doesn't exist: append the section at the end of the file (before the nav footer
125
+ line `*← [[...` if present, otherwise at the very end).
126
+
127
+ This ensures re-running the skill produces the same result, not a growing list.
128
+
129
+ ## Invocation patterns
130
+
131
+ **Manual (user-triggered):**
132
+ The user says something like "sync my PRs to today's note" or "update obsidian with my reviews".
133
+ Run the full flow and confirm how many PRs were written.
134
+
135
+ **Scheduled morning routine:**
136
+ Same flow. No user prompt needed — just run, update the note, and report a one-line
137
+ summary: `"PR sync: 3 work PRs, 2 personal PRs written to 2026-05-11.md"`.
138
+
139
+ **In a remote CCR agent:**
140
+ Clone the vault repo, run the sync, commit and push. The local Obsidian Git plugin
141
+ pulls the changes automatically.
142
+
143
+ ## Output to user
144
+
145
+ After writing the file, show a brief confirmation:
146
+
147
+ ```
148
+ Synced N PRs to Lead/Daily/YYYY-MM-DD.md
149
+ Work (<ORG_PREFIX>): X PRs
150
+ Personal: Y PRs
151
+ Skipped: Z bots/drafts
152
+ ```
153
+
154
+ If any `gh` call fails (e.g. auth expired), surface the error clearly rather than
155
+ writing a partial/corrupt section.
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "olko:obsidian-pr-sync",
3
+ "version": "0.1.0",
4
+ "description": "Fetch open GitHub PRs assigned to you or requesting your review, and write a grouped, age-sorted '## PRs to review' section into today's Obsidian daily note. Idempotent — re-running replaces the section.",
5
+ "skills": "skills/"
6
+ }
@@ -0,0 +1,155 @@
1
+ <!-- Generated by scripts/build-adapters.sh. Do not edit directly. -->
2
+
3
+ ---
4
+ name: obsidian-pr-sync
5
+ description: >
6
+ Fetch open GitHub PRs where the user is an assignee or review-requested reviewer,
7
+ then write or refresh a "## PRs to review" section in today's Obsidian daily note.
8
+ Use this skill whenever the user asks to sync PRs to Obsidian, update their daily note
9
+ with GitHub reviews, check what PRs need attention, or run a morning PR sync routine.
10
+ Also suitable for scheduled/automated runs — fully idempotent (re-running replaces
11
+ the section, never appends).
12
+ license: MIT
13
+ allowed-tools: Bash, Read, Write, Edit
14
+ compatibility: Codex, Claude Code, Cursor, GitHub Copilot, Windsurf, Kiro, and other Agent Skills compatible tools. Requires the GitHub CLI (`gh`) authenticated and a daily note vault.
15
+ metadata:
16
+ targets: ["cursor"]
17
+ author: Oleg Koval
18
+ tags:
19
+ - github
20
+ - obsidian
21
+ - daily-note
22
+ - pull-requests
23
+ - productivity
24
+ - morning-routine
25
+ ---
26
+
27
+ # Obsidian PR Sync
28
+
29
+ Fetch all open PRs where the user is assigned or requested as reviewer, filter out
30
+ noise (bots, drafts, self-authored), and write a clean grouped section into today's
31
+ daily note.
32
+
33
+ ## Configuration
34
+
35
+ Before running, confirm:
36
+ - `VAULT_DAILY` — absolute path to the daily notes folder (e.g. `/Users/you/obsidian/vault/Lead/Daily`)
37
+ - `GH_USERNAME` — GitHub login to exclude self-authored PRs (e.g. `oleg-koval`)
38
+ - `ORG_PREFIX` — org name to group as "Work" (e.g. `Teifi-Digital`); everything else goes to "Personal"
39
+
40
+ If not specified by the user, infer from context (git config, existing vault files).
41
+
42
+ ## Step 1 — Fetch PRs
43
+
44
+ Run two `gh` queries and merge results, deduplicating by URL:
45
+
46
+ ```bash
47
+ # Review-requested
48
+ gh search prs --review-requested=@me --state=open \
49
+ --json title,url,repository,author,createdAt,isDraft --limit 50
50
+
51
+ # Assigned
52
+ gh search prs --assignee=@me --state=open \
53
+ --json title,url,repository,author,createdAt,isDraft --limit 50
54
+ ```
55
+
56
+ Merge both lists, deduplicate by `url`. The union is what needs attention.
57
+
58
+ ## Step 2 — Filter
59
+
60
+ Discard entries where:
61
+ - `isDraft` is `true`
62
+ - `author.login` matches any bot pattern: `dependabot`, `copilot`, `renovate`, `github-actions`, or `author.is_bot` is `true`
63
+ - `author.login` equals `GH_USERNAME` — self-authored PRs are not reviews; they're your own work
64
+
65
+ ## Step 3 — Enrich authors
66
+
67
+ For each unique author login, resolve a display name for the Obsidian wiki-link:
68
+
69
+ ```bash
70
+ gh api /users/<login> --jq '.name // .login'
71
+ ```
72
+
73
+ If the API returns a name, use it (e.g. `Rutger Klaassen`). If it returns null, fall
74
+ back to the login with first letter uppercased. This gives `[[Rutger Klaassen]]` or
75
+ `[[Merlijnmacgillavry]]`.
76
+
77
+ Batch these lookups — run them in parallel if possible to keep the sync fast.
78
+
79
+ ## Step 4 — Calculate age
80
+
81
+ For each PR: `days_old = (today - createdAt).days`. Use today's date in local time.
82
+
83
+ ## Step 5 — Build the section
84
+
85
+ Format the section exactly as:
86
+
87
+ ```markdown
88
+ ## PRs to review
89
+
90
+ ### Work (<ORG_PREFIX>)
91
+ - [ ] [TITLE](url) by [[Author Name]] (N days old)
92
+
93
+ ### Personal
94
+ - [ ] [TITLE](url) by [[Author Name]] (N days old)
95
+ ```
96
+
97
+ Rules:
98
+ - **Work**: `repository.nameWithOwner` starts with `<ORG_PREFIX>/`
99
+ - **Personal**: everything else
100
+ - Within each group, sort by `createdAt` ascending (oldest first — most overdue at top)
101
+ - If a group has no PRs, omit that subsection entirely (don't render an empty `### Work` header)
102
+ - If there are zero PRs total, write: `## PRs to review\n\n_No open PRs — clear queue! 🎉_`
103
+ - Add `⚠️` after the age if `days_old >= 7`
104
+
105
+ **Example line:**
106
+ ```
107
+ - [ ] [RSL-108] Image sync from InRiver by [[Merlijn Mac Gillavry]] (12 days old ⚠️)
108
+ ```
109
+
110
+ ## Step 6 — Write to today's daily note
111
+
112
+ **Find today's note:**
113
+ ```bash
114
+ TODAY=$(date +%Y-%m-%d)
115
+ NOTE="${VAULT_DAILY}/${TODAY}.md"
116
+ ```
117
+
118
+ If the file doesn't exist, create it with standard daily template frontmatter first,
119
+ then append the section. If the file exists:
120
+
121
+ **Replacement logic (idempotent):**
122
+ - If `## PRs to review` already exists: replace everything from that line up to (but not
123
+ including) the next `## ` heading or end-of-file with the newly built section.
124
+ - If it doesn't exist: append the section at the end of the file (before the nav footer
125
+ line `*← [[...` if present, otherwise at the very end).
126
+
127
+ This ensures re-running the skill produces the same result, not a growing list.
128
+
129
+ ## Invocation patterns
130
+
131
+ **Manual (user-triggered):**
132
+ The user says something like "sync my PRs to today's note" or "update obsidian with my reviews".
133
+ Run the full flow and confirm how many PRs were written.
134
+
135
+ **Scheduled morning routine:**
136
+ Same flow. No user prompt needed — just run, update the note, and report a one-line
137
+ summary: `"PR sync: 3 work PRs, 2 personal PRs written to 2026-05-11.md"`.
138
+
139
+ **In a remote CCR agent:**
140
+ Clone the vault repo, run the sync, commit and push. The local Obsidian Git plugin
141
+ pulls the changes automatically.
142
+
143
+ ## Output to user
144
+
145
+ After writing the file, show a brief confirmation:
146
+
147
+ ```
148
+ Synced N PRs to Lead/Daily/YYYY-MM-DD.md
149
+ Work (<ORG_PREFIX>): X PRs
150
+ Personal: Y PRs
151
+ Skipped: Z bots/drafts
152
+ ```
153
+
154
+ If any `gh` call fails (e.g. auth expired), surface the error clearly rather than
155
+ writing a partial/corrupt section.
@@ -0,0 +1,137 @@
1
+ <!-- Generated by scripts/build-adapters.sh. Do not edit directly. -->
2
+
3
+ ---
4
+ inclusion: manual
5
+ description: "Fetch open GitHub PRs assigned to you or requesting your review, and write a grouped, age-sorted '## PRs to review' section into today's Obsidian daily note. Idempotent — re-running replaces the section."
6
+ ---
7
+
8
+
9
+ # Obsidian PR Sync
10
+
11
+ Fetch all open PRs where the user is assigned or requested as reviewer, filter out
12
+ noise (bots, drafts, self-authored), and write a clean grouped section into today's
13
+ daily note.
14
+
15
+ ## Configuration
16
+
17
+ Before running, confirm:
18
+ - `VAULT_DAILY` — absolute path to the daily notes folder (e.g. `/Users/you/obsidian/vault/Lead/Daily`)
19
+ - `GH_USERNAME` — GitHub login to exclude self-authored PRs (e.g. `oleg-koval`)
20
+ - `ORG_PREFIX` — org name to group as "Work" (e.g. `Teifi-Digital`); everything else goes to "Personal"
21
+
22
+ If not specified by the user, infer from context (git config, existing vault files).
23
+
24
+ ## Step 1 — Fetch PRs
25
+
26
+ Run two `gh` queries and merge results, deduplicating by URL:
27
+
28
+ ```bash
29
+ # Review-requested
30
+ gh search prs --review-requested=@me --state=open \
31
+ --json title,url,repository,author,createdAt,isDraft --limit 50
32
+
33
+ # Assigned
34
+ gh search prs --assignee=@me --state=open \
35
+ --json title,url,repository,author,createdAt,isDraft --limit 50
36
+ ```
37
+
38
+ Merge both lists, deduplicate by `url`. The union is what needs attention.
39
+
40
+ ## Step 2 — Filter
41
+
42
+ Discard entries where:
43
+ - `isDraft` is `true`
44
+ - `author.login` matches any bot pattern: `dependabot`, `copilot`, `renovate`, `github-actions`, or `author.is_bot` is `true`
45
+ - `author.login` equals `GH_USERNAME` — self-authored PRs are not reviews; they're your own work
46
+
47
+ ## Step 3 — Enrich authors
48
+
49
+ For each unique author login, resolve a display name for the Obsidian wiki-link:
50
+
51
+ ```bash
52
+ gh api /users/<login> --jq '.name // .login'
53
+ ```
54
+
55
+ If the API returns a name, use it (e.g. `Rutger Klaassen`). If it returns null, fall
56
+ back to the login with first letter uppercased. This gives `[[Rutger Klaassen]]` or
57
+ `[[Merlijnmacgillavry]]`.
58
+
59
+ Batch these lookups — run them in parallel if possible to keep the sync fast.
60
+
61
+ ## Step 4 — Calculate age
62
+
63
+ For each PR: `days_old = (today - createdAt).days`. Use today's date in local time.
64
+
65
+ ## Step 5 — Build the section
66
+
67
+ Format the section exactly as:
68
+
69
+ ```markdown
70
+ ## PRs to review
71
+
72
+ ### Work (<ORG_PREFIX>)
73
+ - [ ] [TITLE](url) by [[Author Name]] (N days old)
74
+
75
+ ### Personal
76
+ - [ ] [TITLE](url) by [[Author Name]] (N days old)
77
+ ```
78
+
79
+ Rules:
80
+ - **Work**: `repository.nameWithOwner` starts with `<ORG_PREFIX>/`
81
+ - **Personal**: everything else
82
+ - Within each group, sort by `createdAt` ascending (oldest first — most overdue at top)
83
+ - If a group has no PRs, omit that subsection entirely (don't render an empty `### Work` header)
84
+ - If there are zero PRs total, write: `## PRs to review\n\n_No open PRs — clear queue! 🎉_`
85
+ - Add `⚠️` after the age if `days_old >= 7`
86
+
87
+ **Example line:**
88
+ ```
89
+ - [ ] [RSL-108] Image sync from InRiver by [[Merlijn Mac Gillavry]] (12 days old ⚠️)
90
+ ```
91
+
92
+ ## Step 6 — Write to today's daily note
93
+
94
+ **Find today's note:**
95
+ ```bash
96
+ TODAY=$(date +%Y-%m-%d)
97
+ NOTE="${VAULT_DAILY}/${TODAY}.md"
98
+ ```
99
+
100
+ If the file doesn't exist, create it with standard daily template frontmatter first,
101
+ then append the section. If the file exists:
102
+
103
+ **Replacement logic (idempotent):**
104
+ - If `## PRs to review` already exists: replace everything from that line up to (but not
105
+ including) the next `## ` heading or end-of-file with the newly built section.
106
+ - If it doesn't exist: append the section at the end of the file (before the nav footer
107
+ line `*← [[...` if present, otherwise at the very end).
108
+
109
+ This ensures re-running the skill produces the same result, not a growing list.
110
+
111
+ ## Invocation patterns
112
+
113
+ **Manual (user-triggered):**
114
+ The user says something like "sync my PRs to today's note" or "update obsidian with my reviews".
115
+ Run the full flow and confirm how many PRs were written.
116
+
117
+ **Scheduled morning routine:**
118
+ Same flow. No user prompt needed — just run, update the note, and report a one-line
119
+ summary: `"PR sync: 3 work PRs, 2 personal PRs written to 2026-05-11.md"`.
120
+
121
+ **In a remote CCR agent:**
122
+ Clone the vault repo, run the sync, commit and push. The local Obsidian Git plugin
123
+ pulls the changes automatically.
124
+
125
+ ## Output to user
126
+
127
+ After writing the file, show a brief confirmation:
128
+
129
+ ```
130
+ Synced N PRs to Lead/Daily/YYYY-MM-DD.md
131
+ Work (<ORG_PREFIX>): X PRs
132
+ Personal: Y PRs
133
+ Skipped: Z bots/drafts
134
+ ```
135
+
136
+ If any `gh` call fails (e.g. auth expired), surface the error clearly rather than
137
+ writing a partial/corrupt section.
@@ -0,0 +1,136 @@
1
+ <!-- Generated by scripts/build-adapters.sh. Do not edit directly. -->
2
+
3
+ ---
4
+ description: "Fetch open GitHub PRs assigned to you or requesting your review, and write a grouped, age-sorted '## PRs to review' section into today's Obsidian daily note. Idempotent — re-running replaces the section."
5
+ ---
6
+
7
+
8
+ # Obsidian PR Sync
9
+
10
+ Fetch all open PRs where the user is assigned or requested as reviewer, filter out
11
+ noise (bots, drafts, self-authored), and write a clean grouped section into today's
12
+ daily note.
13
+
14
+ ## Configuration
15
+
16
+ Before running, confirm:
17
+ - `VAULT_DAILY` — absolute path to the daily notes folder (e.g. `/Users/you/obsidian/vault/Lead/Daily`)
18
+ - `GH_USERNAME` — GitHub login to exclude self-authored PRs (e.g. `oleg-koval`)
19
+ - `ORG_PREFIX` — org name to group as "Work" (e.g. `Teifi-Digital`); everything else goes to "Personal"
20
+
21
+ If not specified by the user, infer from context (git config, existing vault files).
22
+
23
+ ## Step 1 — Fetch PRs
24
+
25
+ Run two `gh` queries and merge results, deduplicating by URL:
26
+
27
+ ```bash
28
+ # Review-requested
29
+ gh search prs --review-requested=@me --state=open \
30
+ --json title,url,repository,author,createdAt,isDraft --limit 50
31
+
32
+ # Assigned
33
+ gh search prs --assignee=@me --state=open \
34
+ --json title,url,repository,author,createdAt,isDraft --limit 50
35
+ ```
36
+
37
+ Merge both lists, deduplicate by `url`. The union is what needs attention.
38
+
39
+ ## Step 2 — Filter
40
+
41
+ Discard entries where:
42
+ - `isDraft` is `true`
43
+ - `author.login` matches any bot pattern: `dependabot`, `copilot`, `renovate`, `github-actions`, or `author.is_bot` is `true`
44
+ - `author.login` equals `GH_USERNAME` — self-authored PRs are not reviews; they're your own work
45
+
46
+ ## Step 3 — Enrich authors
47
+
48
+ For each unique author login, resolve a display name for the Obsidian wiki-link:
49
+
50
+ ```bash
51
+ gh api /users/<login> --jq '.name // .login'
52
+ ```
53
+
54
+ If the API returns a name, use it (e.g. `Rutger Klaassen`). If it returns null, fall
55
+ back to the login with first letter uppercased. This gives `[[Rutger Klaassen]]` or
56
+ `[[Merlijnmacgillavry]]`.
57
+
58
+ Batch these lookups — run them in parallel if possible to keep the sync fast.
59
+
60
+ ## Step 4 — Calculate age
61
+
62
+ For each PR: `days_old = (today - createdAt).days`. Use today's date in local time.
63
+
64
+ ## Step 5 — Build the section
65
+
66
+ Format the section exactly as:
67
+
68
+ ```markdown
69
+ ## PRs to review
70
+
71
+ ### Work (<ORG_PREFIX>)
72
+ - [ ] [TITLE](url) by [[Author Name]] (N days old)
73
+
74
+ ### Personal
75
+ - [ ] [TITLE](url) by [[Author Name]] (N days old)
76
+ ```
77
+
78
+ Rules:
79
+ - **Work**: `repository.nameWithOwner` starts with `<ORG_PREFIX>/`
80
+ - **Personal**: everything else
81
+ - Within each group, sort by `createdAt` ascending (oldest first — most overdue at top)
82
+ - If a group has no PRs, omit that subsection entirely (don't render an empty `### Work` header)
83
+ - If there are zero PRs total, write: `## PRs to review\n\n_No open PRs — clear queue! 🎉_`
84
+ - Add `⚠️` after the age if `days_old >= 7`
85
+
86
+ **Example line:**
87
+ ```
88
+ - [ ] [RSL-108] Image sync from InRiver by [[Merlijn Mac Gillavry]] (12 days old ⚠️)
89
+ ```
90
+
91
+ ## Step 6 — Write to today's daily note
92
+
93
+ **Find today's note:**
94
+ ```bash
95
+ TODAY=$(date +%Y-%m-%d)
96
+ NOTE="${VAULT_DAILY}/${TODAY}.md"
97
+ ```
98
+
99
+ If the file doesn't exist, create it with standard daily template frontmatter first,
100
+ then append the section. If the file exists:
101
+
102
+ **Replacement logic (idempotent):**
103
+ - If `## PRs to review` already exists: replace everything from that line up to (but not
104
+ including) the next `## ` heading or end-of-file with the newly built section.
105
+ - If it doesn't exist: append the section at the end of the file (before the nav footer
106
+ line `*← [[...` if present, otherwise at the very end).
107
+
108
+ This ensures re-running the skill produces the same result, not a growing list.
109
+
110
+ ## Invocation patterns
111
+
112
+ **Manual (user-triggered):**
113
+ The user says something like "sync my PRs to today's note" or "update obsidian with my reviews".
114
+ Run the full flow and confirm how many PRs were written.
115
+
116
+ **Scheduled morning routine:**
117
+ Same flow. No user prompt needed — just run, update the note, and report a one-line
118
+ summary: `"PR sync: 3 work PRs, 2 personal PRs written to 2026-05-11.md"`.
119
+
120
+ **In a remote CCR agent:**
121
+ Clone the vault repo, run the sync, commit and push. The local Obsidian Git plugin
122
+ pulls the changes automatically.
123
+
124
+ ## Output to user
125
+
126
+ After writing the file, show a brief confirmation:
127
+
128
+ ```
129
+ Synced N PRs to Lead/Daily/YYYY-MM-DD.md
130
+ Work (<ORG_PREFIX>): X PRs
131
+ Personal: Y PRs
132
+ Skipped: Z bots/drafts
133
+ ```
134
+
135
+ If any `gh` call fails (e.g. auth expired), surface the error clearly rather than
136
+ writing a partial/corrupt section.