@kud/gh 0.2.0 → 0.4.0
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/inbox.d.ts +18 -0
- package/dist/inbox.d.ts.map +1 -0
- package/dist/inbox.js +144 -0
- package/dist/inbox.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/inbox.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** A repo-scoped or account-wide inbox. */
|
|
2
|
+
export type InboxQueryOptions = {
|
|
3
|
+
/** `owner/name`. Scopes every search to one repository. */
|
|
4
|
+
repo?: string;
|
|
5
|
+
/** How far back `recentlyDone` looks. Defaults to 14 days. */
|
|
6
|
+
doneWithinDays?: number;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Build the inbox query. Without `repo`, it is account-wide.
|
|
10
|
+
*
|
|
11
|
+
* The two qualifiers do NOT compose. `user:@me` means "in repos I own", and
|
|
12
|
+
* GitHub ANDs search qualifiers — so `user:@me repo:someone-else/x` matches
|
|
13
|
+
* nothing, and a scoped inbox on a repo you contribute to but do not own would
|
|
14
|
+
* render empty and read as "nothing to do here". So `repo:` REPLACES
|
|
15
|
+
* `user:@me` rather than joining it.
|
|
16
|
+
*/
|
|
17
|
+
export declare const buildInboxQuery: ({ repo, doneWithinDays, }?: InboxQueryOptions) => string;
|
|
18
|
+
//# sourceMappingURL=inbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inbox.d.ts","sourceRoot":"","sources":["../src/inbox.ts"],"names":[],"mappings":"AAQA,2CAA2C;AAC3C,MAAM,MAAM,iBAAiB,GAAG;IAC9B,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,8DAA8D;IAC9D,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAmDD;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,GAAI,4BAG7B,iBAAsB,WAoFxB,CAAA"}
|
package/dist/inbox.js
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
// The inbox query — one GraphQL round-trip for "what is on my plate": my PRs,
|
|
2
|
+
// review requests, reviews I have given, assigned work, issues and PRs on my
|
|
3
|
+
// repos, and what I closed recently.
|
|
4
|
+
//
|
|
5
|
+
// Query-only by design. Assembling the result into sections is the surface's
|
|
6
|
+
// own vocabulary — cockpit splits home from work, a web dashboard may group by
|
|
7
|
+
// project — so nothing here decides what a section is.
|
|
8
|
+
// computeHealth's precedence needs reviewDecision, mergeable and the check
|
|
9
|
+
// rollup. A fragment that omits them does NOT degrade gracefully — it falls
|
|
10
|
+
// straight through to whatever token is left, so a PR you already sent back
|
|
11
|
+
// renders as "awaiting review" and a failing one renders as quiet. Every PR
|
|
12
|
+
// fragment therefore carries the whole set; none of it is optional.
|
|
13
|
+
const PR_HEALTH = `
|
|
14
|
+
isDraft reviewDecision mergeable
|
|
15
|
+
statusCheckRollup { contexts(first: 20) { nodes {
|
|
16
|
+
... on CheckRun { name conclusion status }
|
|
17
|
+
... on StatusContext { context state }
|
|
18
|
+
} } }`;
|
|
19
|
+
// Whose turn it is cannot be read off a count, so every comment-bearing edge
|
|
20
|
+
// carries its latest author and timestamp: the conversation, the review bodies,
|
|
21
|
+
// and each thread's last reply. The last commit rides along so a consumer can
|
|
22
|
+
// say whether the author has pushed since being sent back.
|
|
23
|
+
//
|
|
24
|
+
// `__typename` distinguishes a Bot from a User, which a login cannot: GraphQL
|
|
25
|
+
// reports app authors bare (`greptile-apps`), without the `[bot]` suffix REST
|
|
26
|
+
// adds, so there is nothing in the name to match on. A consumer needs it to
|
|
27
|
+
// decide whether a push answers what was said — it does when a machine said it,
|
|
28
|
+
// and does not when a person did. Note it catches GitHub Apps only; a machine
|
|
29
|
+
// ACCOUNT like `raycastbot` is a User and reads as human here.
|
|
30
|
+
const PR_CONVERSATION = `
|
|
31
|
+
comments(last: 1) { totalCount nodes { author { __typename login } createdAt } }
|
|
32
|
+
reviews(last: 1) { nodes { author { __typename login } state submittedAt } }
|
|
33
|
+
reviewThreads(first: 50) { nodes {
|
|
34
|
+
isResolved
|
|
35
|
+
comments(last: 1) { totalCount nodes { author { __typename login } createdAt } }
|
|
36
|
+
} }
|
|
37
|
+
commits(last: 1) { nodes { commit { committedDate } } }`;
|
|
38
|
+
const ISSUE_CONVERSATION = `
|
|
39
|
+
comments(last: 1) { totalCount nodes { author { __typename login } createdAt } }`;
|
|
40
|
+
// Fetched so a consumer can tell a `plan` issue from any other — which decides
|
|
41
|
+
// what a delegated session gets handed. Nothing here renders labels.
|
|
42
|
+
const ISSUE_LABELS = `
|
|
43
|
+
labels(first: 10) { nodes { name } }`;
|
|
44
|
+
/*
|
|
45
|
+
* Computed per call, never at module scope. A CLI process is short-lived and
|
|
46
|
+
* would not notice, but a long-running server imports this once and keeps it
|
|
47
|
+
* for days — a module-level date would freeze "recently done" to the morning
|
|
48
|
+
* the server booted and quietly stop reporting anything closed since.
|
|
49
|
+
*/
|
|
50
|
+
const sinceDay = (days) => new Date(Date.now() - days * 86400 * 1000).toISOString().slice(0, 10);
|
|
51
|
+
/**
|
|
52
|
+
* Build the inbox query. Without `repo`, it is account-wide.
|
|
53
|
+
*
|
|
54
|
+
* The two qualifiers do NOT compose. `user:@me` means "in repos I own", and
|
|
55
|
+
* GitHub ANDs search qualifiers — so `user:@me repo:someone-else/x` matches
|
|
56
|
+
* nothing, and a scoped inbox on a repo you contribute to but do not own would
|
|
57
|
+
* render empty and read as "nothing to do here". So `repo:` REPLACES
|
|
58
|
+
* `user:@me` rather than joining it.
|
|
59
|
+
*/
|
|
60
|
+
export const buildInboxQuery = ({ repo, doneWithinDays = 14, } = {}) => {
|
|
61
|
+
const scope = repo ? `repo:${repo} ` : "";
|
|
62
|
+
const owned = repo ? "" : "user:@me ";
|
|
63
|
+
const doneSince = sinceDay(doneWithinDays);
|
|
64
|
+
return `
|
|
65
|
+
{
|
|
66
|
+
viewer { login }
|
|
67
|
+
myPRs: search(query: "${scope}is:pr is:open author:@me", type: ISSUE, first: 100) {
|
|
68
|
+
nodes { __typename ... on PullRequest {
|
|
69
|
+
number title createdAt url headRefName
|
|
70
|
+
repository { nameWithOwner }
|
|
71
|
+
${PR_HEALTH}
|
|
72
|
+
${PR_CONVERSATION}
|
|
73
|
+
}}
|
|
74
|
+
}
|
|
75
|
+
reviewRequests: search(query: "${scope}is:pr is:open review-requested:@me", type: ISSUE, first: 20) {
|
|
76
|
+
nodes { __typename ... on PullRequest {
|
|
77
|
+
number title createdAt url headRefName
|
|
78
|
+
repository { nameWithOwner }
|
|
79
|
+
author { login }
|
|
80
|
+
${PR_HEALTH}
|
|
81
|
+
${PR_CONVERSATION}
|
|
82
|
+
}}
|
|
83
|
+
}
|
|
84
|
+
reviewed: search(query: "${scope}is:pr is:open reviewed-by:@me -author:@me -review-requested:@me", type: ISSUE, first: 20) {
|
|
85
|
+
nodes { __typename ... on PullRequest {
|
|
86
|
+
number title createdAt url headRefName
|
|
87
|
+
repository { nameWithOwner }
|
|
88
|
+
author { login }
|
|
89
|
+
${PR_HEALTH}
|
|
90
|
+
${PR_CONVERSATION}
|
|
91
|
+
}}
|
|
92
|
+
}
|
|
93
|
+
assigned: search(query: "${scope}is:open assignee:@me", type: ISSUE, first: 30) {
|
|
94
|
+
nodes {
|
|
95
|
+
__typename
|
|
96
|
+
... on Issue {
|
|
97
|
+
number title createdAt url repository { nameWithOwner } author { login }
|
|
98
|
+
${ISSUE_CONVERSATION}
|
|
99
|
+
${ISSUE_LABELS}
|
|
100
|
+
}
|
|
101
|
+
... on PullRequest {
|
|
102
|
+
number title createdAt url headRefName repository { nameWithOwner } author { login }
|
|
103
|
+
${PR_HEALTH}
|
|
104
|
+
${PR_CONVERSATION}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
repoIssues: search(query: "${scope}${owned}is:issue is:open archived:false", type: ISSUE, first: 30) {
|
|
109
|
+
nodes { __typename ... on Issue {
|
|
110
|
+
number title createdAt url
|
|
111
|
+
repository { nameWithOwner }
|
|
112
|
+
author { login }
|
|
113
|
+
${ISSUE_CONVERSATION}
|
|
114
|
+
${ISSUE_LABELS}
|
|
115
|
+
}}
|
|
116
|
+
}
|
|
117
|
+
authoredIssues: search(query: "${scope}is:issue is:open author:@me archived:false", type: ISSUE, first: 30) {
|
|
118
|
+
nodes { ... on Issue {
|
|
119
|
+
number title createdAt url
|
|
120
|
+
repository { nameWithOwner }
|
|
121
|
+
author { login }
|
|
122
|
+
${ISSUE_CONVERSATION}
|
|
123
|
+
${ISSUE_LABELS}
|
|
124
|
+
}}
|
|
125
|
+
}
|
|
126
|
+
repoPRs: search(query: "${scope}${owned}is:pr is:open -author:@me archived:false", type: ISSUE, first: 30) {
|
|
127
|
+
nodes { __typename ... on PullRequest {
|
|
128
|
+
number title createdAt url headRefName
|
|
129
|
+
repository { nameWithOwner }
|
|
130
|
+
author { login }
|
|
131
|
+
${PR_HEALTH}
|
|
132
|
+
${PR_CONVERSATION}
|
|
133
|
+
}}
|
|
134
|
+
}
|
|
135
|
+
recentlyDone: search(query: "${scope}is:pr author:@me -is:open closed:>=${doneSince}", type: ISSUE, first: 30) {
|
|
136
|
+
nodes { __typename ... on PullRequest {
|
|
137
|
+
number title state isDraft createdAt mergedAt closedAt url
|
|
138
|
+
repository { nameWithOwner }
|
|
139
|
+
}}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
`;
|
|
143
|
+
};
|
|
144
|
+
//# sourceMappingURL=inbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inbox.js","sourceRoot":"","sources":["../src/inbox.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,6EAA6E;AAC7E,qCAAqC;AACrC,EAAE;AACF,6EAA6E;AAC7E,+EAA+E;AAC/E,uDAAuD;AAUvD,2EAA2E;AAC3E,4EAA4E;AAC5E,4EAA4E;AAC5E,4EAA4E;AAC5E,oEAAoE;AACpE,MAAM,SAAS,GAAG;;;;;YAKN,CAAA;AAEZ,6EAA6E;AAC7E,gFAAgF;AAChF,8EAA8E;AAC9E,2DAA2D;AAC3D,EAAE;AACF,8EAA8E;AAC9E,8EAA8E;AAC9E,4EAA4E;AAC5E,gFAAgF;AAChF,8EAA8E;AAC9E,+DAA+D;AAC/D,MAAM,eAAe,GAAG;;;;;;;8DAOsC,CAAA;AAE9D,MAAM,kBAAkB,GAAG;uFAC4D,CAAA;AAEvF,+EAA+E;AAC/E,qEAAqE;AACrE,MAAM,YAAY,GAAG;2CACsB,CAAA;AAE3C;;;;;GAKG;AACH,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAE,EAAE,CAChC,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,KAAK,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;AAEvE;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,EAC9B,IAAI,EACJ,cAAc,GAAG,EAAE,MACE,EAAE,EAAE,EAAE;IAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAA;IACzC,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAA;IACrC,MAAM,SAAS,GAAG,QAAQ,CAAC,cAAc,CAAC,CAAA;IAE1C,OAAO;;;0BAGiB,KAAK;;;;QAIvB,SAAS;QACT,eAAe;;;mCAGY,KAAK;;;;;QAKhC,SAAS;QACT,eAAe;;;6BAGM,KAAK;;;;;QAK1B,SAAS;QACT,eAAe;;;6BAGM,KAAK;;;;;UAKxB,kBAAkB;UAClB,YAAY;;;;UAIZ,SAAS;UACT,eAAe;;;;+BAIM,KAAK,GAAG,KAAK;;;;;QAKpC,kBAAkB;QAClB,YAAY;;;mCAGe,KAAK;;;;;QAKhC,kBAAkB;QAClB,YAAY;;;4BAGQ,KAAK,GAAG,KAAK;;;;;QAKjC,SAAS;QACT,eAAe;;;iCAGU,KAAK,sCAAsC,SAAS;;;;;;;CAOpF,CAAA;AACD,CAAC,CAAA"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,cAAc,SAAS,CAAA;AACvB,cAAc,SAAS,CAAA;AACvB,cAAc,kBAAkB,CAAA;AAChC,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,cAAc,SAAS,CAAA;AACvB,cAAc,YAAY,CAAA;AAC1B,cAAc,SAAS,CAAA;AACvB,cAAc,kBAAkB,CAAA;AAChC,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,iFAAiF;AACjF,2EAA2E;AAC3E,EAAE;AACF,6EAA6E;AAC7E,8EAA8E;AAC9E,+EAA+E;AAC/E,4EAA4E;AAC5E,gFAAgF;AAChF,iFAAiF;AACjF,mFAAmF;AACnF,2EAA2E;AAC3E,aAAa;AACb,cAAc,SAAS,CAAA;AACvB,cAAc,SAAS,CAAA;AACvB,cAAc,kBAAkB,CAAA;AAChC,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,iFAAiF;AACjF,2EAA2E;AAC3E,EAAE;AACF,6EAA6E;AAC7E,8EAA8E;AAC9E,+EAA+E;AAC/E,4EAA4E;AAC5E,gFAAgF;AAChF,iFAAiF;AACjF,mFAAmF;AACnF,2EAA2E;AAC3E,aAAa;AACb,cAAc,SAAS,CAAA;AACvB,cAAc,YAAY,CAAA;AAC1B,cAAc,SAAS,CAAA;AACvB,cAAc,kBAAkB,CAAA;AAChC,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA"}
|