@nanonets/graft 0.16.0 → 0.18.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.
Files changed (143) hide show
  1. package/README.md +9 -2
  2. package/dist/app/brain-build.d.ts +66 -0
  3. package/dist/app/brain-build.d.ts.map +1 -0
  4. package/dist/app/brain-build.js +169 -0
  5. package/dist/app/brain-build.js.map +1 -0
  6. package/dist/app/checkout.d.ts +53 -3
  7. package/dist/app/checkout.d.ts.map +1 -1
  8. package/dist/app/checkout.js +195 -27
  9. package/dist/app/checkout.js.map +1 -1
  10. package/dist/app/events.d.ts +7 -0
  11. package/dist/app/events.d.ts.map +1 -1
  12. package/dist/app/events.js +7 -2
  13. package/dist/app/events.js.map +1 -1
  14. package/dist/app/history.d.ts +128 -0
  15. package/dist/app/history.d.ts.map +1 -0
  16. package/dist/app/history.js +269 -0
  17. package/dist/app/history.js.map +1 -0
  18. package/dist/app/identity.d.ts +33 -0
  19. package/dist/app/identity.d.ts.map +1 -1
  20. package/dist/app/identity.js +72 -0
  21. package/dist/app/identity.js.map +1 -1
  22. package/dist/app/main.js +12 -0
  23. package/dist/app/main.js.map +1 -1
  24. package/dist/app/pages.d.ts +17 -0
  25. package/dist/app/pages.d.ts.map +1 -1
  26. package/dist/app/pages.js +112 -5
  27. package/dist/app/pages.js.map +1 -1
  28. package/dist/app/review-process.d.ts +66 -0
  29. package/dist/app/review-process.d.ts.map +1 -0
  30. package/dist/app/review-process.js +199 -0
  31. package/dist/app/review-process.js.map +1 -0
  32. package/dist/app/review-worker.d.ts +2 -0
  33. package/dist/app/review-worker.d.ts.map +1 -0
  34. package/dist/app/review-worker.js +108 -0
  35. package/dist/app/review-worker.js.map +1 -0
  36. package/dist/app/review.d.ts.map +1 -1
  37. package/dist/app/review.js +4 -1
  38. package/dist/app/review.js.map +1 -1
  39. package/dist/app/server.d.ts +22 -2
  40. package/dist/app/server.d.ts.map +1 -1
  41. package/dist/app/server.js +77 -3
  42. package/dist/app/server.js.map +1 -1
  43. package/dist/app/sources.d.ts +68 -0
  44. package/dist/app/sources.d.ts.map +1 -0
  45. package/dist/app/sources.js +341 -0
  46. package/dist/app/sources.js.map +1 -0
  47. package/dist/ask/ask.d.ts +6 -0
  48. package/dist/ask/ask.d.ts.map +1 -1
  49. package/dist/ask/ask.js +30 -2
  50. package/dist/ask/ask.js.map +1 -1
  51. package/dist/brain/attach.d.ts +44 -0
  52. package/dist/brain/attach.d.ts.map +1 -0
  53. package/dist/brain/attach.js +63 -0
  54. package/dist/brain/attach.js.map +1 -0
  55. package/dist/brain/connect.d.ts +59 -0
  56. package/dist/brain/connect.d.ts.map +1 -0
  57. package/dist/brain/connect.js +80 -0
  58. package/dist/brain/connect.js.map +1 -0
  59. package/dist/brain/link.d.ts +82 -0
  60. package/dist/brain/link.d.ts.map +1 -0
  61. package/dist/brain/link.js +136 -0
  62. package/dist/brain/link.js.map +1 -0
  63. package/dist/brain/push.d.ts +72 -0
  64. package/dist/brain/push.d.ts.map +1 -0
  65. package/dist/brain/push.js +191 -0
  66. package/dist/brain/push.js.map +1 -0
  67. package/dist/brain/wire.d.ts +38 -0
  68. package/dist/brain/wire.d.ts.map +1 -0
  69. package/dist/brain/wire.js +133 -0
  70. package/dist/brain/wire.js.map +1 -0
  71. package/dist/claude/format.d.ts.map +1 -1
  72. package/dist/claude/format.js +10 -3
  73. package/dist/claude/format.js.map +1 -1
  74. package/dist/claude/hooks.d.ts.map +1 -1
  75. package/dist/claude/hooks.js +32 -1
  76. package/dist/claude/hooks.js.map +1 -1
  77. package/dist/claude/init.d.ts +5 -0
  78. package/dist/claude/init.d.ts.map +1 -1
  79. package/dist/claude/init.js +9 -1
  80. package/dist/claude/init.js.map +1 -1
  81. package/dist/claude/session-metrics.d.ts +10 -0
  82. package/dist/claude/session-metrics.d.ts.map +1 -1
  83. package/dist/claude/session-metrics.js +25 -0
  84. package/dist/claude/session-metrics.js.map +1 -1
  85. package/dist/claude/settings-merge.d.ts +18 -0
  86. package/dist/claude/settings-merge.d.ts.map +1 -1
  87. package/dist/claude/settings-merge.js +42 -8
  88. package/dist/claude/settings-merge.js.map +1 -1
  89. package/dist/claude/skill-template.d.ts.map +1 -1
  90. package/dist/claude/skill-template.js +6 -0
  91. package/dist/claude/skill-template.js.map +1 -1
  92. package/dist/claude/state.d.ts +14 -0
  93. package/dist/claude/state.d.ts.map +1 -1
  94. package/dist/claude/state.js.map +1 -1
  95. package/dist/claude/tally.d.ts +27 -0
  96. package/dist/claude/tally.d.ts.map +1 -1
  97. package/dist/claude/tally.js +74 -1
  98. package/dist/claude/tally.js.map +1 -1
  99. package/dist/cli.js +210 -3
  100. package/dist/cli.js.map +1 -1
  101. package/dist/context/price.d.ts +49 -0
  102. package/dist/context/price.d.ts.map +1 -0
  103. package/dist/context/price.js +83 -0
  104. package/dist/context/price.js.map +1 -0
  105. package/dist/context/savings.d.ts +13 -3
  106. package/dist/context/savings.d.ts.map +1 -1
  107. package/dist/context/savings.js +44 -5
  108. package/dist/context/savings.js.map +1 -1
  109. package/dist/hosts/claude-global.d.ts +33 -0
  110. package/dist/hosts/claude-global.d.ts.map +1 -0
  111. package/dist/hosts/claude-global.js +118 -0
  112. package/dist/hosts/claude-global.js.map +1 -0
  113. package/dist/hosts/plan.d.ts.map +1 -1
  114. package/dist/hosts/plan.js +5 -1
  115. package/dist/hosts/plan.js.map +1 -1
  116. package/dist/hosts/retract.d.ts.map +1 -1
  117. package/dist/hosts/retract.js +33 -13
  118. package/dist/hosts/retract.js.map +1 -1
  119. package/dist/hosts/sections.d.ts +23 -2
  120. package/dist/hosts/sections.d.ts.map +1 -1
  121. package/dist/hosts/sections.js +25 -9
  122. package/dist/hosts/sections.js.map +1 -1
  123. package/dist/mcp/server.d.ts.map +1 -1
  124. package/dist/mcp/server.js +33 -4
  125. package/dist/mcp/server.js.map +1 -1
  126. package/dist/mcp/tools.d.ts.map +1 -1
  127. package/dist/mcp/tools.js +5 -1
  128. package/dist/mcp/tools.js.map +1 -1
  129. package/dist/telemetry/gate.d.ts +14 -0
  130. package/dist/telemetry/gate.d.ts.map +1 -1
  131. package/dist/telemetry/gate.js +18 -2
  132. package/dist/telemetry/gate.js.map +1 -1
  133. package/dist/upkeep-run.d.ts.map +1 -1
  134. package/dist/upkeep-run.js +12 -2
  135. package/dist/upkeep-run.js.map +1 -1
  136. package/dist/upkeep.d.ts +18 -0
  137. package/dist/upkeep.d.ts.map +1 -1
  138. package/dist/upkeep.js +38 -0
  139. package/dist/upkeep.js.map +1 -1
  140. package/dist/util/state.d.ts +9 -0
  141. package/dist/util/state.d.ts.map +1 -1
  142. package/dist/util/state.js.map +1 -1
  143. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"checkout.js","sourceRoot":"","sources":["../../src/app/checkout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,8EAA8E;AAC9E,MAAM,WAAW,GAAG,EAAE,CAAC;AACvB,MAAM,cAAc,GAAG,OAAO,CAAC;AAqB/B,4EAA4E;AAC5E,SAAS,GAAG,CAAC,GAAW,EAAE,IAAc,EAAE,KAAc;IACtD,MAAM,IAAI,GAAG,KAAK;QAChB,CAAC,CAAC;YACE,IAAI;YACJ,2EAA2E;YAC3E,yEAAyE;YACzE,4BAA4B;YAC5B,yCAAyC,MAAM,CAAC,IAAI,CAAC,kBAAkB,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE;SACrG;QACH,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,GAAG,GAAG,SAAS,CACnB,KAAK,EACL,CAAC,IAAI,EAAE,0BAA0B,EAAE,IAAI,EAAE,oBAAoB,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC,EAChF;QACE,GAAG,EAAE,GAAG;QACR,QAAQ,EAAE,MAAM;QAChB,OAAO,EAAE,cAAc;QACvB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;QACjC,GAAG,EAAE;YACH,GAAG,OAAO,CAAC,GAAG;YACd,qEAAqE;YACrE,mBAAmB,EAAE,GAAG;YACxB,mBAAmB,EAAE,GAAG;YACxB,WAAW,EAAE,EAAE;YACf,IAAI,EAAE,GAAG;SACV;KACF,CACF,CAAC;IACF,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,MAAM,IAAI,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;AAChH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAoB;IACtD,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,oBAAoB,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAClE,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,aAAa,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;IAC/E,MAAM,OAAO,GAAG,GAAS,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAE1E,MAAM,KAAK,GAA8B;QACvC,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;QACnD,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,IAAI,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,IAAI,MAAM,CAAC,CAAC;QAC/E,6EAA6E;QAC7E;YACE,OAAO;YACP;gBACE,OAAO;gBACP,SAAS;gBACT,WAAW,WAAW,EAAE;gBACxB,yBAAyB;gBACzB,QAAQ;gBACR,cAAc,GAAG,CAAC,MAAM,yBAAyB;gBACjD,eAAe,GAAG,CAAC,OAAO,kBAAkB;aAC7C;SACF;QACD,CAAC,UAAU,EAAE,CAAC,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,kBAAkB,CAAC,CAAC;KACtE,CAAC;IAEF,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,KAAK,EAAE,CAAC;QACjC,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC7E,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,OAAO,EAAE,CAAC;YACV,0EAA0E;YAC1E,2EAA2E;YAC3E,2DAA2D;YAC3D,MAAM,IAAI,KAAK,CAAC,YAAY,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,MAAM,cAAc,IAAI,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,CAAC;AACnD,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,MAAM,CAAC,IAAY,EAAE,KAAa;IAChD,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,kBAAkB,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC1E,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAC1E,CAAC"}
