pulls.review 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/dist/client/assets/ChatWidget-BsnoQ6oS.js +1 -0
  2. package/dist/client/assets/DisplayFileIcon-DzBo3Ez5.js +151 -0
  3. package/dist/client/assets/GithubAvatar-CSsUV5vf.js +1 -0
  4. package/dist/client/assets/LandingHero-BkTBSu71.js +1 -0
  5. package/dist/client/assets/_repo_-Dcgj3PGg.js +22 -0
  6. package/dist/client/assets/analyze-509KQQBC.js +1 -0
  7. package/dist/client/assets/andromeeda-vGVdxbeo.js +1 -0
  8. package/dist/client/assets/anthropic-messages-Cd2DkgOC.js +41 -0
  9. package/dist/client/assets/aurora-x-CDeNXAV0.js +1 -0
  10. package/dist/client/assets/ayu-dark-DluEY0Gj.js +1 -0
  11. package/dist/client/assets/ayu-light-C3h-C4tm.js +1 -0
  12. package/dist/client/assets/ayu-mirage-Bqwy1Gya.js +1 -0
  13. package/dist/client/assets/browser-agent-rpc-BXhoSh1z-DrxWeI3_.js +1 -0
  14. package/dist/client/assets/c-BNQJhXlP.js +1 -0
  15. package/dist/client/assets/catppuccin-frappe-C9Q5zVZY.js +1 -0
  16. package/dist/client/assets/catppuccin-latte-CtsyrtPq.js +1 -0
  17. package/dist/client/assets/catppuccin-macchiato-R8nAf1vR.js +1 -0
  18. package/dist/client/assets/catppuccin-mocha-DjuaAJKi.js +1 -0
  19. package/dist/client/assets/clojure-DqKBuwfJ.js +1 -0
  20. package/dist/client/assets/cpp-7GgD5o7L.js +1 -0
  21. package/dist/client/assets/csharp-oqKa8noW.js +1 -0
  22. package/dist/client/assets/css-DlBQoFxe.js +1 -0
  23. package/dist/client/assets/dark-plus-Cs2F2srj.js +1 -0
  24. package/dist/client/assets/de-Bq9RfdAn.js +1 -0
  25. package/dist/client/assets/diff-BKQFn0my.js +37 -0
  26. package/dist/client/assets/diff-Bx6SazPw.js +1 -0
  27. package/dist/client/assets/diff-woXpYk--.js +1 -0
  28. package/dist/client/assets/diffs-store-ncE62OUU.js +1510 -0
  29. package/dist/client/assets/dist-Dh0a8u-Y.js +1 -0
  30. package/dist/client/assets/docker-IyjqRm3v.js +1 -0
  31. package/dist/client/assets/dracula-BHWKrbxM.js +1 -0
  32. package/dist/client/assets/dracula-soft-5eyTD99u.js +1 -0
  33. package/dist/client/assets/elixir-D3n0XgqJ.js +1 -0
  34. package/dist/client/assets/en-8hQdak1X.js +1 -0
  35. package/dist/client/assets/error-CJ3RHG07.js +1 -0
  36. package/dist/client/assets/es-QcvEBShr.js +1 -0
  37. package/dist/client/assets/everforest-dark-sB-x3p7T.js +1 -0
  38. package/dist/client/assets/everforest-light-Df2xbC6M.js +1 -0
  39. package/dist/client/assets/fr-DAWKVvDP.js +1 -0
  40. package/dist/client/assets/github-dark-C-LZuMrd.js +1 -0
  41. package/dist/client/assets/github-dark-default-DXG-b-1a.js +1 -0
  42. package/dist/client/assets/github-dark-dimmed-Bx1FflLF.js +1 -0
  43. package/dist/client/assets/github-dark-high-contrast-B_tTalzw.js +1 -0
  44. package/dist/client/assets/github-light-EUqPIrTm.js +1 -0
  45. package/dist/client/assets/github-light-default-BXViO-2h.js +1 -0
  46. package/dist/client/assets/github-light-high-contrast-B68TUdTA.js +1 -0
  47. package/dist/client/assets/go-rLFTqkRN.js +1 -0
  48. package/dist/client/assets/graphql-ki1Ij_uk.js +1 -0
  49. package/dist/client/assets/groovy-CacY0gHj.js +1 -0
  50. package/dist/client/assets/gruvbox-dark-hard-C820rvS2.js +1 -0
  51. package/dist/client/assets/gruvbox-dark-medium-BPjhmG05.js +1 -0
  52. package/dist/client/assets/gruvbox-dark-soft-MrdJrrXF.js +1 -0
  53. package/dist/client/assets/gruvbox-light-hard-BC_s9l72.js +1 -0
  54. package/dist/client/assets/gruvbox-light-medium-BAWPOn9u.js +1 -0
  55. package/dist/client/assets/gruvbox-light-soft-BSMLrYjP.js +1 -0
  56. package/dist/client/assets/haskell-D8IpX4py.js +1 -0
  57. package/dist/client/assets/horizon-CE9ld1lL.js +1 -0
  58. package/dist/client/assets/horizon-bright-DSNQnXHK.js +1 -0
  59. package/dist/client/assets/houston-CsvMBhTu.js +1 -0
  60. package/dist/client/assets/html-BC8aFsRK.js +1 -0
  61. package/dist/client/assets/i18n-CGV_MDS8.js +2 -0
  62. package/dist/client/assets/id-NIGs9Xhn.js +1 -0
  63. package/dist/client/assets/index-BCCy9wJJ.js +2 -0
  64. package/dist/client/assets/index-BDPZiDIt.css +1 -0
  65. package/dist/client/assets/ini-B5eOa1yu.js +1 -0
  66. package/dist/client/assets/install-B-q5w2uE.js +4 -0
  67. package/dist/client/assets/it-DjRuurmk.js +1 -0
  68. package/dist/client/assets/ja-BAKkDsQ5.js +1 -0
  69. package/dist/client/assets/java-D7h0NA_A.js +1 -0
  70. package/dist/client/assets/javascript-DcMHgNcu.js +1 -0
  71. package/dist/client/assets/json-qhed-kSA.js +1 -0
  72. package/dist/client/assets/jsonc-CYpm1nAK.js +1 -0
  73. package/dist/client/assets/jsx-BUUYi3qs.js +1 -0
  74. package/dist/client/assets/kanagawa-dragon-Bozd7klA.js +1 -0
  75. package/dist/client/assets/kanagawa-lotus-BmuOG9ZW.js +1 -0
  76. package/dist/client/assets/kanagawa-wave-BML5mF2J.js +1 -0
  77. package/dist/client/assets/ko-DHculY2W.js +1 -0
  78. package/dist/client/assets/kotlin-DhhofPvG.js +1 -0
  79. package/dist/client/assets/laserwave-C_8bwKvT.js +1 -0
  80. package/dist/client/assets/less-DVTAwKKz.js +1 -0
  81. package/dist/client/assets/light-plus-DVQuIRkW.js +1 -0
  82. package/dist/client/assets/llm-DYDmh8Ki.js +2 -0
  83. package/dist/client/assets/llm-store-CVM33nlB.js +2 -0
  84. package/dist/client/assets/locales-SpkpwNqX.js +1 -0
  85. package/dist/client/assets/lua-DCW0Dwo5.js +1 -0
  86. package/dist/client/assets/make-Dixweg8N.js +1 -0
  87. package/dist/client/assets/markdown-BYOwaDjH.js +1 -0
  88. package/dist/client/assets/material-theme-Bm3Qr25_.js +1 -0
  89. package/dist/client/assets/material-theme-darker-2IIEA8gg.js +1 -0
  90. package/dist/client/assets/material-theme-lighter-uhdI0v04.js +1 -0
  91. package/dist/client/assets/material-theme-ocean-CHQ94UKr.js +1 -0
  92. package/dist/client/assets/material-theme-palenight-B5W6OYN7.js +1 -0
  93. package/dist/client/assets/mdx-DQZ5AkYe.js +1 -0
  94. package/dist/client/assets/min-dark-BSWPekZh.js +1 -0
  95. package/dist/client/assets/min-light-DDpmG2fV.js +1 -0
  96. package/dist/client/assets/monokai-B_bV9PQ9.js +1 -0
  97. package/dist/client/assets/nginx-C4fSytnP.js +1 -0
  98. package/dist/client/assets/night-owl-DhmEMT88.js +1 -0
  99. package/dist/client/assets/night-owl-light-eJ-hLW7d.js +1 -0
  100. package/dist/client/assets/node.browser-BX-QLlU2.js +1 -0
  101. package/dist/client/assets/node.browser-DFtqp6Hr.js +1 -0
  102. package/dist/client/assets/nord-Cb4Vim4T.js +1 -0
  103. package/dist/client/assets/objective-c-D1A_Heim.js +1 -0
  104. package/dist/client/assets/objective-cpp-BsSzOQcm.js +1 -0
  105. package/dist/client/assets/one-dark-pro-CLwyXe_n.js +1 -0
  106. package/dist/client/assets/one-light-D7Lr4KcI.js +1 -0
  107. package/dist/client/assets/openai-completions-CSvY9IVo.js +21 -0
  108. package/dist/client/assets/pages-B5mEqsbn.js +1 -0
  109. package/dist/client/assets/pages-local-x_ACBinc.js +1 -0
  110. package/dist/client/assets/pages-web-DitAPN6U.js +21 -0
  111. package/dist/client/assets/patch-parser-k3Vbbmi0.js +5 -0
  112. package/dist/client/assets/perl-C8GHouAq.js +1 -0
  113. package/dist/client/assets/php-BahmaYs0.js +1 -0
  114. package/dist/client/assets/pierre-dark-CpLgRqie.js +1 -0
  115. package/dist/client/assets/pierre-dark-protanopia-deuteranopia-B35FxJx-.js +1 -0
  116. package/dist/client/assets/pierre-dark-soft-kZQmAZld.js +1 -0
  117. package/dist/client/assets/pierre-dark-tritanopia-CpjhbsIL.js +1 -0
  118. package/dist/client/assets/pierre-dark-vibrant-CpQYzh95.js +1 -0
  119. package/dist/client/assets/pierre-light-CoaEpmwp.js +1 -0
  120. package/dist/client/assets/pierre-light-protanopia-deuteranopia-0fSaH845.js +1 -0
  121. package/dist/client/assets/pierre-light-soft-lWLdNTOI.js +1 -0
  122. package/dist/client/assets/pierre-light-tritanopia-CEbqgOJL.js +1 -0
  123. package/dist/client/assets/pierre-light-vibrant-D80Fkn33.js +1 -0
  124. package/dist/client/assets/plastic-DQwYfKfQ.js +1 -0
  125. package/dist/client/assets/poimandres-DRFjx7u4.js +1 -0
  126. package/dist/client/assets/portalTarget-C60SzJiK.js +1 -0
  127. package/dist/client/assets/preload-helper-BaNbYf_w.js +1 -0
  128. package/dist/client/assets/proto-DB4EqR-F.js +1 -0
  129. package/dist/client/assets/pt-BR-LLtJ99P6.js +1 -0
  130. package/dist/client/assets/python-gzcpVVnB.js +1 -0
  131. package/dist/client/assets/r-C5FwQflr.js +1 -0
  132. package/dist/client/assets/red-DX1BQOs8.js +1 -0
  133. package/dist/client/assets/rolldown-runtime-Dd_uD5pT.js +1 -0
  134. package/dist/client/assets/rose-pine-aMsaMD1D.js +1 -0
  135. package/dist/client/assets/rose-pine-dawn-8PwUyIlP.js +1 -0
  136. package/dist/client/assets/rose-pine-moon-DO-qXg-I.js +1 -0
  137. package/dist/client/assets/ru-DvkrOLxc.js +1 -0
  138. package/dist/client/assets/ruby-CfFGiaYl.js +1 -0
  139. package/dist/client/assets/runtime-dom.esm-bundler-CqL7__VR.js +2 -0
  140. package/dist/client/assets/rust-Cfkwpbl8.js +1 -0
  141. package/dist/client/assets/scala-BiFt_7mu.js +1 -0
  142. package/dist/client/assets/scss-C-_0yqZd.js +1 -0
  143. package/dist/client/assets/shellscript-CLZ0U2zV.js +1 -0
  144. package/dist/client/assets/shiki-wasm-noop-Gxv9UHE7.js +1 -0
  145. package/dist/client/assets/slack-dark-DnToyrRv.js +1 -0
  146. package/dist/client/assets/slack-ochin-B2OO5cIa.js +1 -0
  147. package/dist/client/assets/snazzy-light-4G7pJPwS.js +1 -0
  148. package/dist/client/assets/solarized-dark-UdsmMDCL.js +1 -0
  149. package/dist/client/assets/solarized-light-C1IUL_tW.js +1 -0
  150. package/dist/client/assets/source-hSji-yvG.js +2 -0
  151. package/dist/client/assets/sql-BsFa4tDR.js +1 -0
  152. package/dist/client/assets/swift-CyEgAFGc.js +1 -0
  153. package/dist/client/assets/synthwave-84-nFMaYfgc.js +1 -0
  154. package/dist/client/assets/terraform-DswuEJGm.js +1 -0
  155. package/dist/client/assets/time-ago-Bdao9Hh1.js +1 -0
  156. package/dist/client/assets/tokyo-night-oM2G3aXe.js +1 -0
  157. package/dist/client/assets/toml-CcmNWLt0.js +1 -0
  158. package/dist/client/assets/transform-messages-C8U1xonk.js +3 -0
  159. package/dist/client/assets/tsx-DvWhG4dC.js +1 -0
  160. package/dist/client/assets/typescript-BTGs5etX.js +1 -0
  161. package/dist/client/assets/upload-GnI9kmJu.js +1 -0
  162. package/dist/client/assets/uploadSession-BUj4FNau.js +1 -0
  163. package/dist/client/assets/useDocumentTitle-nuqxXiNo.js +185 -0
  164. package/dist/client/assets/vesper-DdrHHSXu.js +1 -0
  165. package/dist/client/assets/vitesse-black-fwtXNY1n.js +1 -0
  166. package/dist/client/assets/vitesse-dark-BZCL-v6S.js +1 -0
  167. package/dist/client/assets/vitesse-light-VbXTXTou.js +1 -0
  168. package/dist/client/assets/vue-BbYmdtmv.js +1 -0
  169. package/dist/client/assets/vue-html-BXjKVtKk.js +1 -0
  170. package/dist/client/assets/vue-i18n-DVI_S4Q5.js +5 -0
  171. package/dist/client/assets/xml-BsprbK0m.js +1 -0
  172. package/dist/client/assets/yaml-rwi0_p6S.js +1 -0
  173. package/dist/client/assets/zh-CN-BIibd6kG.js +1 -0
  174. package/dist/client/assets/zh-TW-3FtUHjoZ.js +1 -0
  175. package/dist/client/favicon.svg +1 -0
  176. package/dist/client/index.html +44 -0
  177. package/dist/client/og-dark.png +0 -0
  178. package/dist/client/og.png +0 -0
  179. package/dist/client/robots.txt +2 -0
  180. package/dist/devframe-CX5butdC.mjs +493 -0
  181. package/dist/devframe.mjs +2 -0
  182. package/dist/index.mjs +90 -0
  183. package/package.json +2 -2
