clud-bug 0.6.34 → 0.7.0-rc.11

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 (153) hide show
  1. package/README.md +20 -0
  2. package/bin/clud-bug.js +10 -1353
  3. package/data/canonical-v1.json +37 -0
  4. package/dist/cli/agents-md.d.ts +16 -0
  5. package/dist/cli/agents-md.d.ts.map +1 -0
  6. package/dist/cli/agents-md.js +226 -0
  7. package/dist/cli/agents-md.js.map +1 -0
  8. package/dist/cli/audit.d.ts +13 -0
  9. package/dist/cli/audit.d.ts.map +1 -0
  10. package/dist/cli/audit.js +90 -0
  11. package/dist/cli/audit.js.map +1 -0
  12. package/dist/cli/branch-protection.d.ts +57 -0
  13. package/dist/cli/branch-protection.d.ts.map +1 -0
  14. package/dist/cli/branch-protection.js +118 -0
  15. package/dist/cli/branch-protection.js.map +1 -0
  16. package/dist/cli/configure-github.d.ts +58 -0
  17. package/dist/cli/configure-github.d.ts.map +1 -0
  18. package/dist/cli/configure-github.js +242 -0
  19. package/dist/cli/configure-github.js.map +1 -0
  20. package/dist/cli/edit-workflow.d.ts +18 -0
  21. package/dist/cli/edit-workflow.d.ts.map +1 -0
  22. package/dist/cli/edit-workflow.js +43 -0
  23. package/dist/cli/edit-workflow.js.map +1 -0
  24. package/dist/cli/index.d.ts +9 -0
  25. package/dist/cli/index.d.ts.map +1 -0
  26. package/dist/cli/index.js +19 -0
  27. package/dist/cli/index.js.map +1 -0
  28. package/dist/cli/main.d.ts +3 -0
  29. package/dist/cli/main.d.ts.map +1 -0
  30. package/dist/cli/main.js +2067 -0
  31. package/dist/cli/main.js.map +1 -0
  32. package/dist/cli/skill-usage.d.ts +109 -0
  33. package/dist/cli/skill-usage.d.ts.map +1 -0
  34. package/dist/cli/skill-usage.js +380 -0
  35. package/dist/cli/skill-usage.js.map +1 -0
  36. package/dist/cli/skills.d.ts +56 -0
  37. package/dist/cli/skills.d.ts.map +1 -0
  38. package/dist/cli/skills.js +292 -0
  39. package/dist/cli/skills.js.map +1 -0
  40. package/dist/cli/update.d.ts +29 -0
  41. package/dist/cli/update.d.ts.map +1 -0
  42. package/dist/cli/update.js +205 -0
  43. package/dist/cli/update.js.map +1 -0
  44. package/dist/cli/usage.d.ts +142 -0
  45. package/dist/cli/usage.d.ts.map +1 -0
  46. package/dist/cli/usage.js +348 -0
  47. package/dist/cli/usage.js.map +1 -0
  48. package/dist/core/audit.d.ts +8 -0
  49. package/dist/core/audit.d.ts.map +1 -0
  50. package/dist/core/audit.js +47 -0
  51. package/dist/core/audit.js.map +1 -0
  52. package/dist/core/auto-resolve.d.ts +235 -0
  53. package/dist/core/auto-resolve.d.ts.map +1 -0
  54. package/dist/core/auto-resolve.js +293 -0
  55. package/dist/core/auto-resolve.js.map +1 -0
  56. package/dist/core/configure-github.d.ts +179 -0
  57. package/dist/core/configure-github.d.ts.map +1 -0
  58. package/dist/core/configure-github.js +289 -0
  59. package/dist/core/configure-github.js.map +1 -0
  60. package/dist/core/detect.d.ts +77 -0
  61. package/dist/core/detect.d.ts.map +1 -0
  62. package/dist/core/detect.js +262 -0
  63. package/dist/core/detect.js.map +1 -0
  64. package/dist/core/diff-findings.d.ts +96 -0
  65. package/dist/core/diff-findings.d.ts.map +1 -0
  66. package/dist/core/diff-findings.js +261 -0
  67. package/dist/core/diff-findings.js.map +1 -0
  68. package/dist/core/formal-review.d.ts +79 -0
  69. package/dist/core/formal-review.d.ts.map +1 -0
  70. package/dist/core/formal-review.js +71 -0
  71. package/dist/core/formal-review.js.map +1 -0
  72. package/dist/core/index.d.ts +17 -0
  73. package/dist/core/index.d.ts.map +1 -0
  74. package/dist/core/index.js +66 -0
  75. package/dist/core/index.js.map +1 -0
  76. package/dist/core/inline-threads.d.ts +160 -0
  77. package/dist/core/inline-threads.d.ts.map +1 -0
  78. package/dist/core/inline-threads.js +369 -0
  79. package/dist/core/inline-threads.js.map +1 -0
  80. package/dist/core/prompt-builder.d.ts +164 -0
  81. package/dist/core/prompt-builder.d.ts.map +1 -0
  82. package/dist/core/prompt-builder.js +419 -0
  83. package/dist/core/prompt-builder.js.map +1 -0
  84. package/dist/core/prompts.d.ts +9 -0
  85. package/dist/core/prompts.d.ts.map +1 -0
  86. package/dist/core/prompts.js +401 -0
  87. package/dist/core/prompts.js.map +1 -0
  88. package/dist/core/render-review.d.ts +6 -0
  89. package/dist/core/render-review.d.ts.map +1 -0
  90. package/dist/core/render-review.js +219 -0
  91. package/dist/core/render-review.js.map +1 -0
  92. package/dist/core/render.d.ts +13 -0
  93. package/dist/core/render.d.ts.map +1 -0
  94. package/dist/core/render.js +62 -0
  95. package/dist/core/render.js.map +1 -0
  96. package/dist/core/resolve-verifier.d.ts +46 -0
  97. package/dist/core/resolve-verifier.d.ts.map +1 -0
  98. package/dist/core/resolve-verifier.js +187 -0
  99. package/dist/core/resolve-verifier.js.map +1 -0
  100. package/dist/core/review-schema-zod.d.ts +240 -0
  101. package/dist/core/review-schema-zod.d.ts.map +1 -0
  102. package/dist/core/review-schema-zod.js +218 -0
  103. package/dist/core/review-schema-zod.js.map +1 -0
  104. package/dist/core/review-schema.d.ts +42 -0
  105. package/dist/core/review-schema.d.ts.map +1 -0
  106. package/dist/core/review-schema.js +156 -0
  107. package/dist/core/review-schema.js.map +1 -0
  108. package/dist/core/review-writeback.d.ts +193 -0
  109. package/dist/core/review-writeback.d.ts.map +1 -0
  110. package/dist/core/review-writeback.js +364 -0
  111. package/dist/core/review-writeback.js.map +1 -0
  112. package/dist/core/skills.d.ts +147 -0
  113. package/dist/core/skills.d.ts.map +1 -0
  114. package/dist/core/skills.js +726 -0
  115. package/dist/core/skills.js.map +1 -0
  116. package/dist/core/version.d.ts +2 -0
  117. package/dist/core/version.d.ts.map +1 -0
  118. package/dist/core/version.js +4 -0
  119. package/dist/core/version.js.map +1 -0
  120. package/package.json +37 -5
  121. package/{lib/agents-md.js → src/cli/agents-md.ts} +25 -14
  122. package/{lib/audit.js → src/cli/audit.ts} +37 -44
  123. package/{lib/branch-protection.js → src/cli/branch-protection.ts} +75 -11
  124. package/src/cli/configure-github.ts +329 -0
  125. package/{lib/edit-workflow.js → src/cli/edit-workflow.ts} +32 -11
  126. package/src/cli/index.ts +107 -0
  127. package/src/cli/main.ts +2204 -0
  128. package/{lib/skill-usage.js → src/cli/skill-usage.ts} +168 -94
  129. package/src/cli/skills.ts +386 -0
  130. package/{lib/update.js → src/cli/update.ts} +87 -27
  131. package/{lib/usage.js → src/cli/usage.ts} +167 -76
  132. package/src/core/audit.ts +53 -0
  133. package/src/core/auto-resolve.ts +488 -0
  134. package/src/core/configure-github.ts +497 -0
  135. package/{lib/detect.js → src/core/detect.ts} +100 -47
  136. package/src/core/diff-findings.ts +323 -0
  137. package/src/core/formal-review.ts +168 -0
  138. package/src/core/index.ts +250 -0
  139. package/src/core/inline-threads.ts +471 -0
  140. package/src/core/prompt-builder.ts +561 -0
  141. package/{lib/prompts.js → src/core/prompts.ts} +16 -2
  142. package/{lib/render-review.js → src/core/render-review.ts} +57 -25
  143. package/{lib/render.js → src/core/render.ts} +37 -17
  144. package/src/core/resolve-verifier.ts +228 -0
  145. package/src/core/review-schema-zod.ts +262 -0
  146. package/{lib/review-schema.js → src/core/review-schema.ts} +68 -5
  147. package/src/core/review-writeback.ts +565 -0
  148. package/{lib/skills.js → src/core/skills.ts} +456 -342
  149. package/src/core/version.ts +3 -0
  150. package/templates/clud-bug-review.md.tmpl +115 -0
  151. package/templates/workflow-py.yml.tmpl +80 -3
  152. package/templates/workflow-ts.yml.tmpl +80 -3
  153. package/templates/workflow.yml.tmpl +175 -8