1
+ {"version":3,"file":"checkout.js","sourceRoot":"","sources":["../../src/app/checkout.ts"],"names":[],"mappings":"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"}
@@ -26,6 +26,13 @@ export interface ReviewJob {
26
26
  * a bot commenting on every push to one is the fastest way to be uninstalled.
27
27
  * `ready_for_review` is in the accepted set so the comment appears the moment the
28
28
  * author asks for eyes.
29
+ *
30
+ * A CLOSED pull request is not skipped. The graph is most useful to whoever reads
31
+ * the PR later, and a merged PR is exactly what gets read — so the comment has to
32
+ * keep working after the merge. This costs nothing on live traffic: none of the
33
+ * four accepted actions fire on an already-merged PR, so in practice this only
34
+ * admits a `synchronize` that raced a merge, and a deliberate re-delivery. The
35
+ * accepted-action set, not the PR state, is what bounds the work.
29
36
  */
30
37
  export declare function reviewJobFor(event: string, payload: unknown): {
31
38
  job: ReviewJob;
@@ -1 +1 @@
1
- {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/app/events.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,8DAA8D;AAC9D,MAAM,WAAW,SAAS;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb;;6BAEyB;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,QAAQ,EAAE,OAAO,CAAC;CACnB;AAmBD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG;IAAE,GAAG,EAAE,SAAS,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAqCnG;AAED,sFAAsF;AACtF,eAAO,MAAM,MAAM,GAAI,GAAG,SAAS,KAAG,MAA4C,CAAC"}
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/app/events.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,8DAA8D;AAC9D,MAAM,WAAW,SAAS;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb;;6BAEyB;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,QAAQ,EAAE,OAAO,CAAC;CACnB;AAmBD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG;IAAE,GAAG,EAAE,SAAS,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAoCnG;AAED,sFAAsF;AACtF,eAAO,MAAM,MAAM,GAAI,GAAG,SAAS,KAAG,MAA4C,CAAC"}
@@ -14,6 +14,13 @@ const ACTIONS = new Set(["opened", "synchronize", "reopened", "ready_for_review"
14
14
  * a bot commenting on every push to one is the fastest way to be uninstalled.
15
15
  * `ready_for_review` is in the accepted set so the comment appears the moment the
16
16
  * author asks for eyes.
17
+ *
18
+ * A CLOSED pull request is not skipped. The graph is most useful to whoever reads
19
+ * the PR later, and a merged PR is exactly what gets read — so the comment has to
20
+ * keep working after the merge. This costs nothing on live traffic: none of the
21
+ * four accepted actions fire on an already-merged PR, so in practice this only
22
+ * admits a `synchronize` that raced a merge, and a deliberate re-delivery. The
23
+ * accepted-action set, not the PR state, is what bounds the work.
17
24
  */
18
25
  export function reviewJobFor(event, payload) {
19
26
  if (event === "ping")
@@ -36,8 +43,6 @@ export function reviewJobFor(event, payload) {
36
43
  }
37
44
  if (pr?.draft === true && action !== "ready_for_review")
38
45
  return { skip: "draft" };
39
- if (pr?.state === "closed")
40
- return { skip: "closed" };
41
46
  const base = pr?.base?.repo?.full_name;
42
47
  const head = pr?.head?.repo?.full_name;
43
48
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/app/events.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA+BH,mFAAmF;AACnF,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,aAAa,EAAE,UAAU,EAAE,kBAAkB,CAAC,CAAC,CAAC;AAEnF;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,OAAgB;IAC1D,IAAI,KAAK,KAAK,MAAM;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC9C,IAAI,KAAK,KAAK,cAAc;QAAE,OAAO,EAAE,IAAI,EAAE,SAAS,KAAK,EAAE,EAAE,CAAC;IAEhE,MAAM,CAAC,GAAG,OAAyB,CAAC;IACpC,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC;IAC9B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,UAAU,MAAM,EAAE,EAAE,CAAC;IAE9D,MAAM,EAAE,GAAG,CAAC,CAAC,YAAY,CAAC;IAC1B,MAAM,cAAc,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC;IAC1C,MAAM,KAAK,GAAG,CAAC,CAAC,UAAU,EAAE,KAAK,EAAE,KAAK,CAAC;IACzC,MAAM,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,IAAI,CAAC;IAChC,MAAM,MAAM,GAAG,EAAE,EAAE,MAAM,IAAI,CAAC,CAAC,MAAM,CAAC;IACtC,MAAM,OAAO,GAAG,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC;IAC9B,MAAM,OAAO,GAAG,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC;IAE9B,IAAI,CAAC,cAAc,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;QAC1E,OAAO,EAAE,IAAI,EAAE,iEAAiE,EAAE,CAAC;IACrF,CAAC;IACD,IAAI,EAAE,EAAE,KAAK,KAAK,IAAI,IAAI,MAAM,KAAK,kBAAkB;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAClF,IAAI,EAAE,EAAE,KAAK,KAAK,QAAQ;QAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAEtD,MAAM,IAAI,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,CAAC;IACvC,MAAM,IAAI,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,CAAC;IACvC,OAAO;QACL,GAAG,EAAE;YACH,cAAc;YACd,KAAK;YACL,IAAI;YACJ,MAAM;YACN,OAAO;YACP,OAAO;YACP,0EAA0E;YAC1E,sBAAsB;YACtB,QAAQ,EAAE,IAAI,KAAK,IAAI;SACxB;KACF,CAAC;AACJ,CAAC;AAED,sFAAsF;AACtF,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,CAAY,EAAU,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC"}
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/app/events.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA+BH,mFAAmF;AACnF,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,aAAa,EAAE,UAAU,EAAE,kBAAkB,CAAC,CAAC,CAAC;AAEnF;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,OAAgB;IAC1D,IAAI,KAAK,KAAK,MAAM;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC9C,IAAI,KAAK,KAAK,cAAc;QAAE,OAAO,EAAE,IAAI,EAAE,SAAS,KAAK,EAAE,EAAE,CAAC;IAEhE,MAAM,CAAC,GAAG,OAAyB,CAAC;IACpC,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC;IAC9B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,UAAU,MAAM,EAAE,EAAE,CAAC;IAE9D,MAAM,EAAE,GAAG,CAAC,CAAC,YAAY,CAAC;IAC1B,MAAM,cAAc,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC;IAC1C,MAAM,KAAK,GAAG,CAAC,CAAC,UAAU,EAAE,KAAK,EAAE,KAAK,CAAC;IACzC,MAAM,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,IAAI,CAAC;IAChC,MAAM,MAAM,GAAG,EAAE,EAAE,MAAM,IAAI,CAAC,CAAC,MAAM,CAAC;IACtC,MAAM,OAAO,GAAG,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC;IAC9B,MAAM,OAAO,GAAG,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC;IAE9B,IAAI,CAAC,cAAc,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;QAC1E,OAAO,EAAE,IAAI,EAAE,iEAAiE,EAAE,CAAC;IACrF,CAAC;IACD,IAAI,EAAE,EAAE,KAAK,KAAK,IAAI,IAAI,MAAM,KAAK,kBAAkB;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAElF,MAAM,IAAI,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,CAAC;IACvC,MAAM,IAAI,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,CAAC;IACvC,OAAO;QACL,GAAG,EAAE;YACH,cAAc;YACd,KAAK;YACL,IAAI;YACJ,MAAM;YACN,OAAO;YACP,OAAO;YACP,0EAA0E;YAC1E,sBAAsB;YACtB,QAAQ,EAAE,IAAI,KAAK,IAAI;SACxB;KACF,CAAC;AACJ,CAAC;AAED,sFAAsF;AACtF,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,CAAY,EAAU,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC"}
@@ -0,0 +1,128 @@
1
+ import type { GraphV1 } from "../graph/types.js";
2
+ import type { Fetch } from "./identity.js";
3
+ import type { HistorySource } from "./sources.js";
4
+ /** One commit's rule-bearing content. */
5
+ export interface HistoryCommit {
6
+ sha: string;
7
+ subject: string;
8
+ body: string;
9
+ files: string[];
10
+ }
11
+ /** One pull request's discussion. */
12
+ export interface HistoryThread {
13
+ number: number;
14
+ title: string;
15
+ body: string;
16
+ mergeSha: string;
17
+ comments: Array<{
18
+ body: string;
19
+ path?: string;
20
+ }>;
21
+ }
22
+ /** One symbol, as the brain needs it to anchor a rule. */
23
+ export interface HistorySymbol {
24
+ id: string;
25
+ path: string;
26
+ name: string;
27
+ kind: string;
28
+ signature: string;
29
+ fingerprint: string;
30
+ }
31
+ /** The whole payload posted to the brain. */
32
+ export interface RepoDigest {
33
+ provider: "github";
34
+ owner: string;
35
+ name: string;
36
+ head_sha: string;
37
+ default_branch: string;
38
+ is_private: boolean;
39
+ commits: Array<{
40
+ sha: string;
41
+ subject: string;
42
+ body: string;
43
+ files: string[];
44
+ symbols: string[];
45
+ }>;
46
+ threads: Array<{
47
+ number: number;
48
+ title: string;
49
+ body: string;
50
+ merge_sha: string;
51
+ comments: Array<{
52
+ body: string;
53
+ path?: string;
54
+ }>;
55
+ }>;
56
+ symbols: HistorySymbol[];
57
+ /** Everything in the repo that is already a rule, or nearly one: instruction
58
+ * files, decision records, config, ownership, reverts, test names. One array
59
+ * rather than a field per kind, so adding a source is adding an entry. */
60
+ sources: HistorySource[];
61
+ auto_approve: boolean;
62
+ }
63
+ /**
64
+ * Commit subjects, bodies and touched files, oldest first.
65
+ *
66
+ * `--no-merges`: a merge commit's message is "Merge pull request #N from …",
67
+ * which establishes nothing — the decision is in the commits it brings in, and
68
+ * in the thread. `--reverse` so a later reversal reads as a reversal downstream;
69
+ * the extraction prompt relies on that ordering.
70
+ */
71
+ export declare function readCommits(root: string, max?: number): HistoryCommit[];
72
+ /**
73
+ * Closed pull requests and their discussion, most-discussed first.
74
+ *
75
+ * Closed only: an open PR's discussion has not concluded, so mining a rule out
76
+ * of it would record a proposal as a decision.
77
+ *
78
+ * Comment counts have to be discovered by fetching, not by reading the list.
79
+ * GitHub's `GET /pulls` list response carries NO `comments` or
80
+ * `review_comments` field — those exist only on the single-PR GET — so an
81
+ * earlier version that pre-filtered on them read `undefined` for every pull
82
+ * request, scored them all zero and skipped the lot. The failure was silent and
83
+ * total: every repository came back with no discussion at all. So the comments
84
+ * are fetched for the most recently updated closed pull requests, and the
85
+ * ranking happens afterwards, on counts that are real.
86
+ *
87
+ * Bot comments are dropped. A CI bot posting a coverage table is the single
88
+ * largest source of text in a busy repo's threads and it establishes nothing.
89
+ */
90
+ export declare function readThreads(owner: string, repo: string, token: string, fetchImpl: Fetch, api?: string, max?: number): Promise<HistoryThread[]>;
91
+ /**
92
+ * Exported symbols from the graph, with the body hash that makes an anchored
93
+ * rule self-invalidating.
94
+ *
95
+ * Exported only, and biggest first: an internal helper is not what a team's
96
+ * rules are about, and the budget is better spent on the surface a rule is
97
+ * likely to govern.
98
+ */
99
+ export declare function readSymbols(graph: GraphV1 | null, max?: number): HistorySymbol[];
100
+ /**
101
+ * Assemble the digest.
102
+ *
103
+ * Each commit carries the symbol ids its files touched, so a rule mined from a
104
+ * commit message can be anchored even when the message names no symbol — which
105
+ * is most of the time.
106
+ */
107
+ export declare function buildDigest(input: {
108
+ owner: string;
109
+ name: string;
110
+ headSha: string;
111
+ defaultBranch: string;
112
+ isPrivate: boolean;
113
+ commits: HistoryCommit[];
114
+ threads: HistoryThread[];
115
+ symbols: HistorySymbol[];
116
+ sources: HistorySource[];
117
+ autoApprove: boolean;
118
+ }): RepoDigest;
119
+ /**
120
+ * Post the digest to a brain.
121
+ *
122
+ * Returns the job id so the caller can hand it back to whoever asked for the
123
+ * build, which is what the onboarding screen polls.
124
+ */
125
+ export declare function postDigest(baseUrl: string, brainId: string, brainToken: string, digest: RepoDigest, fetchImpl: Fetch): Promise<{
126
+ jobId: string;
127
+ }>;
128
+ //# sourceMappingURL=history.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/app/history.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,269 @@
1
+ /**
2
+ * Reading a repository's history into a rule-bearing digest.
3
+ *
4
+ * What a code graph cannot tell you is why the code is the way it is. That
5
+ * lives in two places: commit messages, and the discussion under pull requests.
6
+ * This module reads both, plus the symbol ids from the graph so a rule mined
7
+ * out of them can be anchored to the code it governs.
8
+ *
9
+ * It deliberately sends NO source code onward. The digest is messages, titles,
10
+ * comments, symbol ids and hashes — nothing a reader could reconstruct a private
11
+ * codebase from.
12
+ */
13
+ import { spawnSync } from "node:child_process";
14
+ /** Field separators inside one `git log` record. Chosen for being bytes no
15
+ * commit message contains, the same trick blast/owners.ts uses. */
16
+ const REC = "\x01";
17
+ const FIELD = "\x02";
18
+ /** Most commits read out of one repository. Above the brain's own per-ingest
19
+ * cap, so the trim happens here where the ordering is known. */
20
+ const MAX_COMMITS = 1_000;
21
+ /** Run git in `root`, or null when git fails. */
22
+ function git(root, args) {
23
+ const res = spawnSync("git", ["-c", "core.quotePath=false", ...args], {
24
+ cwd: root,
25
+ encoding: "utf8",
26
+ stdio: ["ignore", "pipe", "pipe"],
27
+ maxBuffer: 64 * 1024 * 1024,
28
+ });
29
+ if (res.error || res.status !== 0 || typeof res.stdout !== "string")
30
+ return null;
31
+ return res.stdout;
32
+ }
33
+ /**
34
+ * Commit subjects, bodies and touched files, oldest first.
35
+ *
36
+ * `--no-merges`: a merge commit's message is "Merge pull request #N from …",
37
+ * which establishes nothing — the decision is in the commits it brings in, and
38
+ * in the thread. `--reverse` so a later reversal reads as a reversal downstream;
39
+ * the extraction prompt relies on that ordering.
40
+ */
41
+ export function readCommits(root, max = MAX_COMMITS) {
42
+ const fmt = `${REC}%H${FIELD}%s${FIELD}%b${FIELD}`;
43
+ const out = git(root, [
44
+ "log",
45
+ "--no-merges",
46
+ "--reverse",
47
+ `-n`,
48
+ String(max),
49
+ `--format=${fmt}`,
50
+ "--name-only",
51
+ ]);
52
+ if (!out)
53
+ return [];
54
+ const commits = [];
55
+ for (const record of out.split(REC)) {
56
+ if (!record.trim())
57
+ continue;
58
+ const [sha = "", subject = "", body = "", rest = ""] = record.split(FIELD);
59
+ const files = rest
60
+ .split("\n")
61
+ .map((l) => l.trim())
62
+ .filter((l) => l !== "");
63
+ // A commit with no subject is a broken record, not a commit worth mining.
64
+ if (!sha.trim() || !subject.trim())
65
+ continue;
66
+ commits.push({ sha: sha.trim(), subject: subject.trim(), body: body.trim(), files });
67
+ }
68
+ return commits;
69
+ }
70
+ /** How many pull requests to read, and how many comment pages per thread. */
71
+ const MAX_THREADS = 200;
72
+ const MAX_COMMENT_PAGES = 3;
73
+ /** How many threads' comments are fetched at once. Two requests per pull
74
+ * request, so this is the real cost of a repository read; 8 keeps it quick
75
+ * without crowding an installation's rate limit. */
76
+ const THREAD_FETCH_CONCURRENCY = 8;
77
+ /**
78
+ * Closed pull requests and their discussion, most-discussed first.
79
+ *
80
+ * Closed only: an open PR's discussion has not concluded, so mining a rule out
81
+ * of it would record a proposal as a decision.
82
+ *
83
+ * Comment counts have to be discovered by fetching, not by reading the list.
84
+ * GitHub's `GET /pulls` list response carries NO `comments` or
85
+ * `review_comments` field — those exist only on the single-PR GET — so an
86
+ * earlier version that pre-filtered on them read `undefined` for every pull
87
+ * request, scored them all zero and skipped the lot. The failure was silent and
88
+ * total: every repository came back with no discussion at all. So the comments
89
+ * are fetched for the most recently updated closed pull requests, and the
90
+ * ranking happens afterwards, on counts that are real.
91
+ *
92
+ * Bot comments are dropped. A CI bot posting a coverage table is the single
93
+ * largest source of text in a busy repo's threads and it establishes nothing.
94
+ */
95
+ export async function readThreads(owner, repo, token, fetchImpl, api = "https://api.github.com", max = MAX_THREADS) {
96
+ const headers = {
97
+ authorization: `Bearer ${token}`,
98
+ accept: "application/vnd.github+json",
99
+ "user-agent": "graft-app",
100
+ };
101
+ const pulls = [];
102
+ // 100 per page, up to the cap. Sorted by GitHub as most-recently-updated,
103
+ // which is the right window: rules decided two years ago that still hold get
104
+ // restated in newer threads, and ones that do not are usually superseded.
105
+ for (let page = 1; pulls.length < max && page <= Math.ceil(max / 100); page++) {
106
+ const res = await fetchImpl(`${api}/repos/${owner}/${repo}/pulls?state=closed&sort=updated&direction=desc&per_page=100&page=${page}`, { headers });
107
+ if (!res.ok)
108
+ break;
109
+ const batch = JSON.parse(await res.text());
110
+ if (!Array.isArray(batch) || batch.length === 0)
111
+ break;
112
+ pulls.push(...batch);
113
+ }
114
+ const candidates = pulls.filter((p) => typeof p.number === "number").slice(0, max);
115
+ // Bounded concurrency rather than one at a time: two requests per pull
116
+ // request over 200 of them is 400 sequential round trips, which is minutes of
117
+ // a person waiting on a progress screen.
118
+ const threads = [];
119
+ for (let i = 0; i < candidates.length; i += THREAD_FETCH_CONCURRENCY) {
120
+ const slice = candidates.slice(i, i + THREAD_FETCH_CONCURRENCY);
121
+ const fetched = await Promise.all(slice.map(async (p) => {
122
+ const [issueComments, reviewComments] = await Promise.all([
123
+ readComments(`${api}/repos/${owner}/${repo}/issues/${p.number}/comments`, headers, fetchImpl),
124
+ readComments(`${api}/repos/${owner}/${repo}/pulls/${p.number}/comments`, headers, fetchImpl),
125
+ ]);
126
+ const comments = [...issueComments, ...reviewComments];
127
+ if (comments.length === 0)
128
+ return null;
129
+ return {
130
+ number: p.number,
131
+ title: (p.title ?? "").trim(),
132
+ body: (p.body ?? "").trim(),
133
+ mergeSha: (p.merge_commit_sha ?? "").trim(),
134
+ comments,
135
+ };
136
+ }));
137
+ for (const t of fetched)
138
+ if (t)
139
+ threads.push(t);
140
+ }
141
+ // Most-discussed first, because the digest renderer spends its budget in this
142
+ // order and a twenty-comment thread contains an argument while a one-comment
143
+ // thread contains a rubber stamp.
144
+ threads.sort((a, b) => b.comments.length - a.comments.length);
145
+ return threads;
146
+ }
147
+ /** One comment endpoint, paginated, bots removed. */
148
+ async function readComments(url, headers, fetchImpl) {
149
+ const out = [];
150
+ for (let page = 1; page <= MAX_COMMENT_PAGES; page++) {
151
+ const res = await fetchImpl(`${url}?per_page=100&page=${page}`, { headers });
152
+ if (!res.ok)
153
+ break;
154
+ let batch;
155
+ try {
156
+ batch = JSON.parse(await res.text());
157
+ }
158
+ catch {
159
+ break;
160
+ }
161
+ if (!Array.isArray(batch) || batch.length === 0)
162
+ break;
163
+ for (const c of batch) {
164
+ const body = (c.body ?? "").trim();
165
+ if (!body)
166
+ continue;
167
+ if (c.user?.type === "Bot")
168
+ continue;
169
+ out.push(c.path ? { body, path: c.path } : { body });
170
+ }
171
+ if (batch.length < 100)
172
+ break;
173
+ }
174
+ return out;
175
+ }
176
+ /** Most symbols to send. The brain only needs enough to anchor rules against. */
177
+ const MAX_SYMBOLS = 4_000;
178
+ /**
179
+ * Exported symbols from the graph, with the body hash that makes an anchored
180
+ * rule self-invalidating.
181
+ *
182
+ * Exported only, and biggest first: an internal helper is not what a team's
183
+ * rules are about, and the budget is better spent on the surface a rule is
184
+ * likely to govern.
185
+ */
186
+ export function readSymbols(graph, max = MAX_SYMBOLS) {
187
+ if (!graph)
188
+ return [];
189
+ return graph.nodes
190
+ .filter((n) => n.exported && n.kind !== "file")
191
+ .sort((a, b) => (b.chars ?? 0) - (a.chars ?? 0))
192
+ .slice(0, max)
193
+ .map((n) => ({
194
+ id: n.id,
195
+ path: n.path,
196
+ name: n.name,
197
+ kind: n.kind,
198
+ signature: n.signature ?? "",
199
+ fingerprint: n.body_hash,
200
+ }));
201
+ }
202
+ /**
203
+ * Assemble the digest.
204
+ *
205
+ * Each commit carries the symbol ids its files touched, so a rule mined from a
206
+ * commit message can be anchored even when the message names no symbol — which
207
+ * is most of the time.
208
+ */
209
+ export function buildDigest(input) {
210
+ const byPath = new Map();
211
+ for (const s of input.symbols) {
212
+ const bucket = byPath.get(s.path);
213
+ if (bucket)
214
+ bucket.push(s.id);
215
+ else
216
+ byPath.set(s.path, [s.id]);
217
+ }
218
+ return {
219
+ provider: "github",
220
+ owner: input.owner,
221
+ name: input.name,
222
+ head_sha: input.headSha,
223
+ default_branch: input.defaultBranch,
224
+ is_private: input.isPrivate,
225
+ commits: input.commits.map((c) => ({
226
+ sha: c.sha,
227
+ subject: c.subject,
228
+ body: c.body,
229
+ files: c.files,
230
+ // Capped per commit: a sweeping refactor touches hundreds of files, and
231
+ // listing every symbol in all of them would drown the message it belongs to.
232
+ symbols: c.files.flatMap((f) => byPath.get(f) ?? []).slice(0, 20),
233
+ })),
234
+ threads: input.threads.map((t) => ({
235
+ number: t.number,
236
+ title: t.title,
237
+ body: t.body,
238
+ merge_sha: t.mergeSha,
239
+ comments: t.comments,
240
+ })),
241
+ symbols: input.symbols,
242
+ sources: input.sources,
243
+ auto_approve: input.autoApprove,
244
+ };
245
+ }
246
+ /**
247
+ * Post the digest to a brain.
248
+ *
249
+ * Returns the job id so the caller can hand it back to whoever asked for the
250
+ * build, which is what the onboarding screen polls.
251
+ */
252
+ export async function postDigest(baseUrl, brainId, brainToken, digest, fetchImpl) {
253
+ const res = await fetchImpl(`${baseUrl.replace(/\/+$/, "")}/api/brains/${encodeURIComponent(brainId)}/repo`, {
254
+ method: "POST",
255
+ headers: {
256
+ authorization: `Bearer ${brainToken}`,
257
+ "content-type": "application/json",
258
+ accept: "application/json",
259
+ },
260
+ body: JSON.stringify(digest),
261
+ });
262
+ const text = await res.text();
263
+ if (!res.ok) {
264
+ throw new Error(`brain ingest failed: ${res.status} ${text.slice(0, 300)}`);
265
+ }
266
+ const parsed = JSON.parse(text);
267
+ return { jobId: String(parsed.job_id ?? "") };
268
+ }
269
+ //# sourceMappingURL=history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/app/history.ts"],"names":[],"mappings":"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"}
@@ -31,6 +31,39 @@ export type Fetch = (url: string, init?: {
31
31
  * Tokens last an hour and a busy repository can fire a dozen webhooks a minute;
32
32
  * without the cache every one of them spends a round trip and a signature.
33
33
  */
34
+ /**
35
+ * The installation id for one repository.
36
+ *
37
+ * Every existing caller gets the id from a webhook payload, because every
38
+ * existing caller is reacting to one. A request that names a repository instead
39
+ * has to look it up, and this is the only endpoint that answers it: it is
40
+ * App-JWT authed, so it works before any installation token exists.
41
+ *
42
+ * Returns null when the App is not installed on the repository — which is the
43
+ * expected answer for "the user pasted a repo we cannot see", not an error.
44
+ */
45
+ export declare function installationFor(creds: AppCredentials, owner: string, repo: string, fetchImpl: Fetch, nowMs?: number, api?: string): Promise<number | null>;
46
+ /**
47
+ * Why a repository is unreachable, and where to send the user to fix it.
48
+ *
49
+ * Two failures look identical from `/repos/{o}/{r}/installation` — both 404 —
50
+ * and they need different sentences and different links. Either the App is not
51
+ * on the account at all, so they install it; or it is installed and this
52
+ * repository simply is not in its selected list, so they edit that list. Telling
53
+ * someone to install an App they already installed is the kind of dead end that
54
+ * ends the session.
55
+ *
56
+ * ownerId is the account's numeric id, which preselects the right account on
57
+ * GitHub's install screen. There is no equivalent for preselecting a repository;
58
+ * GitHub owns that checkbox list.
59
+ */
60
+ export interface RepoAccessGap {
61
+ reason: "not_installed" | "repo_not_selected";
62
+ ownerId: number | null;
63
+ installationId: number | null;
64
+ }
65
+ /** Which of the two gaps applies to owner/repo. */
66
+ export declare function repoAccessGap(creds: AppCredentials, owner: string, fetchImpl: Fetch, nowMs?: number, api?: string): Promise<RepoAccessGap>;
34
67
  export declare class InstallationTokens {
35
68
  private readonly creds;
36
69
  private readonly fetchImpl;
@@ -1 +1 @@
1
- {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/app/identity.ts"],"names":[],"mappings":"AAuBA,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAOnE;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,iFAAiF;AACjF,MAAM,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK,OAAO,CAAC;IACxH,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CAC7B,CAAC,CAAC;AAOH;;;;;GAKG;AACH,qBAAa,kBAAkB;IAI3B,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,GAAG;IANtB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiC;gBAGpC,KAAK,EAAE,cAAc,EACrB,SAAS,EAAE,KAAK,EAChB,GAAG,GAAE,MAAM,MAAiB,EAC5B,GAAG,SAA2B;IAG3C,GAAG,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAuBlD,8EAA8E;IAC9E,UAAU,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI;CAGzC;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAMjG"}
1
+ {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/app/identity.ts"],"names":[],"mappings":"AAuBA,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAOnE;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,iFAAiF;AACjF,MAAM,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK,OAAO,CAAC;IACxH,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CAC7B,CAAC,CAAC;AAOH;;;;;GAKG;AACH;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,cAAc,EACrB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,KAAK,EAChB,KAAK,GAAE,MAAmB,EAC1B,GAAG,SAA2B,GAC7B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAexB;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,eAAe,GAAG,mBAAmB,CAAC;IAC9C,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,mDAAmD;AACnD,wBAAsB,aAAa,CACjC,KAAK,EAAE,cAAc,EACrB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,KAAK,EAChB,KAAK,GAAE,MAAmB,EAC1B,GAAG,SAA2B,GAC7B,OAAO,CAAC,aAAa,CAAC,CAwBxB;AAiBD,qBAAa,kBAAkB;IAI3B,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,GAAG;IANtB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiC;gBAGpC,KAAK,EAAE,cAAc,EACrB,SAAS,EAAE,KAAK,EAChB,GAAG,GAAE,MAAM,MAAiB,EAC5B,GAAG,SAA2B;IAG3C,GAAG,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAuBlD,8EAA8E;IAC9E,UAAU,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI;CAGzC;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAMjG"}
@@ -38,6 +38,78 @@ export function appJwt(creds, nowMs) {
38
38
  * Tokens last an hour and a busy repository can fire a dozen webhooks a minute;
39
39
  * without the cache every one of them spends a round trip and a signature.
40
40
  */
41
+ /**
42
+ * The installation id for one repository.
43
+ *
44
+ * Every existing caller gets the id from a webhook payload, because every
45
+ * existing caller is reacting to one. A request that names a repository instead
46
+ * has to look it up, and this is the only endpoint that answers it: it is
47
+ * App-JWT authed, so it works before any installation token exists.
48
+ *
49
+ * Returns null when the App is not installed on the repository — which is the
50
+ * expected answer for "the user pasted a repo we cannot see", not an error.
51
+ */
52
+ export async function installationFor(creds, owner, repo, fetchImpl, nowMs = Date.now(), api = "https://api.github.com") {
53
+ const res = await fetchImpl(`${api}/repos/${owner}/${repo}/installation`, {
54
+ headers: {
55
+ authorization: `Bearer ${appJwt(creds, nowMs)}`,
56
+ accept: "application/vnd.github+json",
57
+ "user-agent": "graft-app",
58
+ },
59
+ });
60
+ if (res.status === 404)
61
+ return null;
62
+ if (!res.ok) {
63
+ const body = await res.text();
64
+ throw new Error(`installation lookup for ${owner}/${repo} failed: ${res.status} ${body.slice(0, 200)}`);
65
+ }
66
+ const parsed = JSON.parse(await res.text());
67
+ return typeof parsed.id === "number" ? parsed.id : null;
68
+ }
69
+ /** Which of the two gaps applies to owner/repo. */
70
+ export async function repoAccessGap(creds, owner, fetchImpl, nowMs = Date.now(), api = "https://api.github.com") {
71
+ const headers = {
72
+ authorization: `Bearer ${appJwt(creds, nowMs)}`,
73
+ accept: "application/vnd.github+json",
74
+ "user-agent": "graft-app",
75
+ };
76
+ // An account is an org or a user and the endpoints differ, so try the org one
77
+ // and fall back rather than making the caller know which it is.
78
+ for (const path of [`/orgs/${owner}/installation`, `/users/${owner}/installation`]) {
79
+ try {
80
+ const res = await fetchImpl(`${api}${path}`, { headers });
81
+ if (!res.ok)
82
+ continue;
83
+ const parsed = JSON.parse(await res.text());
84
+ return {
85
+ reason: "repo_not_selected",
86
+ ownerId: parsed.account?.id ?? null,
87
+ installationId: parsed.id ?? null,
88
+ };
89
+ }
90
+ catch {
91
+ // Try the other shape; a network failure here only costs a less specific
92
+ // message, never the whole answer.
93
+ }
94
+ }
95
+ return { reason: "not_installed", ownerId: await ownerIdFor(owner, fetchImpl, api), installationId: null };
96
+ }
97
+ /** The account's numeric id, for preselecting it on the install screen. */
98
+ async function ownerIdFor(owner, fetchImpl, api) {
99
+ try {
100
+ // Unauthenticated: a public account's id is public, and this runs on a path
101
+ // where the App has no installation token to use anyway.
102
+ const res = await fetchImpl(`${api}/users/${owner}`, {
103
+ headers: { accept: "application/vnd.github+json", "user-agent": "graft-app" },
104
+ });
105
+ if (!res.ok)
106
+ return null;
107
+ return JSON.parse(await res.text()).id ?? null;
108
+ }
109
+ catch {
110
+ return null;
111
+ }
112
+ }
41
113
  export class InstallationTokens {
42
114
  creds;
43
115
  fetchImpl;