@@ -0,0 +1,2 @@
1
+ User-agent: *
2
+ Allow: /
@@ -0,0 +1,493 @@
1
+ import process from "node:process";
2
+ import { fileURLToPath } from "node:url";
3
+ import { promisify } from "node:util";
4
+ import { LOCAL_DEVFRAME_ID, LOCAL_RPC } from "@pulls.review/core/local-rpc";
5
+ import { defineDevframe, defineRpcFunction } from "devframe";
6
+ import { createLocalSource, readRepoInfo } from "@pulls.review/core/local";
7
+ import { DiffsPayloadSchema } from "@pulls.review/core/types";
8
+ import { execFile } from "node:child_process";
9
+ import { githubTokenFromEnv } from "@pulls.review/core/env";
10
+ import { resolve } from "node:path";
11
+ import fsDriver from "unstorage/drivers/fs";
12
+ //#region package.json
13
+ var name = "pulls.review";
14
+ var version = "0.2.1";
15
+ const DEFAULT_CONFIG = {
16
+ lang: void 0,
17
+ message: void 0,
18
+ abortEarly: void 0,
19
+ abortPipeEarly: void 0
20
+ };
21
+ /**
22
+ * Returns the global configuration.
23
+ *
24
+ * @param config The config to merge.
25
+ *
26
+ * @returns The configuration.
27
+ */
28
+ /* @__NO_SIDE_EFFECTS__ */
29
+ function getGlobalConfig(config$1) {
30
+ if (!config$1 && true) return DEFAULT_CONFIG;
31
+ return {
32
+ lang: config$1?.lang ?? void 0,
33
+ message: config$1?.message,
34
+ abortEarly: config$1?.abortEarly ?? void 0,
35
+ abortPipeEarly: config$1?.abortPipeEarly ?? void 0
36
+ };
37
+ }
38
+ /**
39
+ * Stringifies an unknown input to a literal or type string.
40
+ *
41
+ * @param input The unknown input.
42
+ *
43
+ * @returns A literal or type string.
44
+ *
45
+ * @internal
46
+ */
47
+ /* @__NO_SIDE_EFFECTS__ */
48
+ function _stringify(input) {
49
+ const type = typeof input;
50
+ if (type === "string") return `"${input}"`;
51
+ if (type === "number" || type === "bigint" || type === "boolean") return `${input}`;
52
+ if (type === "object" || type === "function") return (input && Object.getPrototypeOf(input)?.constructor?.name) ?? "null";
53
+ return type;
54
+ }
55
+ /**
56
+ * Adds an issue to the dataset.
57
+ *
58
+ * @param context The issue context.
59
+ * @param label The issue label.
60
+ * @param dataset The input dataset.
61
+ * @param config The configuration.
62
+ * @param other The optional props.
63
+ *
64
+ * @internal
65
+ */
66
+ function _addIssue(context, label, dataset, config$1, other) {
67
+ const input = other && "input" in other ? other.input : dataset.value;
68
+ const expected = other?.expected ?? context.expects ?? null;
69
+ const received = other?.received ?? /* @__PURE__ */ _stringify(input);
70
+ const issue = {
71
+ kind: context.kind,
72
+ type: context.type,
73
+ input,
74
+ expected,
75
+ received,
76
+ message: `Invalid ${label}: ${expected ? `Expected ${expected} but r` : "R"}eceived ${received}`,
77
+ requirement: context.requirement,
78
+ path: other?.path,
79
+ issues: other?.issues,
80
+ lang: config$1.lang,
81
+ abortEarly: config$1.abortEarly,
82
+ abortPipeEarly: config$1.abortPipeEarly
83
+ };
84
+ const isSchema = context.kind === "schema";
85
+ const message$1 = other?.message ?? context.message ?? (context.reference, issue.lang, void 0) ?? (isSchema ? (issue.lang, void 0) : null) ?? config$1.message ?? (issue.lang, void 0);
86
+ if (message$1 !== void 0) issue.message = typeof message$1 === "function" ? message$1(issue) : message$1;
87
+ if (isSchema) dataset.typed = false;
88
+ if (dataset.issues) dataset.issues.push(issue);
89
+ else dataset.issues = [issue];
90
+ }
91
+ /**
92
+ * Eagerly creates and attaches the Standard Schema properties of a schema.
93
+ *
94
+ * Hint: The contextual `this` type includes the standard properties that are
95
+ * attached before the schema is returned.
96
+ *
97
+ * @param schema The schema to attach standard properties to.
98
+ *
99
+ * @returns The schema with standard properties attached.
100
+ *
101
+ * @internal
102
+ */
103
+ function _standardSchema(schema) {
104
+ schema["~standard"] = {
105
+ version: 1,
106
+ vendor: "valibot",
107
+ validate: (value$1) => schema["~run"]({ value: value$1 }, /* @__PURE__ */ getGlobalConfig())
108
+ };
109
+ return schema;
110
+ }
111
+ /**
112
+ * Returns the fallback value of the schema.
113
+ *
114
+ * @param schema The schema to get it from.
115
+ * @param dataset The output dataset if available.
116
+ * @param config The config if available.
117
+ *
118
+ * @returns The fallback value.
119
+ */
120
+ /* @__NO_SIDE_EFFECTS__ */
121
+ function getFallback(schema, dataset, config$1) {
122
+ return typeof schema.fallback === "function" ? schema.fallback(dataset, config$1) : schema.fallback;
123
+ }
124
+ /**
125
+ * Returns the default value of the schema.
126
+ *
127
+ * @param schema The schema to get it from.
128
+ * @param dataset The input dataset if available.
129
+ * @param config The config if available.
130
+ *
131
+ * @returns The default value.
132
+ */
133
+ /* @__NO_SIDE_EFFECTS__ */
134
+ function getDefault(schema, dataset, config$1) {
135
+ return typeof schema.default === "function" ? schema.default(dataset, config$1) : schema.default;
136
+ }
137
+ /* @__NO_SIDE_EFFECTS__ */
138
+ function array(item, message$1) {
139
+ return _standardSchema({
140
+ kind: "schema",
141
+ type: "array",
142
+ reference: array,
143
+ expects: "Array",
144
+ async: false,
145
+ item,
146
+ message: message$1,
147
+ "~run"(dataset, config$1) {
148
+ const input = dataset.value;
149
+ if (Array.isArray(input)) {
150
+ dataset.typed = true;
151
+ dataset.value = [];
152
+ for (let key = 0; key < input.length; key++) {
153
+ const value$1 = input[key];
154
+ const itemDataset = this.item["~run"]({ value: value$1 }, config$1);
155
+ if (itemDataset.issues) {
156
+ const pathItem = {
157
+ type: "array",
158
+ origin: "value",
159
+ input,
160
+ key,
161
+ value: value$1
162
+ };
163
+ for (const issue of itemDataset.issues) {
164
+ if (issue.path) issue.path.unshift(pathItem);
165
+ else issue.path = [pathItem];
166
+ dataset.issues?.push(issue);
167
+ }
168
+ if (!dataset.issues) dataset.issues = itemDataset.issues;
169
+ if (config$1.abortEarly) {
170
+ dataset.typed = false;
171
+ break;
172
+ }
173
+ }
174
+ if (!itemDataset.typed) dataset.typed = false;
175
+ dataset.value.push(itemDataset.value);
176
+ }
177
+ } else _addIssue(this, "type", dataset, config$1);
178
+ return dataset;
179
+ }
180
+ });
181
+ }
182
+ /* @__NO_SIDE_EFFECTS__ */
183
+ function nullable(wrapped, default_) {
184
+ return _standardSchema({
185
+ kind: "schema",
186
+ type: "nullable",
187
+ reference: nullable,
188
+ expects: `(${wrapped.expects} | null)`,
189
+ async: false,
190
+ wrapped,
191
+ default: default_,
192
+ "~run"(dataset, config$1) {
193
+ if (dataset.value === null) {
194
+ if (this.default !== void 0) dataset.value = /* @__PURE__ */ getDefault(this, dataset, config$1);
195
+ if (dataset.value === null) {
196
+ dataset.typed = true;
197
+ return dataset;
198
+ }
199
+ }
200
+ return this.wrapped["~run"](dataset, config$1);
201
+ }
202
+ });
203
+ }
204
+ /* @__NO_SIDE_EFFECTS__ */
205
+ function object(entries$1, message$1) {
206
+ return _standardSchema({
207
+ kind: "schema",
208
+ type: "object",
209
+ reference: object,
210
+ expects: "Object",
211
+ async: false,
212
+ entries: entries$1,
213
+ message: message$1,
214
+ "~run"(dataset, config$1) {
215
+ const input = dataset.value;
216
+ if (input && typeof input === "object") {
217
+ dataset.typed = true;
218
+ dataset.value = {};
219
+ for (const key in this.entries) {
220
+ const valueSchema = this.entries[key];
221
+ if (key in input || (valueSchema.type === "exact_optional" || valueSchema.type === "optional" || valueSchema.type === "nullish") && valueSchema.default !== void 0) {
222
+ const value$1 = key in input ? input[key] : /* @__PURE__ */ getDefault(valueSchema);
223
+ const valueDataset = valueSchema["~run"]({ value: value$1 }, config$1);
224
+ if (valueDataset.issues) {
225
+ const pathItem = {
226
+ type: "object",
227
+ origin: "value",
228
+ input,
229
+ key,
230
+ value: value$1
231
+ };
232
+ for (const issue of valueDataset.issues) {
233
+ if (issue.path) issue.path.unshift(pathItem);
234
+ else issue.path = [pathItem];
235
+ dataset.issues?.push(issue);
236
+ }
237
+ if (!dataset.issues) dataset.issues = valueDataset.issues;
238
+ if (config$1.abortEarly) {
239
+ dataset.typed = false;
240
+ break;
241
+ }
242
+ }
243
+ if (!valueDataset.typed) dataset.typed = false;
244
+ dataset.value[key] = valueDataset.value;
245
+ } else if (valueSchema.fallback !== void 0) dataset.value[key] = /* @__PURE__ */ getFallback(valueSchema);
246
+ else if (valueSchema.type !== "exact_optional" && valueSchema.type !== "optional" && valueSchema.type !== "nullish") {
247
+ _addIssue(this, "key", dataset, config$1, {
248
+ input: void 0,
249
+ expected: `"${key}"`,
250
+ path: [{
251
+ type: "object",
252
+ origin: "key",
253
+ input,
254
+ key,
255
+ value: input[key]
256
+ }]
257
+ });
258
+ if (config$1.abortEarly) break;
259
+ }
260
+ }
261
+ } else _addIssue(this, "type", dataset, config$1);
262
+ return dataset;
263
+ }
264
+ });
265
+ }
266
+ /* @__NO_SIDE_EFFECTS__ */
267
+ function optional(wrapped, default_) {
268
+ return _standardSchema({
269
+ kind: "schema",
270
+ type: "optional",
271
+ reference: optional,
272
+ expects: `(${wrapped.expects} | undefined)`,
273
+ async: false,
274
+ wrapped,
275
+ default: default_,
276
+ "~run"(dataset, config$1) {
277
+ if (dataset.value === void 0) {
278
+ if (this.default !== void 0) dataset.value = /* @__PURE__ */ getDefault(this, dataset, config$1);
279
+ if (dataset.value === void 0) {
280
+ dataset.typed = true;
281
+ return dataset;
282
+ }
283
+ }
284
+ return this.wrapped["~run"](dataset, config$1);
285
+ }
286
+ });
287
+ }
288
+ /* @__NO_SIDE_EFFECTS__ */
289
+ function string(message$1) {
290
+ return _standardSchema({
291
+ kind: "schema",
292
+ type: "string",
293
+ reference: string,
294
+ expects: "string",
295
+ async: false,
296
+ message: message$1,
297
+ "~run"(dataset, config$1) {
298
+ if (typeof dataset.value === "string") dataset.typed = true;
299
+ else _addIssue(this, "type", dataset, config$1);
300
+ return dataset;
301
+ }
302
+ });
303
+ }
304
+ /* @__NO_SIDE_EFFECTS__ */
305
+ function void_(message$1) {
306
+ return _standardSchema({
307
+ kind: "schema",
308
+ type: "void",
309
+ reference: void_,
310
+ expects: "void",
311
+ async: false,
312
+ message: message$1,
313
+ "~run"(dataset, config$1) {
314
+ if (dataset.value === void 0) dataset.typed = true;
315
+ else _addIssue(this, "type", dataset, config$1);
316
+ return dataset;
317
+ }
318
+ });
319
+ }
320
+ //#endregion
321
+ //#region src/credentials.ts
322
+ /** The environment first, then the GitHub CLI's login, if `gh` is installed and signed in. */
323
+ async function resolveGithubToken(env) {
324
+ const fromEnv = githubTokenFromEnv(env);
325
+ if (fromEnv) return fromEnv;
326
+ try {
327
+ const { stdout } = await promisify(execFile)("gh", ["auth", "token"]);
328
+ return stdout.trim() || void 0;
329
+ } catch {
330
+ return;
331
+ }
332
+ }
333
+ //#endregion
334
+ //#region src/rpc.ts
335
+ const target = /* @__PURE__ */ object({ target: /* @__PURE__ */ string() });
336
+ /**
337
+ * Every function the `PR_LOCAL` SPA calls. Only a client devframe has trusted
338
+ * reaches them; inputs are still validated, since they decide what `git` runs.
339
+ */
340
+ function localRpcFunctions({ cwd, driver, env }) {
341
+ const source = (text) => createLocalSource({
342
+ cwd,
343
+ target: text
344
+ });
345
+ return [
346
+ defineRpcFunction({
347
+ name: LOCAL_RPC.repoInfo,
348
+ type: "query",
349
+ handler: () => readRepoInfo(cwd)
350
+ }),
351
+ defineRpcFunction({
352
+ name: LOCAL_RPC.sourceKey,
353
+ type: "query",
354
+ args: [target],
355
+ returns: /* @__PURE__ */ string(),
356
+ handler: ({ target }) => source(target).key()
357
+ }),
358
+ defineRpcFunction({
359
+ name: LOCAL_RPC.sourceFetch,
360
+ type: "query",
361
+ args: [target],
362
+ returns: DiffsPayloadSchema,
363
+ handler: ({ target }) => source(target).fetch()
364
+ }),
365
+ defineRpcFunction({
366
+ name: LOCAL_RPC.sourceFingerprint,
367
+ type: "query",
368
+ args: [target],
369
+ returns: /* @__PURE__ */ string(),
370
+ handler: ({ target }) => source(target).fingerprint()
371
+ }),
372
+ defineRpcFunction({
373
+ name: LOCAL_RPC.sourceLoadFile,
374
+ type: "query",
375
+ args: [/* @__PURE__ */ object({
376
+ target: /* @__PURE__ */ string(),
377
+ path: /* @__PURE__ */ string(),
378
+ sha: /* @__PURE__ */ string()
379
+ })],
380
+ returns: /* @__PURE__ */ optional(/* @__PURE__ */ string()),
381
+ handler: ({ target, path, sha }) => source(target).loadFile(path, sha)
382
+ }),
383
+ defineRpcFunction({
384
+ name: LOCAL_RPC.storageGetItem,
385
+ type: "query",
386
+ args: [/* @__PURE__ */ object({ key: /* @__PURE__ */ string() })],
387
+ returns: /* @__PURE__ */ nullable(/* @__PURE__ */ string()),
388
+ handler: async ({ key }) => {
389
+ const value = await driver.getItem(key, {});
390
+ return typeof value === "string" ? value : null;
391
+ }
392
+ }),
393
+ defineRpcFunction({
394
+ name: LOCAL_RPC.storageSetItem,
395
+ type: "action",
396
+ args: [/* @__PURE__ */ object({
397
+ key: /* @__PURE__ */ string(),
398
+ value: /* @__PURE__ */ string()
399
+ })],
400
+ returns: /* @__PURE__ */ void_(),
401
+ handler: async ({ key, value }) => {
402
+ await driver.setItem?.(key, value, {});
403
+ }
404
+ }),
405
+ defineRpcFunction({
406
+ name: LOCAL_RPC.storageRemoveItem,
407
+ type: "action",
408
+ args: [/* @__PURE__ */ object({ key: /* @__PURE__ */ string() })],
409
+ returns: /* @__PURE__ */ void_(),
410
+ handler: async ({ key }) => {
411
+ await driver.removeItem?.(key, {});
412
+ }
413
+ }),
414
+ defineRpcFunction({
415
+ name: LOCAL_RPC.storageGetKeys,
416
+ type: "query",
417
+ args: [/* @__PURE__ */ object({ base: /* @__PURE__ */ string() })],
418
+ returns: /* @__PURE__ */ array(/* @__PURE__ */ string()),
419
+ handler: ({ base }) => driver.getKeys(base, {})
420
+ }),
421
+ defineRpcFunction({
422
+ name: LOCAL_RPC.githubToken,
423
+ type: "query",
424
+ handler: () => resolveGithubToken(env)
425
+ })
426
+ ];
427
+ }
428
+ //#endregion
429
+ //#region src/storage.ts
430
+ /**
431
+ * The fs driver maps every `:` of a key to a directory, so `a:b` (a file) and `a:b:c`
432
+ * (needing `a/b/` as a directory) can't both exist. Keys stay one directory per
433
+ * collection prefix (`pr-meta:`, `review:`, ...) with the rest escaped into one file name.
434
+ */
435
+ function flatKeys(driver) {
436
+ const encode = (key) => {
437
+ const [head = "", ...rest] = key.split(":");
438
+ return rest.length ? `${head}:${encodeURIComponent(rest.join(":"))}` : head;
439
+ };
440
+ const decode = (key) => {
441
+ const [head = "", ...rest] = key.split(/[:/]/);
442
+ return rest.length ? `${head}:${decodeURIComponent(rest.join(":"))}` : head;
443
+ };
444
+ return {
445
+ ...driver,
446
+ hasItem: (key, opts) => driver.hasItem(encode(key), opts),
447
+ getItem: (key, opts) => driver.getItem(encode(key), opts),
448
+ setItem: (key, value, opts) => driver.setItem?.(encode(key), value, opts),
449
+ removeItem: (key, opts) => driver.removeItem?.(encode(key), opts),
450
+ getKeys: async (base, opts) => (await driver.getKeys(encode(base.replace(/:$/, "")), opts)).map(decode)
451
+ };
452
+ }
453
+ /** `<git-common-dir>/pulls-review`: shared by every worktree of the repo, never committed. */
454
+ async function repoCacheDir(cwd) {
455
+ const { stdout } = await promisify(execFile)("git", ["rev-parse", "--git-common-dir"], { cwd });
456
+ return resolve(cwd, stdout.trim(), "pulls-review");
457
+ }
458
+ async function createRepoCacheDriver(cwd) {
459
+ return flatKeys(fsDriver({ base: await repoCacheDir(cwd) }));
460
+ }
461
+ //#endregion
462
+ //#region src/devframe.ts
463
+ /**
464
+ * The one definition every surface consumes: the `pulls.review` CLI (`index.ts`)
465
+ * and, through `createPluginFromDevframe`, a devframe hub. The SPA is the app's
466
+ * `PR_LOCAL` build, copied next to this file by the package build.
467
+ */
468
+ var devframe_default = defineDevframe({
469
+ id: LOCAL_DEVFRAME_ID,
470
+ name: "pulls.review",
471
+ version,
472
+ packageName: name,
473
+ description: "Review local git changes, grouped and summarized.",
474
+ homepage: "https://pulls.review",
475
+ icon: "ph:git-diff-duotone",
476
+ clientAssets: fileURLToPath(new URL("./client", import.meta.url)),
477
+ importMetaUrl: import.meta.url,
478
+ cli: {
479
+ command: "pulls.review",
480
+ port: 7390
481
+ },
482
+ async setup(ctx) {
483
+ const scope = ctx.scope(LOCAL_DEVFRAME_ID);
484
+ const functions = localRpcFunctions({
485
+ cwd: ctx.cwd,
486
+ driver: await createRepoCacheDriver(ctx.cwd),
487
+ env: process.env
488
+ });
489
+ for (const fn of functions) scope.rpc.register(fn);
490
+ }
491
+ });
492
+ //#endregion
493
+ export { devframe_default as t };
@@ -0,0 +1,2 @@
1
+ import { t as devframe_default } from "./devframe-CX5butdC.mjs";
2
+ export { devframe_default as default };
package/dist/index.mjs ADDED
@@ -0,0 +1,90 @@
1
+ import { t as devframe_default } from "./devframe-CX5butdC.mjs";
2
+ import { readFile } from "node:fs/promises";
3
+ import process from "node:process";
4
+ import { fileURLToPath } from "node:url";
5
+ import { parseArgs } from "node:util";
6
+ import { createDevServer } from "devframe/adapters/dev";
7
+ import { H3 } from "h3";
8
+ import { isLocalBranch, parseTarget, readCurrentBranch, resolveDefaultBranch } from "@pulls.review/core/local";
9
+ //#region src/page.ts
10
+ /** The page an argument opens (see the app's local routes). */
11
+ async function pageFor(cwd, arg, worktree) {
12
+ if (worktree) return "/worktree";
13
+ if (!arg) {
14
+ const [current, defaultBranch] = await Promise.all([readCurrentBranch(cwd), resolveDefaultBranch(cwd)]);
15
+ return current && defaultBranch && current !== defaultBranch.name ? `/branch/${current}` : "/";
16
+ }
17
+ if (parseTarget(arg).kind === "range") return `/compare/${arg}`;
18
+ return await isLocalBranch(cwd, arg) ? `/branch/${arg}` : `/commit/${arg}`;
19
+ }
20
+ //#endregion
21
+ //#region src/index.ts
22
+ const HELP = `Usage: pulls.review [target] [options]
23
+
24
+ Reviews local git changes in the browser, grouped and summarized. Run it inside
25
+ a git repository. The target only picks the page that opens; any other can be
26
+ picked from the browser.
27
+
28
+ Target (git revision syntax):
29
+ (none) the current branch against the default branch, or the ref picker
30
+ when the default branch itself is checked out
31
+ <branch> what a branch adds since it forked from the default branch
32
+ <rev> one commit against its parent
33
+ A...B what B adds since it forked from A
34
+ A..B the tree diff between two revisions
35
+
36
+ Options:
37
+ --worktree open the uncommitted changes against HEAD
38
+ --port <port> port to listen on
39
+ --no-open do not open the browser
40
+ -h, --help
41
+
42
+ To review a GitHub pull request in CI, use @pulls.review/actions.
43
+ `;
44
+ /**
45
+ * devframe's SPA fallback skips any path that looks like a file, and refs do: `main...feat`
46
+ * ends in `.feat`, `v1.2` in `.2`. Pages whose path carries a ref get the SPA's
47
+ * `index.html` here, before devframe's static handler sees them.
48
+ */
49
+ function createAppWithRefRoutes() {
50
+ const app = new H3();
51
+ const index = fileURLToPath(new URL("./client/index.html", import.meta.url));
52
+ app.use(async (event, next) => {
53
+ if (!/^\/(?:compare|branch|commit)\//.test(event.url.pathname) || !event.req.headers.get("accept")?.includes("text/html")) return next();
54
+ return new Response(await readFile(index, "utf8"), { headers: { "Content-Type": "text/html; charset=utf-8" } });
55
+ });
56
+ return app;
57
+ }
58
+ async function main() {
59
+ const { values: flags, positionals } = parseArgs({
60
+ options: {
61
+ "worktree": { type: "boolean" },
62
+ "port": { type: "string" },
63
+ "no-open": { type: "boolean" },
64
+ "help": {
65
+ type: "boolean",
66
+ short: "h"
67
+ }
68
+ },
69
+ allowPositionals: true
70
+ });
71
+ if (flags.help) {
72
+ process.stdout.write(HELP);
73
+ return;
74
+ }
75
+ const page = encodeURI(await pageFor(process.cwd(), positionals[0], !!flags.worktree));
76
+ await createDevServer(devframe_default, {
77
+ app: createAppWithRefRoutes(),
78
+ port: flags.port ? Number(flags.port) : void 0,
79
+ openBrowser: flags["no-open"] ? false : page,
80
+ onReady: ({ origin }) => {
81
+ process.stdout.write(`pulls.review is serving ${origin}${page}\n`);
82
+ }
83
+ });
84
+ }
85
+ main().catch((error) => {
86
+ console.error(error instanceof Error ? error.message : error);
87
+ process.exitCode = 1;
88
+ });
89
+ //#endregion
90
+ export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pulls.review",
3
3
  "type": "module",
4
- "version": "0.2.0",
4
+ "version": "0.2.1",
5
5
  "description": "Review local git changes - the working tree, a commit or any range - grouped and summarized in the browser.",
6
6
  "author": "Anthony Fu <hi@antfu.me>",
7
7
  "license": "MIT",
@@ -34,7 +34,7 @@
34
34
  "node": ">=20"
35
35
  },
36
36
  "dependencies": {
37
- "@pulls.review/core": "^0.2.0",
37
+ "@pulls.review/core": "^0.2.1",
38
38
  "devframe": "^1.2.0",
39
39
  "h3": "^2.0.1-rc.32",
40
40
  "unstorage": "^1.17.5"