premanmcp 0.16.0 → 0.16.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/bin/integrations.js +104 -36
- package/package.json +1 -1
package/bin/integrations.js
CHANGED
|
@@ -366,14 +366,6 @@ export async function slackCommand(args) {
|
|
|
366
366
|
// The guided run
|
|
367
367
|
// ---------------------------------------------------------------------------
|
|
368
368
|
|
|
369
|
-
/**
|
|
370
|
-
* "yes" | "no" | "back" -- back only offered once there is somewhere to go.
|
|
371
|
-
*
|
|
372
|
-
* `--yes` takes each step's own default rather than answering yes to all of
|
|
373
|
-
* them, so a step that should not ride in on a keypress can say so. Every step
|
|
374
|
-
* that asks defaults to yes today; the desktop app, which used to be the
|
|
375
|
-
* exception, no longer asks at all.
|
|
376
|
-
*/
|
|
377
369
|
/**
|
|
378
370
|
* Ask, once, before PreMan writes into an SDK repository or a docs site.
|
|
379
371
|
*
|
|
@@ -387,8 +379,14 @@ export async function slackCommand(args) {
|
|
|
387
379
|
* which is the whole reason this moved out of the delivery run.
|
|
388
380
|
*/
|
|
389
381
|
async function offerReleaseTargets(args, checkout, { assumeYes }) {
|
|
382
|
+
// SILENT is a step that did not happen rather than one that was skipped: no
|
|
383
|
+
// heading, and no line in the summary either. A repository with no SDK and no
|
|
384
|
+
// docs site has nothing to decide here, and saying so is worse than saying
|
|
385
|
+
// nothing.
|
|
386
|
+
const SILENT = { state: "skipped", silent: true };
|
|
387
|
+
|
|
390
388
|
const integrationId = checkout?.match?.integration_id;
|
|
391
|
-
if (!integrationId) return
|
|
389
|
+
if (!integrationId) return SILENT;
|
|
392
390
|
|
|
393
391
|
const token = resolveApiKey(args);
|
|
394
392
|
const path = `/sdk/integrations/${integrationId}/distribution`;
|
|
@@ -399,18 +397,19 @@ async function offerReleaseTargets(args, checkout, { assumeYes }) {
|
|
|
399
397
|
// Detection costs one root listing per repository in the installation. It
|
|
400
398
|
// is the least important thing in this walk and never worth failing setup
|
|
401
399
|
// over.
|
|
402
|
-
return
|
|
400
|
+
return SILENT;
|
|
403
401
|
}
|
|
404
402
|
|
|
403
|
+
const sdkRepo = detected?.sdk_repo || "";
|
|
404
|
+
const docsRepo = detected?.docs_repo || "";
|
|
405
|
+
if (!sdkRepo && !docsRepo) return SILENT;
|
|
406
|
+
|
|
407
|
+
banner("Releases");
|
|
405
408
|
if (detected?.confirmed) {
|
|
406
409
|
process.stdout.write(`${MARK.ok()} Release targets already answered.\n`);
|
|
407
410
|
return;
|
|
408
411
|
}
|
|
409
412
|
|
|
410
|
-
const sdkRepo = detected?.sdk_repo || "";
|
|
411
|
-
const docsRepo = detected?.docs_repo || "";
|
|
412
|
-
if (!sdkRepo && !docsRepo) return { state: "skipped" };
|
|
413
|
-
|
|
414
413
|
const body = {};
|
|
415
414
|
const decided = [];
|
|
416
415
|
for (const [repo, field, flag, question] of [
|
|
@@ -474,6 +473,46 @@ async function askRelease(question, assumeYes) {
|
|
|
474
473
|
return answer === "y" || answer === "yes";
|
|
475
474
|
}
|
|
476
475
|
|
|
476
|
+
/**
|
|
477
|
+
* Put PreMan on screen, signed in as the account this walk just used.
|
|
478
|
+
*
|
|
479
|
+
* Returns whether the app is actually up, because that is what decides the last
|
|
480
|
+
* line of the walk and nothing downstream can work it out.
|
|
481
|
+
*/
|
|
482
|
+
async function showDesktopSignedIn(openDesktopSignedIn, args, creds, stopOpening) {
|
|
483
|
+
// The same --dest the install honoured, or the launch would look for the app
|
|
484
|
+
// somewhere it was never copied to.
|
|
485
|
+
const destination = args.value("--dest", "/Applications");
|
|
486
|
+
const opened = await openDesktopSignedIn(creds, { destination });
|
|
487
|
+
stopOpening?.();
|
|
488
|
+
if (opened.state === "opened-signed-in") {
|
|
489
|
+
process.stdout.write("Opened PreMan, signed in as this account.\n");
|
|
490
|
+
} else if (opened.state === "not-installed") {
|
|
491
|
+
process.stdout.write(
|
|
492
|
+
`PreMan is not in ${destination} yet \u2014 open it once installed and sign in.\n`
|
|
493
|
+
);
|
|
494
|
+
} else {
|
|
495
|
+
// Either the session could not be handed over or this app is too old to take
|
|
496
|
+
// it up. Say so rather than let the customer wonder why they are looking at
|
|
497
|
+
// a login screen.
|
|
498
|
+
process.stdout.write("Opened PreMan \u2014 sign in with the account you just used.\n");
|
|
499
|
+
}
|
|
500
|
+
return opened.state !== "not-installed";
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/** One step heading, in the one format the whole walk uses. */
|
|
504
|
+
function banner(name) {
|
|
505
|
+
process.stdout.write(`\n── ${name} ──\n`);
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
/**
|
|
509
|
+
* "yes" | "no" | "back" -- back only offered once there is somewhere to go.
|
|
510
|
+
*
|
|
511
|
+
* `--yes` takes each step's own default rather than answering yes to all of
|
|
512
|
+
* them, so a step that should not ride in on a keypress can say so. Every step
|
|
513
|
+
* that asks defaults to yes today; the desktop app, which used to be the
|
|
514
|
+
* exception, no longer asks at all.
|
|
515
|
+
*/
|
|
477
516
|
async function askStep(question, { assumeYes, canGoBack, defaultYes = true }) {
|
|
478
517
|
const fallback = defaultYes ? "yes" : "no";
|
|
479
518
|
if (assumeYes) return fallback;
|
|
@@ -599,6 +638,22 @@ export async function onboardCommand(
|
|
|
599
638
|
process.stdout.write(
|
|
600
639
|
`${checkout.slug} is still not shared. Add it at ${INSTALLATIONS_URL}.\n`
|
|
601
640
|
);
|
|
641
|
+
// Nothing was connected, so this step did not finish. Returning nothing
|
|
642
|
+
// marks it done, which is how the walk came to print a tick directly
|
|
643
|
+
// under a line saying the repository is not shared — and why somebody
|
|
644
|
+
// would then open the app expecting to find GitHub set up and find
|
|
645
|
+
// "Continue with GitHub" instead. The sibling branch below already
|
|
646
|
+
// reports this correctly; this one simply never did.
|
|
647
|
+
return { state: "skipped" };
|
|
648
|
+
},
|
|
649
|
+
onSkip: () => {
|
|
650
|
+
// The one question in this walk that decides whether a fix from this
|
|
651
|
+
// code can ever land anywhere. Declining it in silence is how the gap
|
|
652
|
+
// stays invisible until a fix task finishes and produces nothing.
|
|
653
|
+
process.stdout.write(
|
|
654
|
+
`${MARK.skip()} ${checkout.slug} stays disconnected — fixes here cannot open pull requests.\n`
|
|
655
|
+
);
|
|
656
|
+
process.stdout.write(` Run '${cliInvocation()} github' here to change that.\n`);
|
|
602
657
|
},
|
|
603
658
|
});
|
|
604
659
|
} else {
|
|
@@ -631,6 +686,10 @@ export async function onboardCommand(
|
|
|
631
686
|
// inside a delivery run, on a screen most people never opened.
|
|
632
687
|
steps.push({
|
|
633
688
|
name: "Releases",
|
|
689
|
+
// Prints its own heading, and only once it knows there is a question. A
|
|
690
|
+
// walk that draws an empty section has told the customer something is
|
|
691
|
+
// missing when nothing is.
|
|
692
|
+
ownBanner: true,
|
|
634
693
|
run: () => offerReleaseTargets(args, checkout, { assumeYes }),
|
|
635
694
|
});
|
|
636
695
|
|
|
@@ -678,8 +737,21 @@ export async function onboardCommand(
|
|
|
678
737
|
if (desktop?.state === "installed") {
|
|
679
738
|
steps.push({
|
|
680
739
|
name: "Desktop app",
|
|
681
|
-
|
|
740
|
+
// Nothing to download, which is the point of this branch. It is not a
|
|
741
|
+
// reason to stop at the sentence: the step exists to leave the customer
|
|
742
|
+
// looking at PreMan, so the one run with nothing to install was also the
|
|
743
|
+
// only run that opened nothing, and it closed by sending someone to a
|
|
744
|
+
// website instead of the app already sitting on their machine.
|
|
745
|
+
run: async () => {
|
|
682
746
|
process.stdout.write(`${MARK.ok()} PreMan desktop app already installed.\n`);
|
|
747
|
+
const stopOpening = showOpeningDesktop();
|
|
748
|
+
try {
|
|
749
|
+
return {
|
|
750
|
+
appOpened: await showDesktopSignedIn(openDesktopSignedIn, args, creds, stopOpening),
|
|
751
|
+
};
|
|
752
|
+
} finally {
|
|
753
|
+
stopOpening();
|
|
754
|
+
}
|
|
683
755
|
},
|
|
684
756
|
});
|
|
685
757
|
} else if (!desktop) {
|
|
@@ -707,26 +779,15 @@ export async function onboardCommand(
|
|
|
707
779
|
return installed;
|
|
708
780
|
}
|
|
709
781
|
stopOpening ??= showOpeningDesktop();
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
`PreMan is not in ${destination} yet \u2014 open it once installed and sign in.\n`
|
|
720
|
-
);
|
|
721
|
-
} else {
|
|
722
|
-
// Either the session could not be handed over or this app is too
|
|
723
|
-
// old to take it up. Say so rather than let the customer wonder
|
|
724
|
-
// why they are looking at a login screen.
|
|
725
|
-
process.stdout.write("Opened PreMan \u2014 sign in with the account you just used.\n");
|
|
726
|
-
}
|
|
727
|
-
// Whether the app is on screen decides what the last line of the walk
|
|
728
|
-
// should say, and only this closure knows.
|
|
729
|
-
return { ...installed, appOpened: opened.state !== "not-installed" };
|
|
782
|
+
return {
|
|
783
|
+
...installed,
|
|
784
|
+
appOpened: await showDesktopSignedIn(
|
|
785
|
+
openDesktopSignedIn,
|
|
786
|
+
args,
|
|
787
|
+
creds,
|
|
788
|
+
stopOpening
|
|
789
|
+
),
|
|
790
|
+
};
|
|
730
791
|
} finally {
|
|
731
792
|
stopOpening?.();
|
|
732
793
|
}
|
|
@@ -745,7 +806,7 @@ export async function onboardCommand(
|
|
|
745
806
|
let i = 0;
|
|
746
807
|
while (i < steps.length) {
|
|
747
808
|
const step = steps[i];
|
|
748
|
-
|
|
809
|
+
if (!step.ownBanner) banner(step.name);
|
|
749
810
|
|
|
750
811
|
if (step.question) {
|
|
751
812
|
// "back" goes to the last step that asked something, not simply to the
|
|
@@ -784,6 +845,13 @@ export async function onboardCommand(
|
|
|
784
845
|
// at the end of a successful install: the install reports state "installed",
|
|
785
846
|
// which is none of the three, so it printed as a failure with no detail.
|
|
786
847
|
const reported = await step.run();
|
|
848
|
+
// A step that never announced itself does not belong in the summary
|
|
849
|
+
// either: a line reading "(skipped)" for work nobody was offered reads as
|
|
850
|
+
// something having gone wrong.
|
|
851
|
+
if (reported?.silent) {
|
|
852
|
+
i += 1;
|
|
853
|
+
continue;
|
|
854
|
+
}
|
|
787
855
|
const state =
|
|
788
856
|
{ failed: "failed", skipped: "skipped", unsupported: "skipped" }[reported?.state] ||
|
|
789
857
|
"done";
|