@getpawl/setup 1.4.0 → 1.4.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.
- package/dist/index.js +73 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -186,6 +186,9 @@ async function pawlConnect() {
|
|
|
186
186
|
console.log(" pawl sync Push session data manually\n");
|
|
187
187
|
return result;
|
|
188
188
|
}
|
|
189
|
+
function hyperlink(url, text) {
|
|
190
|
+
return `\x1B]8;;${url}\x1B\\${text}\x1B]8;;\x1B\\`;
|
|
191
|
+
}
|
|
189
192
|
function getRepoUrl(cwd) {
|
|
190
193
|
try {
|
|
191
194
|
return (0, import_node_child_process.execSync)("git remote get-url origin", { cwd, stdio: "pipe" }).toString().trim();
|
|
@@ -193,8 +196,22 @@ function getRepoUrl(cwd) {
|
|
|
193
196
|
return null;
|
|
194
197
|
}
|
|
195
198
|
}
|
|
199
|
+
var PHASE_MESSAGES = {
|
|
200
|
+
scanned: "scanned",
|
|
201
|
+
generating: " Generating spec tree with AI...",
|
|
202
|
+
fetching: " Fetching file samples...",
|
|
203
|
+
refining: " Refining coverage status...",
|
|
204
|
+
extracting: " Extracting decisions..."
|
|
205
|
+
};
|
|
196
206
|
async function autoBootstrap(projectId, apiKey, repoUrl, apiUrl) {
|
|
207
|
+
let sseController = null;
|
|
197
208
|
try {
|
|
209
|
+
sseController = new AbortController();
|
|
210
|
+
const ssePromise = listenForProgress(
|
|
211
|
+
`${apiUrl}/api/projects/${projectId}/events`,
|
|
212
|
+
apiKey,
|
|
213
|
+
sseController.signal
|
|
214
|
+
);
|
|
198
215
|
const res = await fetch(`${apiUrl}/api/projects/${projectId}/bootstrap/cli-scan`, {
|
|
199
216
|
method: "POST",
|
|
200
217
|
headers: {
|
|
@@ -203,13 +220,68 @@ async function autoBootstrap(projectId, apiKey, repoUrl, apiUrl) {
|
|
|
203
220
|
},
|
|
204
221
|
body: JSON.stringify({ repoUrl })
|
|
205
222
|
});
|
|
223
|
+
sseController.abort();
|
|
224
|
+
await ssePromise.catch(() => {
|
|
225
|
+
});
|
|
206
226
|
if (!res.ok) return null;
|
|
207
227
|
const data = await res.json();
|
|
208
228
|
return { specsGenerated: data.specsGenerated, previewUrl: data.previewUrl };
|
|
209
229
|
} catch {
|
|
230
|
+
sseController?.abort();
|
|
210
231
|
return null;
|
|
211
232
|
}
|
|
212
233
|
}
|
|
234
|
+
async function listenForProgress(url, apiKey, signal) {
|
|
235
|
+
let res;
|
|
236
|
+
try {
|
|
237
|
+
res = await fetch(url, {
|
|
238
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
239
|
+
signal
|
|
240
|
+
});
|
|
241
|
+
} catch {
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
if (!res.ok || !res.body) return;
|
|
245
|
+
const reader = res.body.getReader();
|
|
246
|
+
const decoder = new TextDecoder();
|
|
247
|
+
let buffer = "";
|
|
248
|
+
try {
|
|
249
|
+
while (true) {
|
|
250
|
+
const { done, value } = await reader.read();
|
|
251
|
+
if (done) break;
|
|
252
|
+
buffer += decoder.decode(value, { stream: true });
|
|
253
|
+
const lines = buffer.split("\n");
|
|
254
|
+
buffer = lines.pop() ?? "";
|
|
255
|
+
let eventType = "";
|
|
256
|
+
for (const line of lines) {
|
|
257
|
+
if (line.startsWith("event: ")) {
|
|
258
|
+
eventType = line.slice(7).trim();
|
|
259
|
+
} else if (line.startsWith("data: ") && eventType) {
|
|
260
|
+
try {
|
|
261
|
+
const data = JSON.parse(line.slice(6));
|
|
262
|
+
if (eventType === "bootstrap:progress") {
|
|
263
|
+
const phase = data.phase;
|
|
264
|
+
if (phase === "scanned") {
|
|
265
|
+
console.log(` \u2713 ${data.detail || "Repository scanned"}`);
|
|
266
|
+
} else if (PHASE_MESSAGES[phase]) {
|
|
267
|
+
console.log(PHASE_MESSAGES[phase]);
|
|
268
|
+
}
|
|
269
|
+
} else if (eventType === "bootstrap:completed") {
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
} catch {
|
|
273
|
+
}
|
|
274
|
+
eventType = "";
|
|
275
|
+
} else if (line === "") {
|
|
276
|
+
eventType = "";
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
} catch {
|
|
281
|
+
} finally {
|
|
282
|
+
reader.releaseLock();
|
|
283
|
+
}
|
|
284
|
+
}
|
|
213
285
|
function legacySetup(encoded) {
|
|
214
286
|
let config;
|
|
215
287
|
try {
|
|
@@ -280,7 +352,7 @@ async function pawlInit(key, opts) {
|
|
|
280
352
|
const result = await autoBootstrap(config.projectId, config.apiKey, repoUrl, config.apiUrl);
|
|
281
353
|
if (result && result.specsGenerated > 0) {
|
|
282
354
|
console.log(` Generated ${result.specsGenerated} draft specs`);
|
|
283
|
-
console.log(` Review and confirm at: ${result.previewUrl}
|
|
355
|
+
console.log(` Review and confirm at: ${hyperlink(result.previewUrl, result.previewUrl)}
|
|
284
356
|
`);
|
|
285
357
|
}
|
|
286
358
|
}
|