@@ -0,0 +1,380 @@
1
+ // src/cli/skill-usage.ts — Component 1+2 of the pragmatic SkDD pivot.
2
+ //
3
+ // Pure functions for deterministic skill-usage tracking. Per the
4
+ // strategic pivot (2026-05-30): replace Zak Elfassi's speculative
5
+ // recursive-meta-skill direction with concrete usage data + human-gated
6
+ // approval. This module is the data layer.
7
+ //
8
+ // Three responsibilities:
9
+ //
10
+ // 1. computeSkillUsageDelta(reviewJson)
11
+ // Given the structured-output JSON from one clud-bug review,
12
+ // return the per-skill delta for that one review.
13
+ //
14
+ // 2. mergeSkillUsage(existing, delta, timestamp)
15
+ // Merge a delta into the persistent usage block (the `usage`
16
+ // field in `.claude/skills/.clud-bug.json`).
17
+ //
18
+ // 3. assessSkillHealth(usage, now)
19
+ // Apply the deterministic thresholds + return a row per skill
20
+ // that `clud-bug usage --health` renders as a table.
21
+ //
22
+ // All three are pure. Side effects (file I/O) live in bin/clud-bug.js
23
+ // and the workflow post-step (v0.6.29).
24
+ //
25
+ // Thresholds — concrete numbers per design (2026-05-30):
26
+ //
27
+ // - archive-candidate: citations == 0 across last 90 days of loads
28
+ // - stale: last cited > 60 days ago
29
+ // - healthy: >= 3 citations in any rolling 90-day window
30
+ // - new: loads < 5 (still bedding in; don't judge yet)
31
+ //
32
+ // No automation acts on this output. It's a READ-ONLY dashboard.
33
+ // Humans read; humans decide; humans act.
34
+ import { spawn } from 'node:child_process';
35
+ /**
36
+ * Compute per-skill usage delta from a single review's structured JSON.
37
+ *
38
+ * Rules:
39
+ * - loads = 1 for every skill in per_skill_scan (the skill was in
40
+ * context for this review).
41
+ * - citations = 1 if the skill slug appears in ANY finding bucket
42
+ * (critical / minor / dedicated). Multiple findings from the same
43
+ * skill on one review = 1 citation, not N. Citations count REVIEWS
44
+ * that cited the skill, not findings within a review.
45
+ *
46
+ * Returns {} on missing / malformed input (defensive — never throws).
47
+ */
48
+ export function computeSkillUsageDelta(reviewJson) {
49
+ if (!reviewJson || typeof reviewJson !== 'object')
50
+ return {};
51
+ const review = reviewJson;
52
+ const delta = {};
53
+ // Loads — one per skill that scanned.
54
+ for (const entry of review.per_skill_scan || []) {
55
+ if (!entry || typeof entry.skill !== 'string')
56
+ continue;
57
+ const slug = entry.skill;
58
+ if (!delta[slug])
59
+ delta[slug] = { loads: 0, citations: 0 };
60
+ delta[slug].loads = 1;
61
+ }
62
+ // Citations — collect unique skill slugs across all finding buckets.
63
+ const cited = new Set();
64
+ const collect = (findings) => {
65
+ for (const f of findings || []) {
66
+ if (f && typeof f.skill === 'string')
67
+ cited.add(f.skill);
68
+ }
69
+ };
70
+ collect(review.critical_findings);
71
+ collect(review.minor_findings);
72
+ collect(review.preexisting_findings);
73
+ for (const section of review.dedicated_sections || []) {
74
+ collect(section?.findings);
75
+ }
76
+ for (const slug of cited) {
77
+ if (!delta[slug])
78
+ delta[slug] = { loads: 0, citations: 0 };
79
+ delta[slug].citations = 1;
80
+ }
81
+ return delta;
82
+ }
83
+ /**
84
+ * Merge a per-review delta into a persistent usage block.
85
+ *
86
+ * Semantics:
87
+ * - existing.loads + delta.loads → new.loads (accumulates forever)
88
+ * - existing.citations + delta.citations → new.citations
89
+ * - last_cited updates only when delta.citations > 0 (i.e., cited
90
+ * in THIS review). Stays at the prior value otherwise.
91
+ * - New skills (not in existing) get initialized fresh.
92
+ */
93
+ export function mergeSkillUsage(existing, delta, timestamp) {
94
+ const safeExisting = (existing && typeof existing === 'object') ? existing : {};
95
+ const result = {};
96
+ // Copy all existing skills first (preserve skills NOT in this delta).
97
+ for (const [slug, entry] of Object.entries(safeExisting)) {
98
+ if (entry && typeof entry === 'object') {
99
+ const e = entry;
100
+ result[slug] = {
101
+ loads: Number(e.loads) || 0,
102
+ citations: Number(e.citations) || 0,
103
+ last_cited: typeof e.last_cited === 'string' ? e.last_cited : null,
104
+ };
105
+ }
106
+ }
107
+ // Merge delta.
108
+ for (const [slug, d] of Object.entries(delta || {})) {
109
+ let row = result[slug];
110
+ if (!row) {
111
+ row = { loads: 0, citations: 0, last_cited: null };
112
+ result[slug] = row;
113
+ }
114
+ row.loads += Number(d.loads) || 0;
115
+ row.citations += Number(d.citations) || 0;
116
+ if ((Number(d.citations) || 0) > 0 && timestamp) {
117
+ row.last_cited = timestamp;
118
+ }
119
+ }
120
+ return result;
121
+ }
122
+ /**
123
+ * Apply deterministic skill-health thresholds to a usage block.
124
+ *
125
+ * Status values:
126
+ * - "archive-candidate": citations == 0 AND loads >= 5
127
+ * → loaded enough to judge, never cited → propose for removal
128
+ * - "stale": last_cited > 60 days ago (even with citations history)
129
+ * → was useful, hasn't fired recently
130
+ * - "new": loads < 5
131
+ * → still bedding in; don't judge yet
132
+ * - "healthy": cited within 60 days
133
+ * → still earning its place
134
+ *
135
+ * Sorted by status priority (archive > stale > new > healthy), then
136
+ * by loads desc within each group. Highest-noise skills surface first.
137
+ */
138
+ export function assessSkillHealth(usage, now) {
139
+ const safeUsage = (usage && typeof usage === 'object') ? usage : {};
140
+ const safeNow = (now instanceof Date) ? now : new Date();
141
+ const sixtyDaysAgoMs = safeNow.getTime() - (60 * 24 * 60 * 60 * 1000);
142
+ const rows = [];
143
+ for (const [slug, entry] of Object.entries(safeUsage)) {
144
+ if (!entry || typeof entry !== 'object')
145
+ continue;
146
+ const e = entry;
147
+ const loads = Number(e.loads) || 0;
148
+ const citations = Number(e.citations) || 0;
149
+ const last_cited = typeof e.last_cited === 'string' ? e.last_cited : null;
150
+ let status;
151
+ let days_since_cited = null;
152
+ if (loads < 5) {
153
+ status = 'new';
154
+ }
155
+ else if (citations === 0) {
156
+ status = 'archive-candidate';
157
+ }
158
+ else {
159
+ // Has citations. Check recency.
160
+ const lastCitedMs = last_cited ? Date.parse(last_cited) : null;
161
+ if (lastCitedMs && lastCitedMs >= sixtyDaysAgoMs) {
162
+ status = 'healthy';
163
+ days_since_cited = Math.floor((safeNow.getTime() - lastCitedMs) / (24 * 60 * 60 * 1000));
164
+ }
165
+ else if (lastCitedMs) {
166
+ status = 'stale';
167
+ days_since_cited = Math.floor((safeNow.getTime() - lastCitedMs) / (24 * 60 * 60 * 1000));
168
+ }
169
+ else {
170
+ // Has citations count but no timestamp (legacy / corrupted) — treat as stale.
171
+ status = 'stale';
172
+ }
173
+ }
174
+ rows.push({ slug, status, loads, citations, last_cited, days_since_cited });
175
+ }
176
+ // Sort: archive-candidates first, then stale, then new, then healthy.
177
+ // Within each group, by loads descending (loudest first).
178
+ const statusOrder = {
179
+ 'archive-candidate': 0,
180
+ 'stale': 1,
181
+ 'new': 2,
182
+ 'healthy': 3,
183
+ };
184
+ rows.sort((a, b) => {
185
+ const da = statusOrder[a.status] ?? 99;
186
+ const db = statusOrder[b.status] ?? 99;
187
+ if (da !== db)
188
+ return da - db;
189
+ return b.loads - a.loads;
190
+ });
191
+ return rows;
192
+ }
193
+ /**
194
+ * Render the health dashboard as a 3-column table for the CLI.
195
+ */
196
+ export function formatHealthDashboard(rows) {
197
+ if (!rows || rows.length === 0) {
198
+ return ('Skill health: no usage data yet.\n\n' +
199
+ 'Skill-usage artifacts will start accumulating from your next\n' +
200
+ 'clud-bug-review run on a substantive PR (workflow-only PRs auto-skip\n' +
201
+ 'review via 0.0.W² and produce no artifact). Run this command again\n' +
202
+ 'with `--repo owner/name` once a few reviews have completed.');
203
+ }
204
+ const STATUS_GLYPH = {
205
+ 'archive-candidate': '🟥 archive?',
206
+ 'stale': '🟨 stale',
207
+ 'new': '🟦 new',
208
+ 'healthy': '🟩 healthy',
209
+ };
210
+ const lines = [];
211
+ lines.push('Skill health (deterministic — read-only; no automation acts on this)');
212
+ lines.push('');
213
+ lines.push(' STATUS SLUG LOADS CITES LAST CITED');
214
+ lines.push(' ---------------- -------------------------------- ----- ----- --------------');
215
+ for (const r of rows) {
216
+ const status = STATUS_GLYPH[r.status] || r.status;
217
+ const slug = r.slug.length > 32 ? r.slug.slice(0, 29) + '...' : r.slug;
218
+ const ago = r.days_since_cited != null ? `${r.days_since_cited}d ago` : '(never)';
219
+ lines.push(` ${status.padEnd(16)} ${slug.padEnd(32)} ${String(r.loads).padStart(5)} ` +
220
+ `${String(r.citations).padStart(5)} ${ago}`);
221
+ }
222
+ lines.push('');
223
+ lines.push('Thresholds:');
224
+ lines.push(' archive-candidate = citations==0 + loads>=5');
225
+ lines.push(' stale = last cited >60 days ago');
226
+ lines.push(' new = loads<5 (still bedding in)');
227
+ lines.push(' healthy = cited within 60 days');
228
+ return lines.join('\n');
229
+ }
230
+ /**
231
+ * Default `gh` runner — spawns the local gh CLI. Tests inject a mock.
232
+ *
233
+ * The runner has two methods:
234
+ * - json(args): returns parsed JSON stdout, or null on error.
235
+ * - run(args): returns {code, stdout, stderr}. For commands that
236
+ * download files etc. — no JSON parsing.
237
+ */
238
+ async function defaultGhJson(args) {
239
+ return new Promise((resolve) => {
240
+ const child = spawn('gh', args, { stdio: ['ignore', 'pipe', 'pipe'] });
241
+ let stdout = '';
242
+ child.stdout.on('data', (d) => { stdout += d; });
243
+ child.on('error', () => resolve(null));
244
+ child.on('close', (code) => {
245
+ if (code !== 0)
246
+ return resolve(null);
247
+ try {
248
+ resolve(JSON.parse(stdout));
249
+ }
250
+ catch {
251
+ resolve(null);
252
+ }
253
+ });
254
+ });
255
+ }
256
+ async function defaultGhRun(args) {
257
+ return new Promise((resolve) => {
258
+ const child = spawn('gh', args, { stdio: ['ignore', 'pipe', 'pipe'] });
259
+ let stdout = '';
260
+ let stderr = '';
261
+ child.stdout.on('data', (d) => { stdout += d; });
262
+ child.stderr.on('data', (d) => { stderr += d; });
263
+ child.on('error', () => resolve({ code: 1, stdout: '', stderr: 'gh not on PATH' }));
264
+ child.on('close', (code) => resolve({ code, stdout, stderr }));
265
+ });
266
+ }
267
+ export const DEFAULT_GH_RUNNER = {
268
+ json: defaultGhJson,
269
+ run: defaultGhRun,
270
+ };
271
+ /**
272
+ * Fetch all per-PR skill-usage artifacts from a repo. Each artifact is
273
+ * downloaded to a temp dir, its `.clud-bug.json` is parsed, and the
274
+ * usage block is returned.
275
+ */
276
+ export async function fetchUsageArtifacts({ owner, repo, since = null, ghRunner = DEFAULT_GH_RUNNER }) {
277
+ if (!owner || !repo) {
278
+ throw new Error('fetchUsageArtifacts: owner + repo are required');
279
+ }
280
+ // List artifacts in one call. We deliberately do NOT use `--paginate`:
281
+ // `gh api --paginate --jq <expr>` applies the jq filter to EACH page
282
+ // independently and concatenates the outputs with newlines, which
283
+ // produces `[...]\n[...]` — invalid as a single JSON document.
284
+ // `JSON.parse` returns null and the dashboard silently shows nothing
285
+ // for repos with >30 artifacts (default page size). Caught by
286
+ // clud-bug-review on PR #127.
287
+ //
288
+ // `?per_page=100` covers up to 100 artifacts in one call. The 90-day
289
+ // artifact retention means most repos won't hit that ceiling (>100
290
+ // PR reviews in 90 days = >1/day sustained). If a future repo
291
+ // saturates this, paginate manually in v0.6.31+ (per_page=100 +
292
+ // explicit `?page=N` loop, parse each response as JSON, concatenate).
293
+ const list = await ghRunner.json([
294
+ 'api',
295
+ `repos/${owner}/${repo}/actions/artifacts?per_page=100`,
296
+ '--jq',
297
+ '[.artifacts[] | select(.name | startswith("clud-bug-skill-usage-pr-")) | select(.expired == false) | {id, name, workflow_run_id: .workflow_run.id, created_at}]',
298
+ ]);
299
+ // `--jq '[...]'` wraps the stream into a single array. If the runner
300
+ // returns null (404, no auth, etc.), bail to empty list.
301
+ if (!Array.isArray(list))
302
+ return [];
303
+ const items = list;
304
+ const filtered = since
305
+ ? items.filter((a) => new Date(a.created_at) >= since)
306
+ : items;
307
+ const fs = await import('node:fs/promises');
308
+ const path = await import('node:path');
309
+ const os = await import('node:os');
310
+ const results = [];
311
+ for (const art of filtered) {
312
+ const prMatch = art.name.match(/^clud-bug-skill-usage-pr-(\d+)$/);
313
+ if (!prMatch)
314
+ continue;
315
+ // prMatch[1] is `string | undefined` under noUncheckedIndexedAccess; the
316
+ // regex guarantees the capture exists when match succeeds.
317
+ const prNumber = Number(prMatch[1]);
318
+ const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'clud-bug-art-'));
319
+ try {
320
+ const dl = await ghRunner.run([
321
+ 'run', 'download', String(art.workflow_run_id),
322
+ '-R', `${owner}/${repo}`,
323
+ '-n', art.name,
324
+ '-D', tmpDir,
325
+ ]);
326
+ if (dl.code !== 0)
327
+ continue;
328
+ // The workflow uploaded `.clud-bug.json` (single file under the
329
+ // path key). `gh run download -D <dir>` writes it to the dest as
330
+ // `<dir>/.clud-bug.json` (preserves the source path).
331
+ const jsonPath = path.join(tmpDir, '.clud-bug.json');
332
+ let parsed;
333
+ try {
334
+ const raw = await fs.readFile(jsonPath, 'utf-8');
335
+ parsed = JSON.parse(raw);
336
+ }
337
+ catch {
338
+ continue; // artifact corrupted or layout unexpected
339
+ }
340
+ const parsedObj = (parsed && typeof parsed === 'object')
341
+ ? parsed
342
+ : {};
343
+ const usage = (parsedObj.usage && typeof parsedObj.usage === 'object')
344
+ ? parsedObj.usage
345
+ : {};
346
+ results.push({
347
+ prNumber,
348
+ artifactId: art.id,
349
+ usage,
350
+ fetchedAt: art.created_at,
351
+ });
352
+ }
353
+ finally {
354
+ await fs.rm(tmpDir, { recursive: true, force: true });
355
+ }
356
+ }
357
+ return results;
358
+ }
359
+ /**
360
+ * Reduce an array of per-PR artifact records into a single accumulated
361
+ * usage block by left-folding `mergeSkillUsage` over them, ordered by
362
+ * `fetchedAt` ascending so the last_cited timestamp is deterministic.
363
+ *
364
+ * Because `mergeSkillUsage` is commutative for loads + citations counts
365
+ * AND keeps the LATEST timestamp it sees as last_cited (we sort
366
+ * ascending so newest wins on the final pass), out-of-order input
367
+ * produces an identical result.
368
+ */
369
+ export function aggregateUsageStream(artifacts) {
370
+ if (!Array.isArray(artifacts) || artifacts.length === 0)
371
+ return {};
372
+ const sorted = [...artifacts].sort((a, b) => new Date(a.fetchedAt).getTime() - new Date(b.fetchedAt).getTime());
373
+ return sorted.reduce(
374
+ // mergeSkillUsage expects SkillDeltaMap-shape for the delta arg; usage
375
+ // here is SkillUsageMap (loads/citations counts match — only last_cited
376
+ // is extra, which mergeSkillUsage ignores from the delta side). The
377
+ // type assertion is safe and matches the JS prior behavior exactly.
378
+ (acc, art) => mergeSkillUsage(acc, (art.usage || {}), art.fetchedAt), {});
379
+ }
380
+ //# sourceMappingURL=skill-usage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-usage.js","sourceRoot":"","sources":["../../src/cli/skill-usage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ import { SkillsClient, type RankableSkill, type SkillDescriptor } from '../core/skills.js';
2
+ export declare const MANIFEST_FILE = ".clud-bug.json";
3
+ export declare const MANIFEST_VERSION = 1;
4
+ export declare function sanitizeSlug(name: string): string;
5
+ export declare function entryKey(entry: ManifestEntry): string;
6
+ export interface BaselineSkill {
7
+ source: string;
8
+ name: string;
9
+ description: string;
10
+ installs: number;
11
+ kind: string;
12
+ content: string;
13
+ _source?: 'agent-skills' | 'bundled';
14
+ }
15
+ export interface LoadBaselineOptions {
16
+ fetch?: typeof globalThis.fetch | undefined;
17
+ cacheDir?: string | null | undefined;
18
+ }
19
+ export declare function loadBaseline(baselineDir: string, opts?: LoadBaselineOptions): Promise<BaselineSkill[]>;
20
+ export type WritableSkill = RankableSkill;
21
+ export interface ManifestEntry {
22
+ slug: string;
23
+ name: string;
24
+ source: string;
25
+ kind: string;
26
+ description: string;
27
+ }
28
+ export interface Manifest {
29
+ version: number;
30
+ installed: ManifestEntry[];
31
+ [key: string]: unknown;
32
+ }
33
+ export declare function writeSkills(targetDir: string, skills: WritableSkill[], client: SkillsClient): Promise<ManifestEntry[]>;
34
+ export declare function writeSkill(targetDir: string, skill: WritableSkill, client: SkillsClient): Promise<ManifestEntry>;
35
+ export declare function readManifest(targetDir: string): Promise<Manifest>;
36
+ export declare function writeManifest(targetDir: string, manifest: Manifest): Promise<void>;
37
+ export declare function mergeManifest(existing: Manifest, newEntries: ManifestEntry[]): Manifest;
38
+ export declare function removeSkill(targetDir: string, slug: string): Promise<ManifestEntry>;
39
+ export interface InstalledGroups {
40
+ baseline: ManifestEntry[];
41
+ remote: ManifestEntry[];
42
+ custom: Array<{
43
+ slug: string;
44
+ kind: 'custom';
45
+ description: string;
46
+ }>;
47
+ }
48
+ export declare function listInstalled(targetDir: string): Promise<InstalledGroups>;
49
+ export interface ManifestDiff {
50
+ add: RankableSkill[];
51
+ remove: ManifestEntry[];
52
+ unchanged: RankableSkill[];
53
+ }
54
+ export declare function diffManifest(manifest: Manifest, recommended: RankableSkill[]): ManifestDiff;
55
+ export type { SkillDescriptor };
56
+ //# sourceMappingURL=skills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/cli/skills.ts"],"names":[],"mappings":"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"}