@hivemoot-dev/cli 0.1.2 → 0.1.4
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/dist/index.js +76 -33
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
+
import { createRequire } from "module";
|
|
4
5
|
import { Command, InvalidArgumentError } from "commander";
|
|
5
6
|
|
|
6
7
|
// src/config/types.ts
|
|
@@ -243,7 +244,7 @@ async function resolveRepo(repoFlag) {
|
|
|
243
244
|
}
|
|
244
245
|
|
|
245
246
|
// src/github/issues.ts
|
|
246
|
-
async function fetchIssues(repo) {
|
|
247
|
+
async function fetchIssues(repo, limit = 200) {
|
|
247
248
|
const json = await gh([
|
|
248
249
|
"issue",
|
|
249
250
|
"list",
|
|
@@ -254,7 +255,7 @@ async function fetchIssues(repo) {
|
|
|
254
255
|
"--json",
|
|
255
256
|
"number,title,labels,assignees,author,comments,createdAt,updatedAt,url",
|
|
256
257
|
"--limit",
|
|
257
|
-
|
|
258
|
+
String(limit)
|
|
258
259
|
]);
|
|
259
260
|
let parsed;
|
|
260
261
|
try {
|
|
@@ -277,7 +278,7 @@ async function fetchIssues(repo) {
|
|
|
277
278
|
}
|
|
278
279
|
|
|
279
280
|
// src/github/pulls.ts
|
|
280
|
-
async function fetchPulls(repo) {
|
|
281
|
+
async function fetchPulls(repo, limit = 200) {
|
|
281
282
|
const json = await gh([
|
|
282
283
|
"pr",
|
|
283
284
|
"list",
|
|
@@ -288,7 +289,7 @@ async function fetchPulls(repo) {
|
|
|
288
289
|
"--json",
|
|
289
290
|
"number,title,state,author,labels,comments,reviews,createdAt,updatedAt,url,isDraft,reviewDecision,mergeable,statusCheckRollup,closingIssuesReferences",
|
|
290
291
|
"--limit",
|
|
291
|
-
|
|
292
|
+
String(limit)
|
|
292
293
|
]);
|
|
293
294
|
let parsed;
|
|
294
295
|
try {
|
|
@@ -332,6 +333,27 @@ function hasLabel(labels, keyword) {
|
|
|
332
333
|
function hasExactLabel(labels, labelName) {
|
|
333
334
|
return labels.some((l) => l.name.toLowerCase() === labelName.toLowerCase());
|
|
334
335
|
}
|
|
336
|
+
function timeAgo(dateStr, now) {
|
|
337
|
+
const ms = now.getTime() - new Date(dateStr).getTime();
|
|
338
|
+
if (ms < 0) return "just now";
|
|
339
|
+
const minutes = Math.floor(ms / 6e4);
|
|
340
|
+
const hours = Math.floor(ms / 36e5);
|
|
341
|
+
const days = Math.floor(ms / 864e5);
|
|
342
|
+
if (minutes < 1) return "just now";
|
|
343
|
+
if (minutes === 1) return "1 minute ago";
|
|
344
|
+
if (minutes < 60) return `${minutes} minutes ago`;
|
|
345
|
+
if (hours === 1) return "1 hour ago";
|
|
346
|
+
if (hours < 24) return `${hours} hours ago`;
|
|
347
|
+
if (days === 1) return "yesterday";
|
|
348
|
+
if (days < 7) return `${days} days ago`;
|
|
349
|
+
if (days < 14) return "1 week ago";
|
|
350
|
+
if (days < 30) return `${Math.floor(days / 7)} weeks ago`;
|
|
351
|
+
if (days < 60) return "1 month ago";
|
|
352
|
+
if (days < 365) return `${Math.floor(days / 30)} months ago`;
|
|
353
|
+
const years = Math.floor(days / 365);
|
|
354
|
+
if (years === 1) return "1 year ago";
|
|
355
|
+
return `${years} years ago`;
|
|
356
|
+
}
|
|
335
357
|
function daysSince(dateStr, now) {
|
|
336
358
|
const diff = now.getTime() - new Date(dateStr).getTime();
|
|
337
359
|
return Math.max(0, Math.floor(diff / (1e3 * 60 * 60 * 24)));
|
|
@@ -360,18 +382,27 @@ function mergeStatus(pr) {
|
|
|
360
382
|
if (pr.mergeable === "MERGEABLE") return "no conflicts";
|
|
361
383
|
return null;
|
|
362
384
|
}
|
|
363
|
-
function
|
|
364
|
-
|
|
365
|
-
const
|
|
366
|
-
|
|
367
|
-
latestByAuthor.set(review.author.login, review.state);
|
|
385
|
+
function latestReviewByAuthor(pr) {
|
|
386
|
+
const map = /* @__PURE__ */ new Map();
|
|
387
|
+
for (const review of pr.reviews ?? []) {
|
|
388
|
+
map.set(review.author?.login ?? "ghost", review.state);
|
|
368
389
|
}
|
|
390
|
+
return map;
|
|
391
|
+
}
|
|
392
|
+
function approvalCount(pr) {
|
|
369
393
|
let count = 0;
|
|
370
|
-
for (const state of
|
|
394
|
+
for (const state of latestReviewByAuthor(pr).values()) {
|
|
371
395
|
if (state === "APPROVED") count++;
|
|
372
396
|
}
|
|
373
397
|
return count;
|
|
374
398
|
}
|
|
399
|
+
function changesRequestedCount(pr) {
|
|
400
|
+
let count = 0;
|
|
401
|
+
for (const state of latestReviewByAuthor(pr).values()) {
|
|
402
|
+
if (state === "CHANGES_REQUESTED") count++;
|
|
403
|
+
}
|
|
404
|
+
return count;
|
|
405
|
+
}
|
|
375
406
|
|
|
376
407
|
// src/summary/alerts.ts
|
|
377
408
|
var STALE_DISCUSSION_DAYS = 3;
|
|
@@ -429,12 +460,6 @@ function generateAlerts(issues, prs, now = /* @__PURE__ */ new Date()) {
|
|
|
429
460
|
}
|
|
430
461
|
|
|
431
462
|
// src/summary/builder.ts
|
|
432
|
-
function timeAgo(dateStr, now) {
|
|
433
|
-
const days = daysSince(dateStr, now);
|
|
434
|
-
if (days === 0) return "today";
|
|
435
|
-
if (days === 1) return "1 day old";
|
|
436
|
-
return `${days} days old`;
|
|
437
|
-
}
|
|
438
463
|
function compactChecks(raw) {
|
|
439
464
|
if (raw === null) return null;
|
|
440
465
|
if (raw === "checks failing") return "failing";
|
|
@@ -452,7 +477,7 @@ function classifyIssue(issue, now) {
|
|
|
452
477
|
const age = timeAgo(issue.createdAt, now);
|
|
453
478
|
const assigned = issue.assignees.length > 0 ? issue.assignees.map((a) => a.login).join(", ") : void 0;
|
|
454
479
|
const tags = issue.labels.map((l) => l.name);
|
|
455
|
-
const author = issue.author
|
|
480
|
+
const author = issue.author?.login ?? "ghost";
|
|
456
481
|
const comments = issue.comments.length;
|
|
457
482
|
const base = {
|
|
458
483
|
number: issue.number,
|
|
@@ -491,12 +516,15 @@ function classifyIssue(issue, now) {
|
|
|
491
516
|
function classifyPR(pr, now) {
|
|
492
517
|
const age = timeAgo(pr.createdAt, now);
|
|
493
518
|
const tags = pr.labels.map((l) => l.name);
|
|
494
|
-
const author = pr.author
|
|
519
|
+
const author = pr.author?.login ?? "ghost";
|
|
495
520
|
const comments = pr.comments.length;
|
|
496
521
|
const ciFailing = hasCIFailure(pr);
|
|
497
522
|
const checks = compactChecks(checkStatus(pr));
|
|
498
523
|
const merge = compactMergeable(mergeStatus(pr));
|
|
499
|
-
const
|
|
524
|
+
const review = {
|
|
525
|
+
approvals: approvalCount(pr),
|
|
526
|
+
changesRequested: changesRequestedCount(pr)
|
|
527
|
+
};
|
|
500
528
|
if (pr.isDraft || ciFailing || pr.reviewDecision === "CHANGES_REQUESTED") {
|
|
501
529
|
let status2;
|
|
502
530
|
if (pr.isDraft) status2 = "draft";
|
|
@@ -504,20 +532,20 @@ function classifyPR(pr, now) {
|
|
|
504
532
|
else status2 = "waiting";
|
|
505
533
|
return {
|
|
506
534
|
bucket: "addressFeedback",
|
|
507
|
-
item: { number: pr.number, title: pr.title, tags, author, comments, age, status: status2, checks, mergeable: merge,
|
|
535
|
+
item: { number: pr.number, title: pr.title, tags, author, comments, age, status: status2, checks, mergeable: merge, review }
|
|
508
536
|
};
|
|
509
537
|
}
|
|
510
538
|
const status = pr.reviewDecision === "APPROVED" ? "approved" : "waiting";
|
|
511
539
|
return {
|
|
512
540
|
bucket: "reviewPRs",
|
|
513
|
-
item: { number: pr.number, title: pr.title, tags, author, comments, age, status, checks, mergeable: merge,
|
|
541
|
+
item: { number: pr.number, title: pr.title, tags, author, comments, age, status, checks, mergeable: merge, review }
|
|
514
542
|
};
|
|
515
543
|
}
|
|
516
544
|
function buildCompetitionMap(prs, currentUser) {
|
|
517
545
|
const map = /* @__PURE__ */ new Map();
|
|
518
546
|
for (const pr of prs) {
|
|
519
547
|
if (!hasLabel(pr.labels, "implementation")) continue;
|
|
520
|
-
if (pr.author
|
|
548
|
+
if (pr.author?.login === currentUser) continue;
|
|
521
549
|
for (const ref of pr.closingIssuesReferences) {
|
|
522
550
|
map.set(ref.number, (map.get(ref.number) ?? 0) + 1);
|
|
523
551
|
}
|
|
@@ -589,7 +617,8 @@ function buildSummary(repo, issues, prs, currentUser, now = /* @__PURE__ */ new
|
|
|
589
617
|
implement,
|
|
590
618
|
reviewPRs: filteredReviewPRs,
|
|
591
619
|
addressFeedback: filteredAddressFeedback,
|
|
592
|
-
alerts
|
|
620
|
+
alerts,
|
|
621
|
+
notes: []
|
|
593
622
|
};
|
|
594
623
|
}
|
|
595
624
|
|
|
@@ -615,20 +644,20 @@ function formatMeta(item, sectionType, currentUser) {
|
|
|
615
644
|
if (sectionType === "implement") {
|
|
616
645
|
parts.push(kv("assigned", item.assigned ?? "--"));
|
|
617
646
|
parts.push(kv("comments", item.comments));
|
|
618
|
-
parts.push(kv("
|
|
647
|
+
parts.push(kv("created", item.age));
|
|
619
648
|
if (item.competingPRs !== void 0) {
|
|
620
649
|
parts.push(kv("competing", item.competingPRs));
|
|
621
650
|
}
|
|
622
651
|
} else if (sectionType === "vote" || sectionType === "discuss" || sectionType === "driveDiscussion") {
|
|
623
652
|
parts.push(kv("comments", item.comments));
|
|
624
|
-
parts.push(kv("
|
|
653
|
+
parts.push(kv("created", item.age));
|
|
625
654
|
} else {
|
|
626
655
|
if (item.status !== void 0) parts.push(kv("status", item.status));
|
|
627
656
|
if (item.checks !== void 0 && item.checks !== null) parts.push(kv("checks", item.checks));
|
|
628
657
|
if (item.mergeable !== void 0 && item.mergeable !== null) parts.push(kv("merge", item.mergeable));
|
|
629
|
-
if (item.
|
|
658
|
+
if (item.review) parts.push(kv("review", `${item.review.approvals} approved, ${item.review.changesRequested} changes-requested`));
|
|
630
659
|
parts.push(kv("comments", item.comments));
|
|
631
|
-
parts.push(kv("
|
|
660
|
+
parts.push(kv("created", item.age));
|
|
632
661
|
}
|
|
633
662
|
return parts.join(" ");
|
|
634
663
|
}
|
|
@@ -674,6 +703,9 @@ function formatSummaryBody(summary, limit) {
|
|
|
674
703
|
formatSection("ADDRESS FEEDBACK PRs", summary.addressFeedback, u, "addressFeedback", limit)
|
|
675
704
|
].filter(Boolean)
|
|
676
705
|
);
|
|
706
|
+
if (summary.notes.length > 0) {
|
|
707
|
+
sections.push(summary.notes.map((n) => chalk.dim(` ${n}`)).join("\n"));
|
|
708
|
+
}
|
|
677
709
|
if (sections.length === 0) {
|
|
678
710
|
return chalk.dim(" No open issues or PRs.");
|
|
679
711
|
}
|
|
@@ -735,7 +767,8 @@ function jsonBuzz(roleName, role, summary) {
|
|
|
735
767
|
implement: summary.implement,
|
|
736
768
|
reviewPRs: summary.reviewPRs,
|
|
737
769
|
addressFeedback: summary.addressFeedback,
|
|
738
|
-
alerts: summary.alerts
|
|
770
|
+
alerts: summary.alerts,
|
|
771
|
+
notes: summary.notes
|
|
739
772
|
}
|
|
740
773
|
},
|
|
741
774
|
null,
|
|
@@ -754,7 +787,8 @@ function jsonStatus(summary) {
|
|
|
754
787
|
implement: summary.implement,
|
|
755
788
|
reviewPRs: summary.reviewPRs,
|
|
756
789
|
addressFeedback: summary.addressFeedback,
|
|
757
|
-
alerts: summary.alerts
|
|
790
|
+
alerts: summary.alerts,
|
|
791
|
+
notes: summary.notes
|
|
758
792
|
},
|
|
759
793
|
null,
|
|
760
794
|
2
|
|
@@ -771,12 +805,19 @@ function jsonRoles(teamConfig) {
|
|
|
771
805
|
// src/commands/buzz.ts
|
|
772
806
|
async function buzzCommand(options) {
|
|
773
807
|
const repo = await resolveRepo(options.repo);
|
|
808
|
+
const fetchLimit = options.fetchLimit ?? 200;
|
|
774
809
|
const [issues, prs, currentUser] = await Promise.all([
|
|
775
|
-
fetchIssues(repo),
|
|
776
|
-
fetchPulls(repo),
|
|
810
|
+
fetchIssues(repo, fetchLimit),
|
|
811
|
+
fetchPulls(repo, fetchLimit),
|
|
777
812
|
fetchCurrentUser()
|
|
778
813
|
]);
|
|
779
814
|
const summary = buildSummary(repo, issues, prs, currentUser);
|
|
815
|
+
if (issues.length >= fetchLimit) {
|
|
816
|
+
summary.notes.push(`Only the first ${fetchLimit} issues were fetched. Use --fetch-limit to increase.`);
|
|
817
|
+
}
|
|
818
|
+
if (prs.length >= fetchLimit) {
|
|
819
|
+
summary.notes.push(`Only the first ${fetchLimit} PRs were fetched. Use --fetch-limit to increase.`);
|
|
820
|
+
}
|
|
780
821
|
if (options.role) {
|
|
781
822
|
const teamConfig = await loadTeamConfig(repo);
|
|
782
823
|
if (!Object.hasOwn(teamConfig.roles, options.role)) {
|
|
@@ -859,6 +900,8 @@ team:
|
|
|
859
900
|
}
|
|
860
901
|
|
|
861
902
|
// src/index.ts
|
|
903
|
+
var require2 = createRequire(import.meta.url);
|
|
904
|
+
var { version } = require2("../package.json");
|
|
862
905
|
function parseLimit(value) {
|
|
863
906
|
const n = parseInt(value, 10);
|
|
864
907
|
if (isNaN(n) || n <= 0) {
|
|
@@ -867,14 +910,14 @@ function parseLimit(value) {
|
|
|
867
910
|
return n;
|
|
868
911
|
}
|
|
869
912
|
var program = new Command();
|
|
870
|
-
program.name("hivemoot").description("CLI for Hivemoot agents \u2014 role instructions and repo work summaries").version(
|
|
913
|
+
program.name("hivemoot").description("CLI for Hivemoot agents \u2014 role instructions and repo work summaries").version(version).option("--github-token <token>", "GitHub personal access token (or set GITHUB_TOKEN env var)");
|
|
871
914
|
program.hook("preAction", () => {
|
|
872
915
|
const token = program.opts().githubToken;
|
|
873
916
|
if (token) {
|
|
874
917
|
setGhToken(token);
|
|
875
918
|
}
|
|
876
919
|
});
|
|
877
|
-
program.command("buzz").description("Get role instructions and repo work summary (omit --role for summary only)").option("--role <role>", "Role to assume (e.g. engineer, tech_lead)").option("--json", "Output as JSON").option("--limit <n>", "Max items per section", parseLimit).option("--repo <owner/repo>", "Target repository (default: detect from git)").action(buzzCommand);
|
|
920
|
+
program.command("buzz").description("Get role instructions and repo work summary (omit --role for summary only)").option("--role <role>", "Role to assume (e.g. engineer, tech_lead)").option("--json", "Output as JSON").option("--limit <n>", "Max items per section", parseLimit).option("--fetch-limit <n>", "Max issues/PRs to fetch from GitHub (default: 200)", parseLimit).option("--repo <owner/repo>", "Target repository (default: detect from git)").action(buzzCommand);
|
|
878
921
|
program.command("roles").description("List available roles from team config").option("--json", "Output as JSON").option("--repo <owner/repo>", "Target repository (default: detect from git)").action(rolesCommand);
|
|
879
922
|
program.command("init").description("Print a sample .github/hivemoot.yml template").action(initCommand);
|
|
880
923
|
program.exitOverride();
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/config/types.ts","../src/config/loader.ts","../src/github/client.ts","../src/github/repo.ts","../src/github/issues.ts","../src/github/pulls.ts","../src/github/user.ts","../src/summary/utils.ts","../src/summary/alerts.ts","../src/summary/builder.ts","../src/output/formatter.ts","../src/output/json.ts","../src/commands/buzz.ts","../src/commands/roles.ts","../src/commands/init.ts"],"sourcesContent":["import { Command, InvalidArgumentError } from \"commander\";\nimport { buzzCommand } from \"./commands/buzz.js\";\nimport { rolesCommand } from \"./commands/roles.js\";\nimport { initCommand } from \"./commands/init.js\";\nimport { CliError } from \"./config/types.js\";\nimport { setGhToken } from \"./github/client.js\";\n\nfunction parseLimit(value: string): number {\n const n = parseInt(value, 10);\n if (isNaN(n) || n <= 0) {\n throw new InvalidArgumentError(\"Must be a positive integer.\");\n }\n return n;\n}\n\nconst program = new Command();\n\nprogram\n .name(\"hivemoot\")\n .description(\"CLI for Hivemoot agents — role instructions and repo work summaries\")\n .version(\"0.1.0\")\n .option(\"--github-token <token>\", \"GitHub personal access token (or set GITHUB_TOKEN env var)\");\n\nprogram.hook(\"preAction\", () => {\n const token = program.opts().githubToken as string | undefined;\n if (token) {\n setGhToken(token);\n }\n});\n\nprogram\n .command(\"buzz\")\n .description(\"Get role instructions and repo work summary (omit --role for summary only)\")\n .option(\"--role <role>\", \"Role to assume (e.g. engineer, tech_lead)\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"--limit <n>\", \"Max items per section\", parseLimit)\n .option(\"--repo <owner/repo>\", \"Target repository (default: detect from git)\")\n .action(buzzCommand);\n\nprogram\n .command(\"roles\")\n .description(\"List available roles from team config\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"--repo <owner/repo>\", \"Target repository (default: detect from git)\")\n .action(rolesCommand);\n\nprogram\n .command(\"init\")\n .description(\"Print a sample .github/hivemoot.yml template\")\n .action(initCommand);\n\n// Global error handler\nprogram.exitOverride();\n\ntry {\n await program.parseAsync(process.argv);\n} catch (err) {\n if (err instanceof CliError) {\n // Check if parent command requested --json output\n const isJson = process.argv.includes(\"--json\");\n if (isJson) {\n console.log(JSON.stringify({ error: { code: err.code, message: err.message } }, null, 2));\n } else {\n console.error(`Error: ${err.message}`);\n }\n process.exit(err.exitCode);\n }\n\n // Commander exits for --help, --version, etc.\n if (err instanceof Error && \"exitCode\" in err) {\n const exitCode = (err as Error & { exitCode: number }).exitCode;\n process.exit(exitCode);\n }\n\n console.error(\"Unexpected error:\", err);\n process.exit(1);\n}\n","// ── YAML Config Types ──────────────────────────────────────────────\n\nexport interface RoleConfig {\n description: string;\n instructions: string;\n}\n\nexport interface TeamConfig {\n name?: string;\n roles: Record<string, RoleConfig>;\n}\n\nexport interface HivemootConfig {\n version?: number;\n governance?: unknown;\n team?: TeamConfig;\n}\n\n// ── GitHub Data Types ──────────────────────────────────────────────\n\nexport interface GitHubIssue {\n number: number;\n title: string;\n labels: Array<{ name: string }>;\n assignees: Array<{ login: string }>;\n author: { login: string };\n comments: Array<{ createdAt: string }>;\n createdAt: string;\n updatedAt: string;\n url: string;\n}\n\nexport interface StatusCheck {\n context: string;\n state: string | undefined;\n conclusion: string | null;\n}\n\nexport interface PRReview {\n state: string;\n author: { login: string };\n}\n\nexport interface GitHubPR {\n number: number;\n title: string;\n state: string;\n author: { login: string };\n labels: Array<{ name: string }>;\n comments: Array<{ createdAt: string }>;\n reviews: PRReview[];\n createdAt: string;\n updatedAt: string;\n url: string;\n isDraft: boolean;\n reviewDecision: string;\n mergeable: string;\n statusCheckRollup: StatusCheck[] | null;\n closingIssuesReferences: Array<{ number: number }>;\n}\n\n// ── Repo Identity ──────────────────────────────────────────────────\n\nexport interface RepoRef {\n owner: string;\n repo: string;\n}\n\n// ── Summary Types ──────────────────────────────────────────────────\n\nexport interface SummaryItem {\n number: number;\n title: string;\n tags: string[];\n author: string;\n // Common fields\n comments: number;\n age: string; // \"today\" | \"1 day old\" | \"3 days old\"\n // Issue-specific\n assigned?: string; // comma-separated logins, or undefined (= unassigned)\n competingPRs?: number; // only on implement items with competing PRs\n // PR-specific\n status?: string; // \"waiting\" | \"approved\" | \"changes-requested\" | \"draft\"\n checks?: string | null; // \"passing\" | \"failing\" | \"pending\" | null\n mergeable?: string | null; // \"clean\" | \"conflicts\" | null\n approvals?: number;\n}\n\nexport interface Alert {\n icon: string;\n message: string;\n}\n\nexport interface RepoSummary {\n repo: RepoRef;\n currentUser: string;\n driveDiscussion: SummaryItem[];\n driveImplementation: SummaryItem[];\n voteOn: SummaryItem[];\n discuss: SummaryItem[];\n implement: SummaryItem[];\n reviewPRs: SummaryItem[];\n addressFeedback: SummaryItem[];\n alerts: Alert[];\n}\n\n// ── CLI Options ────────────────────────────────────────────────────\n\nexport interface BuzzOptions {\n role?: string;\n json?: boolean;\n limit?: number;\n repo?: string;\n}\n\nexport interface RolesOptions {\n json?: boolean;\n repo?: string;\n}\n\n// ── Error Types ────────────────────────────────────────────────────\n\nexport type ErrorCode =\n | \"GH_NOT_FOUND\"\n | \"GH_NOT_AUTHENTICATED\"\n | \"NOT_GIT_REPO\"\n | \"CONFIG_NOT_FOUND\"\n | \"NO_TEAM_CONFIG\"\n | \"ROLE_NOT_FOUND\"\n | \"INVALID_CONFIG\"\n | \"RATE_LIMITED\"\n | \"GH_ERROR\";\n\nexport class CliError extends Error {\n constructor(\n message: string,\n public readonly code: ErrorCode,\n public readonly exitCode: number = 1,\n ) {\n super(message);\n this.name = \"CliError\";\n }\n}\n","import yaml from \"js-yaml\";\nimport { gh } from \"../github/client.js\";\nimport type { HivemootConfig, TeamConfig, RepoRef, RoleConfig } from \"./types.js\";\nimport { CliError } from \"./types.js\";\n\nconst ROLE_SLUG_RE = /^[a-z][a-z0-9_]{0,49}$/;\nconst MAX_DESCRIPTION_LENGTH = 500;\nconst MAX_INSTRUCTIONS_LENGTH = 10_000;\n\nfunction validateTeamConfig(raw: HivemootConfig): TeamConfig {\n if (!raw.team) {\n throw new CliError(\n \"No team config in .github/hivemoot.yml. Run: hivemoot init\",\n \"NO_TEAM_CONFIG\",\n 1,\n );\n }\n\n const { team } = raw;\n\n if (!team.roles || typeof team.roles !== \"object\" || Object.keys(team.roles).length === 0) {\n throw new CliError(\n \"Config error: team.roles must contain at least one role\",\n \"INVALID_CONFIG\",\n 1,\n );\n }\n\n const validatedRoles: Record<string, RoleConfig> = {};\n\n for (const [slug, role] of Object.entries(team.roles)) {\n if (!ROLE_SLUG_RE.test(slug)) {\n throw new CliError(\n `Config error: invalid role slug \"${slug}\" — must match /^[a-z][a-z0-9_]{0,49}$/`,\n \"INVALID_CONFIG\",\n 1,\n );\n }\n\n if (typeof role !== \"object\" || role === null) {\n throw new CliError(\n `Config error: role \"${slug}\" must be an object`,\n \"INVALID_CONFIG\",\n 1,\n );\n }\n\n const r = role as unknown as Record<string, unknown>;\n\n if (typeof r.description !== \"string\" || r.description.length === 0) {\n throw new CliError(\n `Config error: role \"${slug}\" is missing a description`,\n \"INVALID_CONFIG\",\n 1,\n );\n }\n\n if (r.description.length > MAX_DESCRIPTION_LENGTH) {\n throw new CliError(\n `Config error: role \"${slug}\" description exceeds ${MAX_DESCRIPTION_LENGTH} characters`,\n \"INVALID_CONFIG\",\n 1,\n );\n }\n\n if (typeof r.instructions !== \"string\" || r.instructions.length === 0) {\n throw new CliError(\n `Config error: role \"${slug}\" is missing instructions`,\n \"INVALID_CONFIG\",\n 1,\n );\n }\n\n if (r.instructions.length > MAX_INSTRUCTIONS_LENGTH) {\n throw new CliError(\n `Config error: role \"${slug}\" instructions exceeds ${MAX_INSTRUCTIONS_LENGTH} characters`,\n \"INVALID_CONFIG\",\n 1,\n );\n }\n\n validatedRoles[slug] = {\n description: r.description,\n instructions: r.instructions,\n };\n }\n\n return {\n name: typeof team.name === \"string\" ? team.name : undefined,\n roles: validatedRoles,\n };\n}\n\nexport async function loadTeamConfig(repo: RepoRef): Promise<TeamConfig> {\n let rawJson: string;\n\n try {\n rawJson = await gh([\n \"api\",\n `repos/${repo.owner}/${repo.repo}/contents/.github/hivemoot.yml`,\n ]);\n } catch (err) {\n if (err instanceof Error && /404|Not Found/i.test(err.message)) {\n throw new CliError(\n \"No .github/hivemoot.yml found. Run: hivemoot init\",\n \"CONFIG_NOT_FOUND\",\n 1,\n );\n }\n throw err;\n }\n\n let content: string;\n try {\n const parsed = JSON.parse(rawJson);\n content = Buffer.from(parsed.content, \"base64\").toString(\"utf-8\");\n } catch (err) {\n const detail = err instanceof Error ? `: ${err.message}` : \"\";\n throw new CliError(\n `Config error: failed to decode .github/hivemoot.yml content${detail}`,\n \"INVALID_CONFIG\",\n 1,\n );\n }\n\n let config: HivemootConfig;\n try {\n config = yaml.load(content, { schema: yaml.JSON_SCHEMA }) as HivemootConfig;\n } catch (err) {\n const detail = err instanceof Error ? `: ${err.message}` : \"\";\n throw new CliError(\n `Config error: invalid YAML in .github/hivemoot.yml${detail}`,\n \"INVALID_CONFIG\",\n 1,\n );\n }\n\n if (typeof config !== \"object\" || config === null) {\n throw new CliError(\n \"Config error: .github/hivemoot.yml must be a YAML object\",\n \"INVALID_CONFIG\",\n 1,\n );\n }\n\n return validateTeamConfig(config);\n}\n","import { execFile } from \"child_process\";\nimport { promisify } from \"util\";\nimport { CliError } from \"../config/types.js\";\n\nconst execFileAsync = promisify(execFile);\n\nlet ghToken: string | undefined;\n\n/** Set the GitHub token used for all subsequent `gh` calls. */\nexport function setGhToken(token: string): void {\n ghToken = token;\n}\n\n/**\n * Execute a `gh` CLI command and return stdout.\n * All GitHub I/O goes through this single function.\n */\nexport async function gh(args: string[]): Promise<string> {\n try {\n const opts: { timeout: number; env?: NodeJS.ProcessEnv } = {\n timeout: 30_000,\n };\n if (ghToken) {\n opts.env = { ...process.env, GH_TOKEN: ghToken };\n }\n const { stdout } = await execFileAsync(\"gh\", args, opts);\n return stdout.trim();\n } catch (err: unknown) {\n const error = err as NodeJS.ErrnoException & {\n stderr?: string;\n code?: string | number;\n };\n\n if (error.code === \"ENOENT\") {\n throw new CliError(\n \"gh CLI not found. Install: https://cli.github.com\",\n \"GH_NOT_FOUND\",\n 2,\n );\n }\n\n const stderr = error.stderr ?? error.message ?? \"\";\n\n if (/gh auth login|not logged in|authentication required/i.test(stderr)) {\n throw new CliError(\n \"Not authenticated. Pass --github-token <token>, set GITHUB_TOKEN, or run: gh auth login\",\n \"GH_NOT_AUTHENTICATED\",\n 2,\n );\n }\n\n if (/rate.?limit|API rate limit/i.test(stderr)) {\n throw new CliError(\n \"GitHub rate limited. Try again later.\",\n \"RATE_LIMITED\",\n 3,\n );\n }\n\n throw new CliError(stderr || \"gh command failed\", \"GH_ERROR\", 1);\n }\n}\n","import { CliError, type RepoRef } from \"../config/types.js\";\nimport { gh } from \"./client.js\";\n\nconst GITHUB_NAME_RE = /^[a-zA-Z0-9._-]+$/;\n\nexport async function resolveRepo(repoFlag?: string): Promise<RepoRef> {\n if (repoFlag) {\n const parts = repoFlag.split(\"/\");\n if (parts.length !== 2 || !parts[0] || !parts[1]) {\n throw new CliError(\n `Invalid repo format: \"${repoFlag}\". Expected OWNER/REPO`,\n \"GH_ERROR\",\n 1,\n );\n }\n if (!GITHUB_NAME_RE.test(parts[0]) || !GITHUB_NAME_RE.test(parts[1])) {\n throw new CliError(\n `Invalid repo name: \"${repoFlag}\". Owner and repo must match ${GITHUB_NAME_RE}`,\n \"GH_ERROR\",\n 1,\n );\n }\n return { owner: parts[0], repo: parts[1] };\n }\n\n try {\n const json = await gh([\"repo\", \"view\", \"--json\", \"owner,name\"]);\n let data: { owner?: { login?: string } | string; name?: string };\n try {\n data = JSON.parse(json);\n } catch {\n throw new CliError(\n \"Failed to parse repo info from gh CLI. Use --repo OWNER/REPO\",\n \"GH_ERROR\",\n 1,\n );\n }\n // gh returns owner as an object { login: \"...\" } not a plain string\n const owner =\n typeof data.owner === \"object\" && data.owner !== null\n ? data.owner.login\n : data.owner;\n const name = data.name;\n if (typeof owner !== \"string\" || !owner || typeof name !== \"string\" || !name) {\n throw new CliError(\n \"Could not detect repo owner/name. Use --repo OWNER/REPO\",\n \"NOT_GIT_REPO\",\n 2,\n );\n }\n return { owner, repo: name };\n } catch (err) {\n if (err instanceof CliError) {\n throw err;\n }\n throw new CliError(\n \"Not in a git repository. Use --repo OWNER/REPO\",\n \"NOT_GIT_REPO\",\n 2,\n );\n }\n}\n","import type { GitHubIssue, RepoRef } from \"../config/types.js\";\nimport { CliError } from \"../config/types.js\";\nimport { gh } from \"./client.js\";\n\nexport async function fetchIssues(repo: RepoRef): Promise<GitHubIssue[]> {\n const json = await gh([\n \"issue\",\n \"list\",\n \"-R\",\n `${repo.owner}/${repo.repo}`,\n \"--state\",\n \"open\",\n \"--json\",\n \"number,title,labels,assignees,author,comments,createdAt,updatedAt,url\",\n \"--limit\",\n \"200\",\n ]);\n let parsed: unknown;\n try {\n parsed = JSON.parse(json);\n } catch {\n throw new CliError(\n \"Failed to parse issues response from gh CLI\",\n \"GH_ERROR\",\n 1,\n );\n }\n if (!Array.isArray(parsed)) {\n throw new CliError(\n \"Unexpected issues response format from gh CLI\",\n \"GH_ERROR\",\n 1,\n );\n }\n return parsed as GitHubIssue[];\n}\n","import type { GitHubPR, RepoRef } from \"../config/types.js\";\nimport { CliError } from \"../config/types.js\";\nimport { gh } from \"./client.js\";\n\nexport async function fetchPulls(repo: RepoRef): Promise<GitHubPR[]> {\n const json = await gh([\n \"pr\",\n \"list\",\n \"-R\",\n `${repo.owner}/${repo.repo}`,\n \"--state\",\n \"open\",\n \"--json\",\n \"number,title,state,author,labels,comments,reviews,createdAt,updatedAt,url,isDraft,reviewDecision,mergeable,statusCheckRollup,closingIssuesReferences\",\n \"--limit\",\n \"200\",\n ]);\n let parsed: unknown;\n try {\n parsed = JSON.parse(json);\n } catch {\n throw new CliError(\n \"Failed to parse pull requests response from gh CLI\",\n \"GH_ERROR\",\n 1,\n );\n }\n if (!Array.isArray(parsed)) {\n throw new CliError(\n \"Unexpected pull requests response format from gh CLI\",\n \"GH_ERROR\",\n 1,\n );\n }\n return parsed as GitHubPR[];\n}\n","import { gh } from \"./client.js\";\nimport { CliError } from \"../config/types.js\";\n\n/**\n * Return the login of the currently authenticated GitHub user.\n */\nexport async function fetchCurrentUser(): Promise<string> {\n const login = await gh([\"api\", \"user\", \"--jq\", \".login\"]);\n if (!login) {\n throw new CliError(\n \"Could not determine GitHub username. Pass --github-token <token>, set GITHUB_TOKEN, or run: gh auth login\",\n \"GH_NOT_AUTHENTICATED\",\n 2,\n );\n }\n return login;\n}\n","import type { GitHubPR } from \"../config/types.js\";\n\nexport function hasLabel(labels: Array<{ name: string }>, keyword: string): boolean {\n return labels.some((l) =>\n l.name.toLowerCase().split(/[:\\-_]/).some((seg) => seg === keyword),\n );\n}\n\nexport function hasExactLabel(labels: Array<{ name: string }>, labelName: string): boolean {\n return labels.some((l) => l.name.toLowerCase() === labelName.toLowerCase());\n}\n\nexport function daysSince(dateStr: string, now: Date): number {\n const diff = now.getTime() - new Date(dateStr).getTime();\n return Math.max(0, Math.floor(diff / (1000 * 60 * 60 * 24)));\n}\n\nexport function hasCIFailure(pr: GitHubPR): boolean {\n if (!pr.statusCheckRollup) return false;\n return pr.statusCheckRollup.some((check) => {\n const conclusion = check.conclusion?.toUpperCase();\n const state = check.state?.toUpperCase();\n return conclusion === \"FAILURE\" || state === \"FAILURE\";\n });\n}\n\n/**\n * Summarize all status checks into a single label.\n * Returns null when there are no checks to report.\n */\nexport function checkStatus(pr: GitHubPR): string | null {\n if (!pr.statusCheckRollup || pr.statusCheckRollup.length === 0) return null;\n\n const hasFailing = hasCIFailure(pr);\n if (hasFailing) return \"checks failing\";\n\n const hasPending = pr.statusCheckRollup.some((c) => {\n const s = c.state?.toUpperCase();\n return s === \"PENDING\" || s === \"QUEUED\" || s === \"IN_PROGRESS\";\n });\n if (hasPending) return \"checks pending\";\n\n return \"checks passing\";\n}\n\n/**\n * Return a merge-conflict label, or null if no conflict info.\n */\nexport function mergeStatus(pr: GitHubPR): string | null {\n if (pr.mergeable === \"CONFLICTING\") return \"has conflicts\";\n if (pr.mergeable === \"MERGEABLE\") return \"no conflicts\";\n return null;\n}\n\n/**\n * Count unique approvals (latest review per author).\n */\nexport function approvalCount(pr: GitHubPR): number {\n if (!pr.reviews || pr.reviews.length === 0) return 0;\n const latestByAuthor = new Map<string, string>();\n for (const review of pr.reviews) {\n latestByAuthor.set(review.author.login, review.state);\n }\n let count = 0;\n for (const state of latestByAuthor.values()) {\n if (state === \"APPROVED\") count++;\n }\n return count;\n}\n","import type { GitHubIssue, GitHubPR, Alert } from \"../config/types.js\";\nimport { hasLabel, hasExactLabel, daysSince, hasCIFailure } from \"./utils.js\";\n\nconst STALE_DISCUSSION_DAYS = 3;\nconst PR_WAITING_REVIEW_DAYS = 2;\n\nfunction lastCommentDate(issue: GitHubIssue): string | null {\n if (issue.comments.length === 0) return null;\n return issue.comments.reduce((latest, c) =>\n c.createdAt > latest.createdAt ? c : latest,\n ).createdAt;\n}\n\nexport function generateAlerts(\n issues: GitHubIssue[],\n prs: GitHubPR[],\n now: Date = new Date(),\n): Alert[] {\n const alerts: Alert[] = [];\n\n // Stale discussions: discuss-labeled issues with no recent comments\n for (const issue of issues) {\n if (!hasLabel(issue.labels, \"discuss\") && !hasExactLabel(issue.labels, \"phase:discussion\")) continue;\n const lastComment = lastCommentDate(issue);\n const referenceDate = lastComment ?? issue.createdAt;\n const days = daysSince(referenceDate, now);\n if (days >= STALE_DISCUSSION_DAYS) {\n alerts.push({\n icon: \"\\u26a0\\ufe0f\",\n message: `#${issue.number} in discussion ${days} days, no recent comments`,\n });\n }\n }\n\n // Issues needing human attention\n for (const issue of issues) {\n if (hasExactLabel(issue.labels, \"needs:human\")) {\n alerts.push({\n icon: \"\\ud83d\\uded1\",\n message: `#${issue.number} needs human attention`,\n });\n }\n }\n\n // Only PRs in the governance intake (with \"implementation\" label) generate attention items\n const intakePRs = prs.filter((pr) => hasExactLabel(pr.labels, \"implementation\"));\n\n // PRs waiting on review too long (skip approved/changes-requested/drafts)\n for (const pr of intakePRs) {\n if (pr.isDraft) continue;\n if (pr.reviewDecision === \"APPROVED\" || pr.reviewDecision === \"CHANGES_REQUESTED\") continue;\n const days = daysSince(pr.createdAt, now);\n if (days >= PR_WAITING_REVIEW_DAYS) {\n alerts.push({\n icon: \"\\u26a0\\ufe0f\",\n message: `PR #${pr.number} waiting on review ${days} days`,\n });\n }\n }\n\n // CI failures on non-draft PRs\n for (const pr of intakePRs) {\n if (pr.isDraft) continue;\n if (hasCIFailure(pr)) {\n alerts.push({\n icon: \"\\u26a0\\ufe0f\",\n message: `PR #${pr.number} has CI failures`,\n });\n }\n }\n\n return alerts;\n}\n","import type {\n GitHubIssue,\n GitHubPR,\n RepoRef,\n RepoSummary,\n SummaryItem,\n} from \"../config/types.js\";\nimport { generateAlerts } from \"./alerts.js\";\nimport { hasLabel, hasExactLabel, daysSince, hasCIFailure, checkStatus, mergeStatus, approvalCount } from \"./utils.js\";\n\nfunction timeAgo(dateStr: string, now: Date): string {\n const days = daysSince(dateStr, now);\n if (days === 0) return \"today\";\n if (days === 1) return \"1 day old\";\n return `${days} days old`;\n}\n\n/** Map verbose check labels to compact values for structured output. */\nfunction compactChecks(raw: string | null): string | null {\n if (raw === null) return null;\n if (raw === \"checks failing\") return \"failing\";\n if (raw === \"checks pending\") return \"pending\";\n if (raw === \"checks passing\") return \"passing\";\n return raw;\n}\n\n/** Map verbose merge labels to compact values for structured output. */\nfunction compactMergeable(raw: string | null): string | null {\n if (raw === null) return null;\n if (raw === \"has conflicts\") return \"conflicts\";\n if (raw === \"no conflicts\") return \"clean\";\n return raw;\n}\n\nfunction classifyIssue(\n issue: GitHubIssue,\n now: Date,\n): { bucket: \"voteOn\" | \"discuss\" | \"implement\" | \"needsHuman\"; item: SummaryItem } {\n const age = timeAgo(issue.createdAt, now);\n const assigned =\n issue.assignees.length > 0\n ? issue.assignees.map((a) => a.login).join(\", \")\n : undefined;\n\n const tags = issue.labels.map((l) => l.name);\n const author = issue.author.login;\n const comments = issue.comments.length;\n\n const base: SummaryItem = {\n number: issue.number,\n title: issue.title,\n tags,\n author,\n comments,\n age,\n };\n\n // Issues needing human attention are excluded from all actionable buckets\n if (hasExactLabel(issue.labels, \"needs:human\")) {\n return {\n bucket: \"needsHuman\",\n item: { ...base, assigned },\n };\n }\n\n // Bot governance labels (exact match)\n if (hasExactLabel(issue.labels, \"phase:voting\") || hasExactLabel(issue.labels, \"phase:extended-voting\")) {\n return { bucket: \"voteOn\", item: base };\n }\n if (hasExactLabel(issue.labels, \"phase:discussion\")) {\n return { bucket: \"discuss\", item: base };\n }\n if (hasExactLabel(issue.labels, \"phase:ready-to-implement\")) {\n return { bucket: \"implement\", item: { ...base, assigned } };\n }\n\n // Keyword fallback (repos without the bot)\n if (hasLabel(issue.labels, \"vote\")) {\n return { bucket: \"voteOn\", item: base };\n }\n if (hasLabel(issue.labels, \"discuss\")) {\n return { bucket: \"discuss\", item: base };\n }\n\n return {\n bucket: \"implement\",\n item: { ...base, assigned },\n };\n}\n\nfunction classifyPR(\n pr: GitHubPR,\n now: Date,\n): { bucket: \"reviewPRs\" | \"addressFeedback\"; item: SummaryItem } {\n const age = timeAgo(pr.createdAt, now);\n const tags = pr.labels.map((l) => l.name);\n const author = pr.author.login;\n const comments = pr.comments.length;\n const ciFailing = hasCIFailure(pr);\n const checks = compactChecks(checkStatus(pr));\n const merge = compactMergeable(mergeStatus(pr));\n const approvals = approvalCount(pr);\n\n if (pr.isDraft || ciFailing || pr.reviewDecision === \"CHANGES_REQUESTED\") {\n let status: string;\n if (pr.isDraft) status = \"draft\";\n else if (pr.reviewDecision === \"CHANGES_REQUESTED\") status = \"changes-requested\";\n else status = \"waiting\";\n\n return {\n bucket: \"addressFeedback\",\n item: { number: pr.number, title: pr.title, tags, author, comments, age, status, checks, mergeable: merge, approvals },\n };\n }\n\n const status = pr.reviewDecision === \"APPROVED\" ? \"approved\" : \"waiting\";\n\n return {\n bucket: \"reviewPRs\",\n item: { number: pr.number, title: pr.title, tags, author, comments, age, status, checks, mergeable: merge, approvals },\n };\n}\n\nfunction buildCompetitionMap(prs: GitHubPR[], currentUser: string): Map<number, number> {\n const map = new Map<number, number>();\n for (const pr of prs) {\n if (!hasLabel(pr.labels, \"implementation\")) continue;\n if (pr.author.login === currentUser) continue;\n for (const ref of pr.closingIssuesReferences) {\n map.set(ref.number, (map.get(ref.number) ?? 0) + 1);\n }\n }\n return map;\n}\n\nexport function buildSummary(\n repo: RepoRef,\n issues: GitHubIssue[],\n prs: GitHubPR[],\n currentUser: string,\n now: Date = new Date(),\n): RepoSummary {\n const voteOn: SummaryItem[] = [];\n const discuss: SummaryItem[] = [];\n const implement: SummaryItem[] = [];\n const reviewPRs: SummaryItem[] = [];\n const addressFeedback: SummaryItem[] = [];\n\n for (const issue of issues) {\n const { bucket, item } = classifyIssue(issue, now);\n if (bucket === \"voteOn\") voteOn.push(item);\n else if (bucket === \"discuss\") discuss.push(item);\n else if (bucket === \"implement\") implement.push(item);\n // \"needsHuman\" issues intentionally excluded from all buckets\n }\n\n // Annotate implement items with competing PR counts\n const competitionMap = buildCompetitionMap(prs, currentUser);\n for (const item of implement) {\n const count = competitionMap.get(item.number) ?? 0;\n if (count > 0) {\n item.competingPRs = count;\n }\n }\n\n for (const pr of prs) {\n const { bucket, item } = classifyPR(pr, now);\n if (bucket === \"reviewPRs\") reviewPRs.push(item);\n else addressFeedback.push(item);\n }\n\n const alerts = generateAlerts(issues, prs, now);\n\n // Extract authored items into \"drive\" buckets so the agent knows what it owns\n const driveDiscussion: SummaryItem[] = [];\n const driveImplementation: SummaryItem[] = [];\n\n const filteredDiscuss = discuss.filter((item) => {\n if (item.author === currentUser) { driveDiscussion.push(item); return false; }\n return true;\n });\n\n const filteredVoteOn = voteOn.filter((item) => {\n if (item.author === currentUser && item.tags.includes(\"phase:extended-voting\")) {\n driveDiscussion.push(item);\n return false;\n }\n return true;\n });\n\n const filteredReviewPRs = reviewPRs.filter((item) => {\n if (item.author === currentUser) { driveImplementation.push(item); return false; }\n return true;\n });\n\n const filteredAddressFeedback = addressFeedback.filter((item) => {\n if (item.author === currentUser) { driveImplementation.push(item); return false; }\n return true;\n });\n\n return {\n repo,\n currentUser,\n driveDiscussion,\n driveImplementation,\n voteOn: filteredVoteOn,\n discuss: filteredDiscuss,\n implement,\n reviewPRs: filteredReviewPRs,\n addressFeedback: filteredAddressFeedback,\n alerts,\n };\n}\n","import chalk from \"chalk\";\nimport type { RepoSummary, RoleConfig, SummaryItem, TeamConfig } from \"../config/types.js\";\n\nconst DIVIDER_WIDTH = 50;\n\n// Section types determine which metadata keys appear on the second line\ntype SectionType = \"vote\" | \"discuss\" | \"implement\" | \"reviewPRs\" | \"addressFeedback\" | \"driveDiscussion\" | \"driveImplementation\";\n\nfunction sectionDivider(title: string, count: number): string {\n const label = ` ${title} (${count}) `;\n const remaining = Math.max(0, DIVIDER_WIDTH - label.length - 2);\n return chalk.dim(\"──\") + chalk.bold(label) + chalk.dim(\"─\".repeat(remaining));\n}\n\nfunction formatTags(tags: string[]): string {\n if (tags.length === 0) return \"\";\n return \" \" + tags.map((t) => chalk.magenta(`[${t}]`)).join(\" \");\n}\n\nfunction kv(key: string, value: string | number): string {\n return `${key}: ${chalk.dim(String(value))}`;\n}\n\nfunction formatMeta(item: SummaryItem, sectionType: SectionType, currentUser: string): string {\n const isYou = item.author === currentUser;\n const authorVal = isYou ? chalk.green(`${item.author} (you)`) : chalk.dim(item.author);\n const parts: string[] = [`by: ${authorVal}`];\n\n if (sectionType === \"implement\") {\n parts.push(kv(\"assigned\", item.assigned ?? \"--\"));\n parts.push(kv(\"comments\", item.comments));\n parts.push(kv(\"age\", item.age));\n if (item.competingPRs !== undefined) {\n parts.push(kv(\"competing\", item.competingPRs));\n }\n } else if (sectionType === \"vote\" || sectionType === \"discuss\" || sectionType === \"driveDiscussion\") {\n parts.push(kv(\"comments\", item.comments));\n parts.push(kv(\"age\", item.age));\n } else {\n // PR sections: reviewPRs, addressFeedback, driveImplementation\n if (item.status !== undefined) parts.push(kv(\"status\", item.status));\n if (item.checks !== undefined && item.checks !== null) parts.push(kv(\"checks\", item.checks));\n if (item.mergeable !== undefined && item.mergeable !== null) parts.push(kv(\"merge\", item.mergeable));\n if (item.approvals !== undefined) parts.push(kv(\"approvals\", item.approvals));\n parts.push(kv(\"comments\", item.comments));\n parts.push(kv(\"age\", item.age));\n }\n\n return parts.join(\" \");\n}\n\nfunction formatItem(item: SummaryItem, currentUser: string, sectionType: SectionType): string {\n const isYou = item.author === currentUser;\n const prefix = isYou ? chalk.green(\"★\") : \" \";\n const num = chalk.cyan(`#${item.number}`);\n const tags = formatTags(item.tags);\n\n const titleLine = `${prefix} ${num} ${item.title}${tags}`;\n const metaLine = ` ${formatMeta(item, sectionType, currentUser)}`;\n\n return `${titleLine}\\n${metaLine}`;\n}\n\nfunction formatSection(\n title: string,\n items: SummaryItem[],\n currentUser: string,\n sectionType: SectionType,\n limit?: number,\n): string {\n if (items.length === 0) return \"\";\n\n const displayed = limit ? items.slice(0, limit) : items;\n const header = sectionDivider(title, items.length);\n const itemBlocks = displayed.map((item) => formatItem(item, currentUser, sectionType));\n\n const parts = [header, ...itemBlocks];\n\n if (limit && items.length > limit) {\n parts.push(chalk.dim(` ... and ${items.length - limit} more`));\n }\n\n return parts.join(\"\\n\\n\");\n}\n\nfunction formatSummaryBody(summary: RepoSummary, limit?: number): string {\n const u = summary.currentUser;\n const sections: string[] = [];\n\n // Attention items at the top\n if (summary.alerts.length > 0) {\n const alertLines = [\n sectionDivider(\"REQUIRES YOUR ATTENTION\", summary.alerts.length),\n ...summary.alerts.map((a) => ` ${a.icon} ${chalk.yellow(a.message)}`),\n ];\n sections.push(alertLines.join(\"\\n\"));\n }\n\n sections.push(\n ...[\n formatSection(\"DRIVE THE DISCUSSION\", summary.driveDiscussion, u, \"driveDiscussion\", limit),\n formatSection(\"DRIVE THE IMPLEMENTATION\", summary.driveImplementation, u, \"driveImplementation\", limit),\n formatSection(\"VOTE ON ISSUES\", summary.voteOn, u, \"vote\", limit),\n formatSection(\"DISCUSS ISSUES\", summary.discuss, u, \"discuss\", limit),\n formatSection(\"READY TO IMPLEMENT ISSUES\", summary.implement, u, \"implement\", limit),\n formatSection(\"REVIEW PRs\", summary.reviewPRs, u, \"reviewPRs\", limit),\n formatSection(\"ADDRESS FEEDBACK PRs\", summary.addressFeedback, u, \"addressFeedback\", limit),\n ].filter(Boolean),\n );\n\n if (sections.length === 0) {\n return chalk.dim(\" No open issues or PRs.\");\n }\n\n return sections.join(\"\\n\\n\");\n}\n\nexport function formatBuzz(\n roleName: string,\n role: RoleConfig,\n summary: RepoSummary,\n limit?: number,\n): string {\n const lines = [\n chalk.bold(`ROLE: ${roleName}`) + ` — ${role.description}`,\n \"\",\n chalk.bold(\"INSTRUCTIONS:\"),\n role.instructions.trimEnd(),\n \"\",\n `You are working on ${chalk.bold(`${summary.repo.owner}/${summary.repo.repo}`)}, logged in as ${chalk.green(summary.currentUser)}`,\n \"\",\n formatSummaryBody(summary, limit),\n ];\n\n return lines.join(\"\\n\");\n}\n\nexport function formatStatus(summary: RepoSummary, limit?: number): string {\n const lines = [\n `You are working on ${chalk.bold(`${summary.repo.owner}/${summary.repo.repo}`)}, logged in as ${chalk.green(summary.currentUser)}`,\n \"\",\n formatSummaryBody(summary, limit),\n ];\n\n return lines.join(\"\\n\");\n}\n\nexport function formatRoles(teamConfig: TeamConfig, repoFullName: string): string {\n const nameLabel = teamConfig.name ? ` (${teamConfig.name})` : \"\";\n const lines = [\n chalk.bold(`ROLES — ${repoFullName}${nameLabel}`),\n \"\",\n ];\n\n const slugs = Object.keys(teamConfig.roles);\n const maxLen = Math.max(...slugs.map((s) => s.length));\n\n for (const slug of slugs) {\n const role = teamConfig.roles[slug];\n const padded = slug.padEnd(maxLen + 2);\n lines.push(` ${chalk.cyan(padded)}${role.description}`);\n }\n\n return lines.join(\"\\n\");\n}\n","import type { RepoSummary, RoleConfig, TeamConfig } from \"../config/types.js\";\n\nexport function jsonBuzz(\n roleName: string,\n role: RoleConfig,\n summary: RepoSummary,\n): string {\n return JSON.stringify(\n {\n role: {\n name: roleName,\n description: role.description,\n instructions: role.instructions,\n },\n summary: {\n repo: `${summary.repo.owner}/${summary.repo.repo}`,\n currentUser: summary.currentUser,\n driveDiscussion: summary.driveDiscussion,\n driveImplementation: summary.driveImplementation,\n voteOn: summary.voteOn,\n discuss: summary.discuss,\n implement: summary.implement,\n reviewPRs: summary.reviewPRs,\n addressFeedback: summary.addressFeedback,\n alerts: summary.alerts,\n },\n },\n null,\n 2,\n );\n}\n\nexport function jsonStatus(summary: RepoSummary): string {\n return JSON.stringify(\n {\n repo: `${summary.repo.owner}/${summary.repo.repo}`,\n currentUser: summary.currentUser,\n driveDiscussion: summary.driveDiscussion,\n driveImplementation: summary.driveImplementation,\n voteOn: summary.voteOn,\n discuss: summary.discuss,\n implement: summary.implement,\n reviewPRs: summary.reviewPRs,\n addressFeedback: summary.addressFeedback,\n alerts: summary.alerts,\n },\n null,\n 2,\n );\n}\n\nexport function jsonRoles(teamConfig: TeamConfig): string {\n const roles = Object.entries(teamConfig.roles).map(([slug, role]) => ({\n name: slug,\n description: role.description,\n }));\n\n return JSON.stringify({ roles }, null, 2);\n}\n","import { CliError, type BuzzOptions } from \"../config/types.js\";\nimport { loadTeamConfig } from \"../config/loader.js\";\nimport { resolveRepo } from \"../github/repo.js\";\nimport { fetchIssues } from \"../github/issues.js\";\nimport { fetchPulls } from \"../github/pulls.js\";\nimport { fetchCurrentUser } from \"../github/user.js\";\nimport { buildSummary } from \"../summary/builder.js\";\nimport { formatBuzz, formatStatus } from \"../output/formatter.js\";\nimport { jsonBuzz, jsonStatus } from \"../output/json.js\";\n\nexport async function buzzCommand(options: BuzzOptions): Promise<void> {\n const repo = await resolveRepo(options.repo);\n\n const [issues, prs, currentUser] = await Promise.all([\n fetchIssues(repo),\n fetchPulls(repo),\n fetchCurrentUser(),\n ]);\n\n const summary = buildSummary(repo, issues, prs, currentUser);\n\n if (options.role) {\n const teamConfig = await loadTeamConfig(repo);\n if (!Object.hasOwn(teamConfig.roles, options.role)) {\n const available = Object.keys(teamConfig.roles).join(\", \");\n throw new CliError(\n `Role '${options.role}' not found. Available: ${available}. Run: hivemoot roles`,\n \"ROLE_NOT_FOUND\",\n 1,\n );\n }\n const roleConfig = teamConfig.roles[options.role];\n\n if (options.json) {\n console.log(jsonBuzz(options.role, roleConfig, summary));\n } else {\n console.log(formatBuzz(options.role, roleConfig, summary, options.limit));\n }\n } else {\n if (options.json) {\n console.log(jsonStatus(summary));\n } else {\n console.log(formatStatus(summary, options.limit));\n }\n }\n}\n","import type { RolesOptions } from \"../config/types.js\";\nimport { loadTeamConfig } from \"../config/loader.js\";\nimport { resolveRepo } from \"../github/repo.js\";\nimport { formatRoles } from \"../output/formatter.js\";\nimport { jsonRoles } from \"../output/json.js\";\n\nexport async function rolesCommand(options: RolesOptions): Promise<void> {\n const repo = await resolveRepo(options.repo);\n const teamConfig = await loadTeamConfig(repo);\n\n if (options.json) {\n console.log(jsonRoles(teamConfig));\n } else {\n console.log(formatRoles(teamConfig, `${repo.owner}/${repo.repo}`));\n }\n}\n","export async function initCommand(): Promise<void> {\n const template = `# Hivemoot team configuration\n# Place this file at .github/hivemoot.yml in your repository.\n#\n# Roles define personas (who the agent is), not workflow.\n# Workflow details belong in .agent/skills/.\n\nteam:\n roles:\n pm:\n description: \"Product manager focused on user value and clarity\"\n instructions: |\n You think from the user's perspective.\n Evaluate ideas by the problem they solve and who benefits.\n Push for clear requirements and well-scoped proposals.\n Ask \"why does this matter?\" before \"how do we build it?\"\n\n engineer:\n description: \"Software engineer focused on clean implementation\"\n instructions: |\n You care about code quality, patterns, and maintainability.\n Favor simple, proven approaches over clever solutions.\n Write clean code with good test coverage.\n Build on existing conventions in the codebase.\n\n architect:\n description: \"Architect focused on system design and long-term health\"\n instructions: |\n You think about how pieces fit together.\n Evaluate proposals for scalability, consistency, and technical debt.\n Guard the system's boundaries and abstractions.\n Push back when short-term wins create long-term problems.\n\n qa:\n description: \"QA engineer focused on reliability and edge cases\"\n instructions: |\n You think about what can go wrong.\n Find edge cases, race conditions, and failure modes others miss.\n Push for thorough error handling and defensive design.\n Ask \"what happens when this fails?\" about everything.\n`;\n\n console.log(template);\n}\n"],"mappings":"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","names":["status"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/config/types.ts","../src/config/loader.ts","../src/github/client.ts","../src/github/repo.ts","../src/github/issues.ts","../src/github/pulls.ts","../src/github/user.ts","../src/summary/utils.ts","../src/summary/alerts.ts","../src/summary/builder.ts","../src/output/formatter.ts","../src/output/json.ts","../src/commands/buzz.ts","../src/commands/roles.ts","../src/commands/init.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\nimport { Command, InvalidArgumentError } from \"commander\";\nimport { buzzCommand } from \"./commands/buzz.js\";\nimport { rolesCommand } from \"./commands/roles.js\";\nimport { initCommand } from \"./commands/init.js\";\nimport { CliError } from \"./config/types.js\";\nimport { setGhToken } from \"./github/client.js\";\n\nconst require = createRequire(import.meta.url);\nconst { version } = require(\"../package.json\") as { version: string };\n\nfunction parseLimit(value: string): number {\n const n = parseInt(value, 10);\n if (isNaN(n) || n <= 0) {\n throw new InvalidArgumentError(\"Must be a positive integer.\");\n }\n return n;\n}\n\nconst program = new Command();\n\nprogram\n .name(\"hivemoot\")\n .description(\"CLI for Hivemoot agents — role instructions and repo work summaries\")\n .version(version)\n .option(\"--github-token <token>\", \"GitHub personal access token (or set GITHUB_TOKEN env var)\");\n\nprogram.hook(\"preAction\", () => {\n const token = program.opts().githubToken as string | undefined;\n if (token) {\n setGhToken(token);\n }\n});\n\nprogram\n .command(\"buzz\")\n .description(\"Get role instructions and repo work summary (omit --role for summary only)\")\n .option(\"--role <role>\", \"Role to assume (e.g. engineer, tech_lead)\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"--limit <n>\", \"Max items per section\", parseLimit)\n .option(\"--fetch-limit <n>\", \"Max issues/PRs to fetch from GitHub (default: 200)\", parseLimit)\n .option(\"--repo <owner/repo>\", \"Target repository (default: detect from git)\")\n .action(buzzCommand);\n\nprogram\n .command(\"roles\")\n .description(\"List available roles from team config\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"--repo <owner/repo>\", \"Target repository (default: detect from git)\")\n .action(rolesCommand);\n\nprogram\n .command(\"init\")\n .description(\"Print a sample .github/hivemoot.yml template\")\n .action(initCommand);\n\n// Global error handler\nprogram.exitOverride();\n\ntry {\n await program.parseAsync(process.argv);\n} catch (err) {\n if (err instanceof CliError) {\n // Check if parent command requested --json output\n const isJson = process.argv.includes(\"--json\");\n if (isJson) {\n console.log(JSON.stringify({ error: { code: err.code, message: err.message } }, null, 2));\n } else {\n console.error(`Error: ${err.message}`);\n }\n process.exit(err.exitCode);\n }\n\n // Commander exits for --help, --version, etc.\n if (err instanceof Error && \"exitCode\" in err) {\n const exitCode = (err as Error & { exitCode: number }).exitCode;\n process.exit(exitCode);\n }\n\n console.error(\"Unexpected error:\", err);\n process.exit(1);\n}\n","// ── YAML Config Types ──────────────────────────────────────────────\n\nexport interface RoleConfig {\n description: string;\n instructions: string;\n}\n\nexport interface TeamConfig {\n name?: string;\n roles: Record<string, RoleConfig>;\n}\n\nexport interface HivemootConfig {\n version?: number;\n governance?: unknown;\n team?: TeamConfig;\n}\n\n// ── GitHub Data Types ──────────────────────────────────────────────\n\nexport interface GitHubIssue {\n number: number;\n title: string;\n labels: Array<{ name: string }>;\n assignees: Array<{ login: string }>;\n author: { login: string } | null;\n comments: Array<{ createdAt: string }>;\n createdAt: string;\n updatedAt: string;\n url: string;\n}\n\nexport interface StatusCheck {\n context: string;\n state: string | undefined;\n conclusion: string | null;\n}\n\nexport interface PRReview {\n state: string;\n author: { login: string } | null;\n}\n\nexport interface GitHubPR {\n number: number;\n title: string;\n state: string;\n author: { login: string } | null;\n labels: Array<{ name: string }>;\n comments: Array<{ createdAt: string }>;\n reviews: PRReview[];\n createdAt: string;\n updatedAt: string;\n url: string;\n isDraft: boolean;\n reviewDecision: string;\n mergeable: string;\n statusCheckRollup: StatusCheck[] | null;\n closingIssuesReferences: Array<{ number: number }>;\n}\n\n// ── Repo Identity ──────────────────────────────────────────────────\n\nexport interface RepoRef {\n owner: string;\n repo: string;\n}\n\n// ── Summary Types ──────────────────────────────────────────────────\n\nexport interface ReviewSummary {\n approvals: number;\n changesRequested: number;\n}\n\nexport interface SummaryItem {\n number: number;\n title: string;\n tags: string[];\n author: string;\n // Common fields\n comments: number;\n age: string; // \"just now\" | \"5 minutes ago\" | \"2 hours ago\" | \"3 days ago\"\n // Issue-specific\n assigned?: string; // comma-separated logins, or undefined (= unassigned)\n competingPRs?: number; // only on implement items with competing PRs\n // PR-specific\n status?: string; // \"waiting\" | \"approved\" | \"changes-requested\" | \"draft\"\n checks?: string | null; // \"passing\" | \"failing\" | \"pending\" | null\n mergeable?: string | null; // \"clean\" | \"conflicts\" | null\n review?: ReviewSummary;\n}\n\nexport interface Alert {\n icon: string;\n message: string;\n}\n\nexport interface RepoSummary {\n repo: RepoRef;\n currentUser: string;\n driveDiscussion: SummaryItem[];\n driveImplementation: SummaryItem[];\n voteOn: SummaryItem[];\n discuss: SummaryItem[];\n implement: SummaryItem[];\n reviewPRs: SummaryItem[];\n addressFeedback: SummaryItem[];\n alerts: Alert[];\n notes: string[];\n}\n\n// ── CLI Options ────────────────────────────────────────────────────\n\nexport interface BuzzOptions {\n role?: string;\n json?: boolean;\n limit?: number;\n fetchLimit?: number;\n repo?: string;\n}\n\nexport interface RolesOptions {\n json?: boolean;\n repo?: string;\n}\n\n// ── Error Types ────────────────────────────────────────────────────\n\nexport type ErrorCode =\n | \"GH_NOT_FOUND\"\n | \"GH_NOT_AUTHENTICATED\"\n | \"NOT_GIT_REPO\"\n | \"CONFIG_NOT_FOUND\"\n | \"NO_TEAM_CONFIG\"\n | \"ROLE_NOT_FOUND\"\n | \"INVALID_CONFIG\"\n | \"RATE_LIMITED\"\n | \"GH_ERROR\";\n\nexport class CliError extends Error {\n constructor(\n message: string,\n public readonly code: ErrorCode,\n public readonly exitCode: number = 1,\n ) {\n super(message);\n this.name = \"CliError\";\n }\n}\n","import yaml from \"js-yaml\";\nimport { gh } from \"../github/client.js\";\nimport type { HivemootConfig, TeamConfig, RepoRef, RoleConfig } from \"./types.js\";\nimport { CliError } from \"./types.js\";\n\nconst ROLE_SLUG_RE = /^[a-z][a-z0-9_]{0,49}$/;\nconst MAX_DESCRIPTION_LENGTH = 500;\nconst MAX_INSTRUCTIONS_LENGTH = 10_000;\n\nfunction validateTeamConfig(raw: HivemootConfig): TeamConfig {\n if (!raw.team) {\n throw new CliError(\n \"No team config in .github/hivemoot.yml. Run: hivemoot init\",\n \"NO_TEAM_CONFIG\",\n 1,\n );\n }\n\n const { team } = raw;\n\n if (!team.roles || typeof team.roles !== \"object\" || Object.keys(team.roles).length === 0) {\n throw new CliError(\n \"Config error: team.roles must contain at least one role\",\n \"INVALID_CONFIG\",\n 1,\n );\n }\n\n const validatedRoles: Record<string, RoleConfig> = {};\n\n for (const [slug, role] of Object.entries(team.roles)) {\n if (!ROLE_SLUG_RE.test(slug)) {\n throw new CliError(\n `Config error: invalid role slug \"${slug}\" — must match /^[a-z][a-z0-9_]{0,49}$/`,\n \"INVALID_CONFIG\",\n 1,\n );\n }\n\n if (typeof role !== \"object\" || role === null) {\n throw new CliError(\n `Config error: role \"${slug}\" must be an object`,\n \"INVALID_CONFIG\",\n 1,\n );\n }\n\n const r = role as unknown as Record<string, unknown>;\n\n if (typeof r.description !== \"string\" || r.description.length === 0) {\n throw new CliError(\n `Config error: role \"${slug}\" is missing a description`,\n \"INVALID_CONFIG\",\n 1,\n );\n }\n\n if (r.description.length > MAX_DESCRIPTION_LENGTH) {\n throw new CliError(\n `Config error: role \"${slug}\" description exceeds ${MAX_DESCRIPTION_LENGTH} characters`,\n \"INVALID_CONFIG\",\n 1,\n );\n }\n\n if (typeof r.instructions !== \"string\" || r.instructions.length === 0) {\n throw new CliError(\n `Config error: role \"${slug}\" is missing instructions`,\n \"INVALID_CONFIG\",\n 1,\n );\n }\n\n if (r.instructions.length > MAX_INSTRUCTIONS_LENGTH) {\n throw new CliError(\n `Config error: role \"${slug}\" instructions exceeds ${MAX_INSTRUCTIONS_LENGTH} characters`,\n \"INVALID_CONFIG\",\n 1,\n );\n }\n\n validatedRoles[slug] = {\n description: r.description,\n instructions: r.instructions,\n };\n }\n\n return {\n name: typeof team.name === \"string\" ? team.name : undefined,\n roles: validatedRoles,\n };\n}\n\nexport async function loadTeamConfig(repo: RepoRef): Promise<TeamConfig> {\n let rawJson: string;\n\n try {\n rawJson = await gh([\n \"api\",\n `repos/${repo.owner}/${repo.repo}/contents/.github/hivemoot.yml`,\n ]);\n } catch (err) {\n if (err instanceof Error && /404|Not Found/i.test(err.message)) {\n throw new CliError(\n \"No .github/hivemoot.yml found. Run: hivemoot init\",\n \"CONFIG_NOT_FOUND\",\n 1,\n );\n }\n throw err;\n }\n\n let content: string;\n try {\n const parsed = JSON.parse(rawJson);\n content = Buffer.from(parsed.content, \"base64\").toString(\"utf-8\");\n } catch (err) {\n const detail = err instanceof Error ? `: ${err.message}` : \"\";\n throw new CliError(\n `Config error: failed to decode .github/hivemoot.yml content${detail}`,\n \"INVALID_CONFIG\",\n 1,\n );\n }\n\n let config: HivemootConfig;\n try {\n config = yaml.load(content, { schema: yaml.JSON_SCHEMA }) as HivemootConfig;\n } catch (err) {\n const detail = err instanceof Error ? `: ${err.message}` : \"\";\n throw new CliError(\n `Config error: invalid YAML in .github/hivemoot.yml${detail}`,\n \"INVALID_CONFIG\",\n 1,\n );\n }\n\n if (typeof config !== \"object\" || config === null) {\n throw new CliError(\n \"Config error: .github/hivemoot.yml must be a YAML object\",\n \"INVALID_CONFIG\",\n 1,\n );\n }\n\n return validateTeamConfig(config);\n}\n","import { execFile } from \"child_process\";\nimport { promisify } from \"util\";\nimport { CliError } from \"../config/types.js\";\n\nconst execFileAsync = promisify(execFile);\n\nlet ghToken: string | undefined;\n\n/** Set the GitHub token used for all subsequent `gh` calls. */\nexport function setGhToken(token: string): void {\n ghToken = token;\n}\n\n/**\n * Execute a `gh` CLI command and return stdout.\n * All GitHub I/O goes through this single function.\n */\nexport async function gh(args: string[]): Promise<string> {\n try {\n const opts: { timeout: number; env?: NodeJS.ProcessEnv } = {\n timeout: 30_000,\n };\n if (ghToken) {\n opts.env = { ...process.env, GH_TOKEN: ghToken };\n }\n const { stdout } = await execFileAsync(\"gh\", args, opts);\n return stdout.trim();\n } catch (err: unknown) {\n const error = err as NodeJS.ErrnoException & {\n stderr?: string;\n code?: string | number;\n };\n\n if (error.code === \"ENOENT\") {\n throw new CliError(\n \"gh CLI not found. Install: https://cli.github.com\",\n \"GH_NOT_FOUND\",\n 2,\n );\n }\n\n const stderr = error.stderr ?? error.message ?? \"\";\n\n if (/gh auth login|not logged in|authentication required/i.test(stderr)) {\n throw new CliError(\n \"Not authenticated. Pass --github-token <token>, set GITHUB_TOKEN, or run: gh auth login\",\n \"GH_NOT_AUTHENTICATED\",\n 2,\n );\n }\n\n if (/rate.?limit|API rate limit/i.test(stderr)) {\n throw new CliError(\n \"GitHub rate limited. Try again later.\",\n \"RATE_LIMITED\",\n 3,\n );\n }\n\n throw new CliError(stderr || \"gh command failed\", \"GH_ERROR\", 1);\n }\n}\n","import { CliError, type RepoRef } from \"../config/types.js\";\nimport { gh } from \"./client.js\";\n\nconst GITHUB_NAME_RE = /^[a-zA-Z0-9._-]+$/;\n\nexport async function resolveRepo(repoFlag?: string): Promise<RepoRef> {\n if (repoFlag) {\n const parts = repoFlag.split(\"/\");\n if (parts.length !== 2 || !parts[0] || !parts[1]) {\n throw new CliError(\n `Invalid repo format: \"${repoFlag}\". Expected OWNER/REPO`,\n \"GH_ERROR\",\n 1,\n );\n }\n if (!GITHUB_NAME_RE.test(parts[0]) || !GITHUB_NAME_RE.test(parts[1])) {\n throw new CliError(\n `Invalid repo name: \"${repoFlag}\". Owner and repo must match ${GITHUB_NAME_RE}`,\n \"GH_ERROR\",\n 1,\n );\n }\n return { owner: parts[0], repo: parts[1] };\n }\n\n try {\n const json = await gh([\"repo\", \"view\", \"--json\", \"owner,name\"]);\n let data: { owner?: { login?: string } | string; name?: string };\n try {\n data = JSON.parse(json);\n } catch {\n throw new CliError(\n \"Failed to parse repo info from gh CLI. Use --repo OWNER/REPO\",\n \"GH_ERROR\",\n 1,\n );\n }\n // gh returns owner as an object { login: \"...\" } not a plain string\n const owner =\n typeof data.owner === \"object\" && data.owner !== null\n ? data.owner.login\n : data.owner;\n const name = data.name;\n if (typeof owner !== \"string\" || !owner || typeof name !== \"string\" || !name) {\n throw new CliError(\n \"Could not detect repo owner/name. Use --repo OWNER/REPO\",\n \"NOT_GIT_REPO\",\n 2,\n );\n }\n return { owner, repo: name };\n } catch (err) {\n if (err instanceof CliError) {\n throw err;\n }\n throw new CliError(\n \"Not in a git repository. Use --repo OWNER/REPO\",\n \"NOT_GIT_REPO\",\n 2,\n );\n }\n}\n","import type { GitHubIssue, RepoRef } from \"../config/types.js\";\nimport { CliError } from \"../config/types.js\";\nimport { gh } from \"./client.js\";\n\nexport async function fetchIssues(repo: RepoRef, limit = 200): Promise<GitHubIssue[]> {\n const json = await gh([\n \"issue\",\n \"list\",\n \"-R\",\n `${repo.owner}/${repo.repo}`,\n \"--state\",\n \"open\",\n \"--json\",\n \"number,title,labels,assignees,author,comments,createdAt,updatedAt,url\",\n \"--limit\",\n String(limit),\n ]);\n let parsed: unknown;\n try {\n parsed = JSON.parse(json);\n } catch {\n throw new CliError(\n \"Failed to parse issues response from gh CLI\",\n \"GH_ERROR\",\n 1,\n );\n }\n if (!Array.isArray(parsed)) {\n throw new CliError(\n \"Unexpected issues response format from gh CLI\",\n \"GH_ERROR\",\n 1,\n );\n }\n return parsed as GitHubIssue[];\n}\n","import type { GitHubPR, RepoRef } from \"../config/types.js\";\nimport { CliError } from \"../config/types.js\";\nimport { gh } from \"./client.js\";\n\nexport async function fetchPulls(repo: RepoRef, limit = 200): Promise<GitHubPR[]> {\n const json = await gh([\n \"pr\",\n \"list\",\n \"-R\",\n `${repo.owner}/${repo.repo}`,\n \"--state\",\n \"open\",\n \"--json\",\n \"number,title,state,author,labels,comments,reviews,createdAt,updatedAt,url,isDraft,reviewDecision,mergeable,statusCheckRollup,closingIssuesReferences\",\n \"--limit\",\n String(limit),\n ]);\n let parsed: unknown;\n try {\n parsed = JSON.parse(json);\n } catch {\n throw new CliError(\n \"Failed to parse pull requests response from gh CLI\",\n \"GH_ERROR\",\n 1,\n );\n }\n if (!Array.isArray(parsed)) {\n throw new CliError(\n \"Unexpected pull requests response format from gh CLI\",\n \"GH_ERROR\",\n 1,\n );\n }\n return parsed as GitHubPR[];\n}\n","import { gh } from \"./client.js\";\nimport { CliError } from \"../config/types.js\";\n\n/**\n * Return the login of the currently authenticated GitHub user.\n */\nexport async function fetchCurrentUser(): Promise<string> {\n const login = await gh([\"api\", \"user\", \"--jq\", \".login\"]);\n if (!login) {\n throw new CliError(\n \"Could not determine GitHub username. Pass --github-token <token>, set GITHUB_TOKEN, or run: gh auth login\",\n \"GH_NOT_AUTHENTICATED\",\n 2,\n );\n }\n return login;\n}\n","import type { GitHubPR } from \"../config/types.js\";\n\nexport function hasLabel(labels: Array<{ name: string }>, keyword: string): boolean {\n return labels.some((l) =>\n l.name.toLowerCase().split(/[:\\-_]/).some((seg) => seg === keyword),\n );\n}\n\nexport function hasExactLabel(labels: Array<{ name: string }>, labelName: string): boolean {\n return labels.some((l) => l.name.toLowerCase() === labelName.toLowerCase());\n}\n\n/** Human-relative time string (\"just now\", \"5 minutes ago\", \"yesterday\", etc.). */\nexport function timeAgo(dateStr: string, now: Date): string {\n const ms = now.getTime() - new Date(dateStr).getTime();\n if (ms < 0) return \"just now\"; // future date — clock skew or bad data\n\n const minutes = Math.floor(ms / 60_000);\n const hours = Math.floor(ms / 3_600_000);\n const days = Math.floor(ms / 86_400_000);\n\n if (minutes < 1) return \"just now\";\n if (minutes === 1) return \"1 minute ago\";\n if (minutes < 60) return `${minutes} minutes ago`;\n if (hours === 1) return \"1 hour ago\";\n if (hours < 24) return `${hours} hours ago`;\n if (days === 1) return \"yesterday\";\n if (days < 7) return `${days} days ago`;\n if (days < 14) return \"1 week ago\";\n if (days < 30) return `${Math.floor(days / 7)} weeks ago`;\n if (days < 60) return \"1 month ago\";\n if (days < 365) return `${Math.floor(days / 30)} months ago`;\n const years = Math.floor(days / 365);\n if (years === 1) return \"1 year ago\";\n return `${years} years ago`;\n}\n\nexport function daysSince(dateStr: string, now: Date): number {\n const diff = now.getTime() - new Date(dateStr).getTime();\n return Math.max(0, Math.floor(diff / (1000 * 60 * 60 * 24)));\n}\n\nexport function hasCIFailure(pr: GitHubPR): boolean {\n if (!pr.statusCheckRollup) return false;\n return pr.statusCheckRollup.some((check) => {\n const conclusion = check.conclusion?.toUpperCase();\n const state = check.state?.toUpperCase();\n return conclusion === \"FAILURE\" || state === \"FAILURE\";\n });\n}\n\n/**\n * Summarize all status checks into a single label.\n * Returns null when there are no checks to report.\n */\nexport function checkStatus(pr: GitHubPR): string | null {\n if (!pr.statusCheckRollup || pr.statusCheckRollup.length === 0) return null;\n\n const hasFailing = hasCIFailure(pr);\n if (hasFailing) return \"checks failing\";\n\n const hasPending = pr.statusCheckRollup.some((c) => {\n const s = c.state?.toUpperCase();\n return s === \"PENDING\" || s === \"QUEUED\" || s === \"IN_PROGRESS\";\n });\n if (hasPending) return \"checks pending\";\n\n return \"checks passing\";\n}\n\n/**\n * Return a merge-conflict label, or null if no conflict info.\n */\nexport function mergeStatus(pr: GitHubPR): string | null {\n if (pr.mergeable === \"CONFLICTING\") return \"has conflicts\";\n if (pr.mergeable === \"MERGEABLE\") return \"no conflicts\";\n return null;\n}\n\n/** Collapse reviews to the latest state per author. */\nfunction latestReviewByAuthor(pr: GitHubPR): Map<string, string> {\n const map = new Map<string, string>();\n for (const review of pr.reviews ?? []) {\n map.set(review.author?.login ?? \"ghost\", review.state);\n }\n return map;\n}\n\n/** Count unique approvals (latest review per author). */\nexport function approvalCount(pr: GitHubPR): number {\n let count = 0;\n for (const state of latestReviewByAuthor(pr).values()) {\n if (state === \"APPROVED\") count++;\n }\n return count;\n}\n\n/**\n * Count unique changes-requested reviews (latest review per author).\n * If an author requests changes then later approves, they are no longer counted.\n */\nexport function changesRequestedCount(pr: GitHubPR): number {\n let count = 0;\n for (const state of latestReviewByAuthor(pr).values()) {\n if (state === \"CHANGES_REQUESTED\") count++;\n }\n return count;\n}\n","import type { GitHubIssue, GitHubPR, Alert } from \"../config/types.js\";\nimport { hasLabel, hasExactLabel, daysSince, hasCIFailure } from \"./utils.js\";\n\nconst STALE_DISCUSSION_DAYS = 3;\nconst PR_WAITING_REVIEW_DAYS = 2;\n\nfunction lastCommentDate(issue: GitHubIssue): string | null {\n if (issue.comments.length === 0) return null;\n return issue.comments.reduce((latest, c) =>\n c.createdAt > latest.createdAt ? c : latest,\n ).createdAt;\n}\n\nexport function generateAlerts(\n issues: GitHubIssue[],\n prs: GitHubPR[],\n now: Date = new Date(),\n): Alert[] {\n const alerts: Alert[] = [];\n\n // Stale discussions: discuss-labeled issues with no recent comments\n for (const issue of issues) {\n if (!hasLabel(issue.labels, \"discuss\") && !hasExactLabel(issue.labels, \"phase:discussion\")) continue;\n const lastComment = lastCommentDate(issue);\n const referenceDate = lastComment ?? issue.createdAt;\n const days = daysSince(referenceDate, now);\n if (days >= STALE_DISCUSSION_DAYS) {\n alerts.push({\n icon: \"\\u26a0\\ufe0f\",\n message: `#${issue.number} in discussion ${days} days, no recent comments`,\n });\n }\n }\n\n // Issues needing human attention\n for (const issue of issues) {\n if (hasExactLabel(issue.labels, \"needs:human\")) {\n alerts.push({\n icon: \"\\ud83d\\uded1\",\n message: `#${issue.number} needs human attention`,\n });\n }\n }\n\n // Only PRs in the governance intake (with \"implementation\" label) generate attention items\n const intakePRs = prs.filter((pr) => hasExactLabel(pr.labels, \"implementation\"));\n\n // PRs waiting on review too long (skip approved/changes-requested/drafts)\n for (const pr of intakePRs) {\n if (pr.isDraft) continue;\n if (pr.reviewDecision === \"APPROVED\" || pr.reviewDecision === \"CHANGES_REQUESTED\") continue;\n const days = daysSince(pr.createdAt, now);\n if (days >= PR_WAITING_REVIEW_DAYS) {\n alerts.push({\n icon: \"\\u26a0\\ufe0f\",\n message: `PR #${pr.number} waiting on review ${days} days`,\n });\n }\n }\n\n // CI failures on non-draft PRs\n for (const pr of intakePRs) {\n if (pr.isDraft) continue;\n if (hasCIFailure(pr)) {\n alerts.push({\n icon: \"\\u26a0\\ufe0f\",\n message: `PR #${pr.number} has CI failures`,\n });\n }\n }\n\n return alerts;\n}\n","import type {\n GitHubIssue,\n GitHubPR,\n RepoRef,\n RepoSummary,\n SummaryItem,\n} from \"../config/types.js\";\nimport { generateAlerts } from \"./alerts.js\";\nimport { hasLabel, hasExactLabel, hasCIFailure, checkStatus, mergeStatus, approvalCount, changesRequestedCount, timeAgo } from \"./utils.js\";\n\n/** Map verbose check labels to compact values for structured output. */\nfunction compactChecks(raw: string | null): string | null {\n if (raw === null) return null;\n if (raw === \"checks failing\") return \"failing\";\n if (raw === \"checks pending\") return \"pending\";\n if (raw === \"checks passing\") return \"passing\";\n return raw;\n}\n\n/** Map verbose merge labels to compact values for structured output. */\nfunction compactMergeable(raw: string | null): string | null {\n if (raw === null) return null;\n if (raw === \"has conflicts\") return \"conflicts\";\n if (raw === \"no conflicts\") return \"clean\";\n return raw;\n}\n\nfunction classifyIssue(\n issue: GitHubIssue,\n now: Date,\n): { bucket: \"voteOn\" | \"discuss\" | \"implement\" | \"needsHuman\"; item: SummaryItem } {\n const age = timeAgo(issue.createdAt, now);\n const assigned =\n issue.assignees.length > 0\n ? issue.assignees.map((a) => a.login).join(\", \")\n : undefined;\n\n const tags = issue.labels.map((l) => l.name);\n const author = issue.author?.login ?? \"ghost\";\n const comments = issue.comments.length;\n\n const base: SummaryItem = {\n number: issue.number,\n title: issue.title,\n tags,\n author,\n comments,\n age,\n };\n\n // Issues needing human attention are excluded from all actionable buckets\n if (hasExactLabel(issue.labels, \"needs:human\")) {\n return {\n bucket: \"needsHuman\",\n item: { ...base, assigned },\n };\n }\n\n // Bot governance labels (exact match)\n if (hasExactLabel(issue.labels, \"phase:voting\") || hasExactLabel(issue.labels, \"phase:extended-voting\")) {\n return { bucket: \"voteOn\", item: base };\n }\n if (hasExactLabel(issue.labels, \"phase:discussion\")) {\n return { bucket: \"discuss\", item: base };\n }\n if (hasExactLabel(issue.labels, \"phase:ready-to-implement\")) {\n return { bucket: \"implement\", item: { ...base, assigned } };\n }\n\n // Keyword fallback (repos without the bot)\n if (hasLabel(issue.labels, \"vote\")) {\n return { bucket: \"voteOn\", item: base };\n }\n if (hasLabel(issue.labels, \"discuss\")) {\n return { bucket: \"discuss\", item: base };\n }\n\n return {\n bucket: \"implement\",\n item: { ...base, assigned },\n };\n}\n\nfunction classifyPR(\n pr: GitHubPR,\n now: Date,\n): { bucket: \"reviewPRs\" | \"addressFeedback\"; item: SummaryItem } {\n const age = timeAgo(pr.createdAt, now);\n const tags = pr.labels.map((l) => l.name);\n const author = pr.author?.login ?? \"ghost\";\n const comments = pr.comments.length;\n const ciFailing = hasCIFailure(pr);\n const checks = compactChecks(checkStatus(pr));\n const merge = compactMergeable(mergeStatus(pr));\n const review = {\n approvals: approvalCount(pr),\n changesRequested: changesRequestedCount(pr),\n };\n\n if (pr.isDraft || ciFailing || pr.reviewDecision === \"CHANGES_REQUESTED\") {\n let status: string;\n if (pr.isDraft) status = \"draft\";\n else if (pr.reviewDecision === \"CHANGES_REQUESTED\") status = \"changes-requested\";\n else status = \"waiting\";\n\n return {\n bucket: \"addressFeedback\",\n item: { number: pr.number, title: pr.title, tags, author, comments, age, status, checks, mergeable: merge, review },\n };\n }\n\n const status = pr.reviewDecision === \"APPROVED\" ? \"approved\" : \"waiting\";\n\n return {\n bucket: \"reviewPRs\",\n item: { number: pr.number, title: pr.title, tags, author, comments, age, status, checks, mergeable: merge, review },\n };\n}\n\nfunction buildCompetitionMap(prs: GitHubPR[], currentUser: string): Map<number, number> {\n const map = new Map<number, number>();\n for (const pr of prs) {\n if (!hasLabel(pr.labels, \"implementation\")) continue;\n if (pr.author?.login === currentUser) continue;\n for (const ref of pr.closingIssuesReferences) {\n map.set(ref.number, (map.get(ref.number) ?? 0) + 1);\n }\n }\n return map;\n}\n\nexport function buildSummary(\n repo: RepoRef,\n issues: GitHubIssue[],\n prs: GitHubPR[],\n currentUser: string,\n now: Date = new Date(),\n): RepoSummary {\n const voteOn: SummaryItem[] = [];\n const discuss: SummaryItem[] = [];\n const implement: SummaryItem[] = [];\n const reviewPRs: SummaryItem[] = [];\n const addressFeedback: SummaryItem[] = [];\n\n for (const issue of issues) {\n const { bucket, item } = classifyIssue(issue, now);\n if (bucket === \"voteOn\") voteOn.push(item);\n else if (bucket === \"discuss\") discuss.push(item);\n else if (bucket === \"implement\") implement.push(item);\n // \"needsHuman\" issues intentionally excluded from all buckets\n }\n\n // Annotate implement items with competing PR counts\n const competitionMap = buildCompetitionMap(prs, currentUser);\n for (const item of implement) {\n const count = competitionMap.get(item.number) ?? 0;\n if (count > 0) {\n item.competingPRs = count;\n }\n }\n\n for (const pr of prs) {\n const { bucket, item } = classifyPR(pr, now);\n if (bucket === \"reviewPRs\") reviewPRs.push(item);\n else addressFeedback.push(item);\n }\n\n const alerts = generateAlerts(issues, prs, now);\n\n // Extract authored items into \"drive\" buckets so the agent knows what it owns\n const driveDiscussion: SummaryItem[] = [];\n const driveImplementation: SummaryItem[] = [];\n\n const filteredDiscuss = discuss.filter((item) => {\n if (item.author === currentUser) { driveDiscussion.push(item); return false; }\n return true;\n });\n\n const filteredVoteOn = voteOn.filter((item) => {\n if (item.author === currentUser && item.tags.includes(\"phase:extended-voting\")) {\n driveDiscussion.push(item);\n return false;\n }\n return true;\n });\n\n const filteredReviewPRs = reviewPRs.filter((item) => {\n if (item.author === currentUser) { driveImplementation.push(item); return false; }\n return true;\n });\n\n const filteredAddressFeedback = addressFeedback.filter((item) => {\n if (item.author === currentUser) { driveImplementation.push(item); return false; }\n return true;\n });\n\n return {\n repo,\n currentUser,\n driveDiscussion,\n driveImplementation,\n voteOn: filteredVoteOn,\n discuss: filteredDiscuss,\n implement,\n reviewPRs: filteredReviewPRs,\n addressFeedback: filteredAddressFeedback,\n alerts,\n notes: [],\n };\n}\n","import chalk from \"chalk\";\nimport type { RepoSummary, RoleConfig, SummaryItem, TeamConfig } from \"../config/types.js\";\n\nconst DIVIDER_WIDTH = 50;\n\n// Section types determine which metadata keys appear on the second line\ntype SectionType = \"vote\" | \"discuss\" | \"implement\" | \"reviewPRs\" | \"addressFeedback\" | \"driveDiscussion\" | \"driveImplementation\";\n\nfunction sectionDivider(title: string, count: number): string {\n const label = ` ${title} (${count}) `;\n const remaining = Math.max(0, DIVIDER_WIDTH - label.length - 2);\n return chalk.dim(\"──\") + chalk.bold(label) + chalk.dim(\"─\".repeat(remaining));\n}\n\nfunction formatTags(tags: string[]): string {\n if (tags.length === 0) return \"\";\n return \" \" + tags.map((t) => chalk.magenta(`[${t}]`)).join(\" \");\n}\n\nfunction kv(key: string, value: string | number): string {\n return `${key}: ${chalk.dim(String(value))}`;\n}\n\nfunction formatMeta(item: SummaryItem, sectionType: SectionType, currentUser: string): string {\n const isYou = item.author === currentUser;\n const authorVal = isYou ? chalk.green(`${item.author} (you)`) : chalk.dim(item.author);\n const parts: string[] = [`by: ${authorVal}`];\n\n if (sectionType === \"implement\") {\n parts.push(kv(\"assigned\", item.assigned ?? \"--\"));\n parts.push(kv(\"comments\", item.comments));\n parts.push(kv(\"created\", item.age));\n if (item.competingPRs !== undefined) {\n parts.push(kv(\"competing\", item.competingPRs));\n }\n } else if (sectionType === \"vote\" || sectionType === \"discuss\" || sectionType === \"driveDiscussion\") {\n parts.push(kv(\"comments\", item.comments));\n parts.push(kv(\"created\", item.age));\n } else {\n // PR sections: reviewPRs, addressFeedback, driveImplementation\n if (item.status !== undefined) parts.push(kv(\"status\", item.status));\n if (item.checks !== undefined && item.checks !== null) parts.push(kv(\"checks\", item.checks));\n if (item.mergeable !== undefined && item.mergeable !== null) parts.push(kv(\"merge\", item.mergeable));\n if (item.review) parts.push(kv(\"review\", `${item.review.approvals} approved, ${item.review.changesRequested} changes-requested`));\n parts.push(kv(\"comments\", item.comments));\n parts.push(kv(\"created\", item.age));\n }\n\n return parts.join(\" \");\n}\n\nfunction formatItem(item: SummaryItem, currentUser: string, sectionType: SectionType): string {\n const isYou = item.author === currentUser;\n const prefix = isYou ? chalk.green(\"★\") : \" \";\n const num = chalk.cyan(`#${item.number}`);\n const tags = formatTags(item.tags);\n\n const titleLine = `${prefix} ${num} ${item.title}${tags}`;\n const metaLine = ` ${formatMeta(item, sectionType, currentUser)}`;\n\n return `${titleLine}\\n${metaLine}`;\n}\n\nfunction formatSection(\n title: string,\n items: SummaryItem[],\n currentUser: string,\n sectionType: SectionType,\n limit?: number,\n): string {\n if (items.length === 0) return \"\";\n\n const displayed = limit ? items.slice(0, limit) : items;\n const header = sectionDivider(title, items.length);\n const itemBlocks = displayed.map((item) => formatItem(item, currentUser, sectionType));\n\n const parts = [header, ...itemBlocks];\n\n if (limit && items.length > limit) {\n parts.push(chalk.dim(` ... and ${items.length - limit} more`));\n }\n\n return parts.join(\"\\n\\n\");\n}\n\nfunction formatSummaryBody(summary: RepoSummary, limit?: number): string {\n const u = summary.currentUser;\n const sections: string[] = [];\n\n // Attention items at the top\n if (summary.alerts.length > 0) {\n const alertLines = [\n sectionDivider(\"REQUIRES YOUR ATTENTION\", summary.alerts.length),\n ...summary.alerts.map((a) => ` ${a.icon} ${chalk.yellow(a.message)}`),\n ];\n sections.push(alertLines.join(\"\\n\"));\n }\n\n sections.push(\n ...[\n formatSection(\"DRIVE THE DISCUSSION\", summary.driveDiscussion, u, \"driveDiscussion\", limit),\n formatSection(\"DRIVE THE IMPLEMENTATION\", summary.driveImplementation, u, \"driveImplementation\", limit),\n formatSection(\"VOTE ON ISSUES\", summary.voteOn, u, \"vote\", limit),\n formatSection(\"DISCUSS ISSUES\", summary.discuss, u, \"discuss\", limit),\n formatSection(\"READY TO IMPLEMENT ISSUES\", summary.implement, u, \"implement\", limit),\n formatSection(\"REVIEW PRs\", summary.reviewPRs, u, \"reviewPRs\", limit),\n formatSection(\"ADDRESS FEEDBACK PRs\", summary.addressFeedback, u, \"addressFeedback\", limit),\n ].filter(Boolean),\n );\n\n if (summary.notes.length > 0) {\n sections.push(summary.notes.map((n) => chalk.dim(` ${n}`)).join(\"\\n\"));\n }\n\n if (sections.length === 0) {\n return chalk.dim(\" No open issues or PRs.\");\n }\n\n return sections.join(\"\\n\\n\");\n}\n\nexport function formatBuzz(\n roleName: string,\n role: RoleConfig,\n summary: RepoSummary,\n limit?: number,\n): string {\n const lines = [\n chalk.bold(`ROLE: ${roleName}`) + ` — ${role.description}`,\n \"\",\n chalk.bold(\"INSTRUCTIONS:\"),\n role.instructions.trimEnd(),\n \"\",\n `You are working on ${chalk.bold(`${summary.repo.owner}/${summary.repo.repo}`)}, logged in as ${chalk.green(summary.currentUser)}`,\n \"\",\n formatSummaryBody(summary, limit),\n ];\n\n return lines.join(\"\\n\");\n}\n\nexport function formatStatus(summary: RepoSummary, limit?: number): string {\n const lines = [\n `You are working on ${chalk.bold(`${summary.repo.owner}/${summary.repo.repo}`)}, logged in as ${chalk.green(summary.currentUser)}`,\n \"\",\n formatSummaryBody(summary, limit),\n ];\n\n return lines.join(\"\\n\");\n}\n\nexport function formatRoles(teamConfig: TeamConfig, repoFullName: string): string {\n const nameLabel = teamConfig.name ? ` (${teamConfig.name})` : \"\";\n const lines = [\n chalk.bold(`ROLES — ${repoFullName}${nameLabel}`),\n \"\",\n ];\n\n const slugs = Object.keys(teamConfig.roles);\n const maxLen = Math.max(...slugs.map((s) => s.length));\n\n for (const slug of slugs) {\n const role = teamConfig.roles[slug];\n const padded = slug.padEnd(maxLen + 2);\n lines.push(` ${chalk.cyan(padded)}${role.description}`);\n }\n\n return lines.join(\"\\n\");\n}\n","import type { RepoSummary, RoleConfig, TeamConfig } from \"../config/types.js\";\n\nexport function jsonBuzz(\n roleName: string,\n role: RoleConfig,\n summary: RepoSummary,\n): string {\n return JSON.stringify(\n {\n role: {\n name: roleName,\n description: role.description,\n instructions: role.instructions,\n },\n summary: {\n repo: `${summary.repo.owner}/${summary.repo.repo}`,\n currentUser: summary.currentUser,\n driveDiscussion: summary.driveDiscussion,\n driveImplementation: summary.driveImplementation,\n voteOn: summary.voteOn,\n discuss: summary.discuss,\n implement: summary.implement,\n reviewPRs: summary.reviewPRs,\n addressFeedback: summary.addressFeedback,\n alerts: summary.alerts,\n notes: summary.notes,\n },\n },\n null,\n 2,\n );\n}\n\nexport function jsonStatus(summary: RepoSummary): string {\n return JSON.stringify(\n {\n repo: `${summary.repo.owner}/${summary.repo.repo}`,\n currentUser: summary.currentUser,\n driveDiscussion: summary.driveDiscussion,\n driveImplementation: summary.driveImplementation,\n voteOn: summary.voteOn,\n discuss: summary.discuss,\n implement: summary.implement,\n reviewPRs: summary.reviewPRs,\n addressFeedback: summary.addressFeedback,\n alerts: summary.alerts,\n notes: summary.notes,\n },\n null,\n 2,\n );\n}\n\nexport function jsonRoles(teamConfig: TeamConfig): string {\n const roles = Object.entries(teamConfig.roles).map(([slug, role]) => ({\n name: slug,\n description: role.description,\n }));\n\n return JSON.stringify({ roles }, null, 2);\n}\n","import { CliError, type BuzzOptions } from \"../config/types.js\";\nimport { loadTeamConfig } from \"../config/loader.js\";\nimport { resolveRepo } from \"../github/repo.js\";\nimport { fetchIssues } from \"../github/issues.js\";\nimport { fetchPulls } from \"../github/pulls.js\";\nimport { fetchCurrentUser } from \"../github/user.js\";\nimport { buildSummary } from \"../summary/builder.js\";\nimport { formatBuzz, formatStatus } from \"../output/formatter.js\";\nimport { jsonBuzz, jsonStatus } from \"../output/json.js\";\n\nexport async function buzzCommand(options: BuzzOptions): Promise<void> {\n const repo = await resolveRepo(options.repo);\n const fetchLimit = options.fetchLimit ?? 200;\n\n const [issues, prs, currentUser] = await Promise.all([\n fetchIssues(repo, fetchLimit),\n fetchPulls(repo, fetchLimit),\n fetchCurrentUser(),\n ]);\n\n const summary = buildSummary(repo, issues, prs, currentUser);\n\n if (issues.length >= fetchLimit) {\n summary.notes.push(`Only the first ${fetchLimit} issues were fetched. Use --fetch-limit to increase.`);\n }\n if (prs.length >= fetchLimit) {\n summary.notes.push(`Only the first ${fetchLimit} PRs were fetched. Use --fetch-limit to increase.`);\n }\n\n if (options.role) {\n const teamConfig = await loadTeamConfig(repo);\n if (!Object.hasOwn(teamConfig.roles, options.role)) {\n const available = Object.keys(teamConfig.roles).join(\", \");\n throw new CliError(\n `Role '${options.role}' not found. Available: ${available}. Run: hivemoot roles`,\n \"ROLE_NOT_FOUND\",\n 1,\n );\n }\n const roleConfig = teamConfig.roles[options.role];\n\n if (options.json) {\n console.log(jsonBuzz(options.role, roleConfig, summary));\n } else {\n console.log(formatBuzz(options.role, roleConfig, summary, options.limit));\n }\n } else {\n if (options.json) {\n console.log(jsonStatus(summary));\n } else {\n console.log(formatStatus(summary, options.limit));\n }\n }\n}\n","import type { RolesOptions } from \"../config/types.js\";\nimport { loadTeamConfig } from \"../config/loader.js\";\nimport { resolveRepo } from \"../github/repo.js\";\nimport { formatRoles } from \"../output/formatter.js\";\nimport { jsonRoles } from \"../output/json.js\";\n\nexport async function rolesCommand(options: RolesOptions): Promise<void> {\n const repo = await resolveRepo(options.repo);\n const teamConfig = await loadTeamConfig(repo);\n\n if (options.json) {\n console.log(jsonRoles(teamConfig));\n } else {\n console.log(formatRoles(teamConfig, `${repo.owner}/${repo.repo}`));\n }\n}\n","export async function initCommand(): Promise<void> {\n const template = `# Hivemoot team configuration\n# Place this file at .github/hivemoot.yml in your repository.\n#\n# Roles define personas (who the agent is), not workflow.\n# Workflow details belong in .agent/skills/.\n\nteam:\n roles:\n pm:\n description: \"Product manager focused on user value and clarity\"\n instructions: |\n You think from the user's perspective.\n Evaluate ideas by the problem they solve and who benefits.\n Push for clear requirements and well-scoped proposals.\n Ask \"why does this matter?\" before \"how do we build it?\"\n\n engineer:\n description: \"Software engineer focused on clean implementation\"\n instructions: |\n You care about code quality, patterns, and maintainability.\n Favor simple, proven approaches over clever solutions.\n Write clean code with good test coverage.\n Build on existing conventions in the codebase.\n\n architect:\n description: \"Architect focused on system design and long-term health\"\n instructions: |\n You think about how pieces fit together.\n Evaluate proposals for scalability, consistency, and technical debt.\n Guard the system's boundaries and abstractions.\n Push back when short-term wins create long-term problems.\n\n qa:\n description: \"QA engineer focused on reliability and edge cases\"\n instructions: |\n You think about what can go wrong.\n Find edge cases, race conditions, and failure modes others miss.\n Push for thorough error handling and defensive design.\n Ask \"what happens when this fails?\" about everything.\n`;\n\n console.log(template);\n}\n"],"mappings":"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","names":["status","require"]}
|