premanmcp 0.15.3 → 0.16.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/bin/integrations.js +109 -0
- package/package.json +1 -1
package/bin/integrations.js
CHANGED
|
@@ -374,6 +374,106 @@ export async function slackCommand(args) {
|
|
|
374
374
|
* that asks defaults to yes today; the desktop app, which used to be the
|
|
375
375
|
* exception, no longer asks at all.
|
|
376
376
|
*/
|
|
377
|
+
/**
|
|
378
|
+
* Ask, once, before PreMan writes into an SDK repository or a docs site.
|
|
379
|
+
*
|
|
380
|
+
* Two questions rather than one. Agreeing to a generated client library is not
|
|
381
|
+
* agreeing to have your documentation site rewritten (a docs release replaces
|
|
382
|
+
* mkdocs.yml), and a single answer used to buy both.
|
|
383
|
+
*
|
|
384
|
+
* Says nothing when there is nothing to ask: no connected repository, no
|
|
385
|
+
* detected target, or an answer already on file. A walk that re-asks a question
|
|
386
|
+
* it has already had answered teaches people that answering buys them nothing,
|
|
387
|
+
* which is the whole reason this moved out of the delivery run.
|
|
388
|
+
*/
|
|
389
|
+
async function offerReleaseTargets(args, checkout, { assumeYes }) {
|
|
390
|
+
const integrationId = checkout?.match?.integration_id;
|
|
391
|
+
if (!integrationId) return { state: "skipped" };
|
|
392
|
+
|
|
393
|
+
const token = resolveApiKey(args);
|
|
394
|
+
const path = `/sdk/integrations/${integrationId}/distribution`;
|
|
395
|
+
let detected = null;
|
|
396
|
+
try {
|
|
397
|
+
detected = await callBackendJson(args, "GET", path, { token });
|
|
398
|
+
} catch {
|
|
399
|
+
// Detection costs one root listing per repository in the installation. It
|
|
400
|
+
// is the least important thing in this walk and never worth failing setup
|
|
401
|
+
// over.
|
|
402
|
+
return { state: "skipped" };
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
if (detected?.confirmed) {
|
|
406
|
+
process.stdout.write(`${MARK.ok()} Release targets already answered.\n`);
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
const sdkRepo = detected?.sdk_repo || "";
|
|
411
|
+
const docsRepo = detected?.docs_repo || "";
|
|
412
|
+
if (!sdkRepo && !docsRepo) return { state: "skipped" };
|
|
413
|
+
|
|
414
|
+
const body = {};
|
|
415
|
+
const decided = [];
|
|
416
|
+
for (const [repo, field, flag, question] of [
|
|
417
|
+
[
|
|
418
|
+
sdkRepo,
|
|
419
|
+
"sdk_repo",
|
|
420
|
+
"publish_sdk",
|
|
421
|
+
`${sdkRepo} looks like your client library. Open pull requests there with generated SDKs?`,
|
|
422
|
+
],
|
|
423
|
+
[
|
|
424
|
+
docsRepo,
|
|
425
|
+
"docs_repo",
|
|
426
|
+
"publish_docs",
|
|
427
|
+
// The wider blast radius is named in the question, because it is the part
|
|
428
|
+
// somebody would resent discovering afterwards.
|
|
429
|
+
`${docsRepo} looks like your docs site. Open pull requests there? Releases rewrite mkdocs.yml.`,
|
|
430
|
+
],
|
|
431
|
+
]) {
|
|
432
|
+
if (!repo) continue;
|
|
433
|
+
const answer = await askRelease(question, assumeYes);
|
|
434
|
+
if (answer === null) continue;
|
|
435
|
+
body[field] = repo;
|
|
436
|
+
body[flag] = answer;
|
|
437
|
+
decided.push([repo, answer]);
|
|
438
|
+
}
|
|
439
|
+
if (!decided.length) return { state: "skipped" };
|
|
440
|
+
|
|
441
|
+
await callBackendJson(args, "PUT", path, { token, json: body });
|
|
442
|
+
|
|
443
|
+
for (const [repo, allowed] of decided) {
|
|
444
|
+
// A no is reported as recorded, not as a step that failed. It is an answer,
|
|
445
|
+
// and PreMan will not come back to it.
|
|
446
|
+
if (allowed) process.stdout.write(`${MARK.ok()} Publishing to ${repo}.\n`);
|
|
447
|
+
else
|
|
448
|
+
process.stdout.write(
|
|
449
|
+
`${MARK.skip()} Not publishing to ${repo}. PreMan will not ask again.\n`
|
|
450
|
+
);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Yes, no, or nobody answered.
|
|
456
|
+
*
|
|
457
|
+
* Three outcomes rather than two, and the third is the whole reason this does
|
|
458
|
+
* not use `confirm`. That helper reads a closed stdin as a no, which is right
|
|
459
|
+
* for a step that then simply does less work. A no here is *recorded*, and a
|
|
460
|
+
* recorded no is never asked again, so reading silence as refusal would retire
|
|
461
|
+
* a question the customer never saw.
|
|
462
|
+
*
|
|
463
|
+
* The same argument applies to --yes: accepting defaults on someone's behalf is
|
|
464
|
+
* fine for a hook or a download, and is not a way to acquire write access to a
|
|
465
|
+
* repository nobody mentioned. So an unattended run leaves both questions open.
|
|
466
|
+
*
|
|
467
|
+
* The default is no, for the reason silence means no everywhere else PreMan
|
|
468
|
+
* writes to somebody's repository.
|
|
469
|
+
*/
|
|
470
|
+
async function askRelease(question, assumeYes) {
|
|
471
|
+
if (assumeYes) return null;
|
|
472
|
+
const answer = (await promptText(`${question} [y/N]: `)).trim().toLowerCase();
|
|
473
|
+
if (answer === "") return null;
|
|
474
|
+
return answer === "y" || answer === "yes";
|
|
475
|
+
}
|
|
476
|
+
|
|
377
477
|
async function askStep(question, { assumeYes, canGoBack, defaultYes = true }) {
|
|
378
478
|
const fallback = defaultYes ? "yes" : "no";
|
|
379
479
|
if (assumeYes) return fallback;
|
|
@@ -525,6 +625,15 @@ export async function onboardCommand(
|
|
|
525
625
|
});
|
|
526
626
|
}
|
|
527
627
|
|
|
628
|
+
// The only questions in this walk about repositories *other* than the one
|
|
629
|
+
// being connected. They are asked here, while PreMan has just read the
|
|
630
|
+
// installation and can name what it found, rather than weeks later from
|
|
631
|
+
// inside a delivery run, on a screen most people never opened.
|
|
632
|
+
steps.push({
|
|
633
|
+
name: "Releases",
|
|
634
|
+
run: () => offerReleaseTargets(args, checkout, { assumeYes }),
|
|
635
|
+
});
|
|
636
|
+
|
|
528
637
|
steps.push({
|
|
529
638
|
name: "Push checks",
|
|
530
639
|
question: "Check your endpoints on every git push in this repo?",
|