@m8t-stack/cli 0.2.21 → 0.2.23
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/README.md +3 -3
- package/dist/cli.js +251 -126
- package/dist/cli.js.map +1 -1
- package/package.json +4 -4
package/dist/cli.js
CHANGED
|
@@ -1231,7 +1231,7 @@ var init_enable_hosted_brain = __esm({
|
|
|
1231
1231
|
import { Builtins, Cli } from "clipanion";
|
|
1232
1232
|
|
|
1233
1233
|
// src/lib/package-version.ts
|
|
1234
|
-
var CLI_VERSION = "0.2.
|
|
1234
|
+
var CLI_VERSION = "0.2.23";
|
|
1235
1235
|
|
|
1236
1236
|
// src/lib/render-error.ts
|
|
1237
1237
|
init_errors();
|
|
@@ -11481,6 +11481,31 @@ import { DefaultAzureCredential } from "@azure/identity";
|
|
|
11481
11481
|
// src/lib/az.ts
|
|
11482
11482
|
init_errors();
|
|
11483
11483
|
import { spawn } from "child_process";
|
|
11484
|
+
var SECRET_VALUE_FLAGS = /* @__PURE__ */ new Set(["--secure-environment-variables"]);
|
|
11485
|
+
var SECRET_KEY_RE = /(pem|secret|token|password|passwd|pwd|credential|private[-_]?key)/i;
|
|
11486
|
+
function redactAzArgs(args) {
|
|
11487
|
+
const out = [];
|
|
11488
|
+
let secretFlagActive = false;
|
|
11489
|
+
for (const arg of args) {
|
|
11490
|
+
if (arg.startsWith("-")) {
|
|
11491
|
+
secretFlagActive = SECRET_VALUE_FLAGS.has(arg);
|
|
11492
|
+
out.push(arg);
|
|
11493
|
+
continue;
|
|
11494
|
+
}
|
|
11495
|
+
const eq = arg.indexOf("=");
|
|
11496
|
+
const key2 = eq > 0 ? arg.slice(0, eq) : "";
|
|
11497
|
+
if (secretFlagActive) {
|
|
11498
|
+
out.push(key2 ? `${key2}=[REDACTED]` : "[REDACTED]");
|
|
11499
|
+
continue;
|
|
11500
|
+
}
|
|
11501
|
+
if (key2 && SECRET_KEY_RE.test(key2)) {
|
|
11502
|
+
out.push(`${key2}=[REDACTED]`);
|
|
11503
|
+
continue;
|
|
11504
|
+
}
|
|
11505
|
+
out.push(arg);
|
|
11506
|
+
}
|
|
11507
|
+
return out;
|
|
11508
|
+
}
|
|
11484
11509
|
function runAz(args) {
|
|
11485
11510
|
return new Promise((resolve3, reject) => {
|
|
11486
11511
|
const proc = spawn("az", args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
@@ -11517,7 +11542,7 @@ function runAz(args) {
|
|
|
11517
11542
|
reject(
|
|
11518
11543
|
new LocalCliError({
|
|
11519
11544
|
code: "AZ_COMMAND_FAILED",
|
|
11520
|
-
message: `'az ${args.join(" ")}' failed: ${errString.trim()}`
|
|
11545
|
+
message: `'az ${redactAzArgs(args).join(" ")}' failed: ${errString.trim()}`
|
|
11521
11546
|
})
|
|
11522
11547
|
);
|
|
11523
11548
|
return;
|
|
@@ -15653,7 +15678,7 @@ async function awaitDataPlaneReady(opts) {
|
|
|
15653
15678
|
const consecutive = opts.consecutive ?? 3;
|
|
15654
15679
|
const attempts = opts.attempts ?? 60;
|
|
15655
15680
|
const intervalMs = opts.intervalMs ?? 5e3;
|
|
15656
|
-
const
|
|
15681
|
+
const sleep4 = opts.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
15657
15682
|
let streak = 0;
|
|
15658
15683
|
for (let i = 1; i <= attempts; i++) {
|
|
15659
15684
|
const r = await opts.probe();
|
|
@@ -15675,7 +15700,7 @@ async function awaitDataPlaneReady(opts) {
|
|
|
15675
15700
|
streak = 0;
|
|
15676
15701
|
opts.onProgress?.(`data-plane not ready (${forcedRetryable ? `status ${(r.status ?? 0).toString()}` : cls.category}), waiting\u2026`);
|
|
15677
15702
|
}
|
|
15678
|
-
if (i < attempts) await
|
|
15703
|
+
if (i < attempts) await sleep4(intervalMs);
|
|
15679
15704
|
}
|
|
15680
15705
|
return { ready: false, attempts };
|
|
15681
15706
|
}
|
|
@@ -16703,7 +16728,7 @@ init_errors();
|
|
|
16703
16728
|
async function deployHostedWorker(args) {
|
|
16704
16729
|
const onProgress = args.onProgress ?? ((_m) => {
|
|
16705
16730
|
});
|
|
16706
|
-
const
|
|
16731
|
+
const sleep4 = args.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
16707
16732
|
const now = args.now ?? (() => Date.now());
|
|
16708
16733
|
const timeout = args.pollTimeoutMs ?? 8 * 60 * 1e3;
|
|
16709
16734
|
const interval = args.pollIntervalMs ?? 1e4;
|
|
@@ -16755,7 +16780,7 @@ async function deployHostedWorker(args) {
|
|
|
16755
16780
|
hint: "Provisioning can take 2\u20135 min; re-run with the same name to resume, or check the version status in the Foundry portal."
|
|
16756
16781
|
});
|
|
16757
16782
|
}
|
|
16758
|
-
await
|
|
16783
|
+
await sleep4(interval);
|
|
16759
16784
|
}
|
|
16760
16785
|
}
|
|
16761
16786
|
|
|
@@ -16900,7 +16925,7 @@ var SIZE_PRESETS = {
|
|
|
16900
16925
|
medium: { cpu: "1", memory: "2Gi" },
|
|
16901
16926
|
large: { cpu: "2", memory: "4Gi" }
|
|
16902
16927
|
};
|
|
16903
|
-
var DEFAULT_REGISTRY = "ghcr.io/m8t-
|
|
16928
|
+
var DEFAULT_REGISTRY = "ghcr.io/m8t-labs";
|
|
16904
16929
|
var DEFAULT_IMAGE = "m8t-coding-agent";
|
|
16905
16930
|
var DEFAULT_TAG = "v0.1.0";
|
|
16906
16931
|
var DEFAULT_MODEL = "gpt-4.1-mini";
|
|
@@ -16909,7 +16934,7 @@ var CoderDeployCommand = class extends M8tCommand {
|
|
|
16909
16934
|
static paths = [["coder", "deploy"]];
|
|
16910
16935
|
static usage = Command28.Usage({
|
|
16911
16936
|
description: "Deploy the curated coding agent as a hosted Foundry worker.",
|
|
16912
|
-
details: "Creates a hosted agent version from a container image (defaults to the public GHCR image ghcr.io/m8t-
|
|
16937
|
+
details: "Creates a hosted agent version from a container image (defaults to the public GHCR image ghcr.io/m8t-labs/m8t-coding-agent). Post-2026-06-25 Foundry projects require an authenticated pull, so a public image is staged into the customer's Azure Container Registry first (created if missing, then `az acr import` \u2014 a server-side copy, no local build) and the agent is deployed from that ACR ref. Re-running with a newer --image-tag imports the new tag and rolls out a new agent version \u2014 that is how you update a worker's image. Override --image with a private ACR ref to bring your own registry.",
|
|
16913
16938
|
examples: [
|
|
16914
16939
|
["Deploy a coder with defaults", "$0 coder deploy my-coder"],
|
|
16915
16940
|
["Larger sandbox + a custom model", "$0 coder deploy my-coder --size large --model-deployment gpt-4.1"],
|
|
@@ -17296,7 +17321,7 @@ var SIZE_PRESETS2 = {
|
|
|
17296
17321
|
medium: { cpu: "1", memory: "2Gi" },
|
|
17297
17322
|
large: { cpu: "2", memory: "4Gi" }
|
|
17298
17323
|
};
|
|
17299
|
-
var DEFAULT_REGISTRY2 = "ghcr.io/m8t-
|
|
17324
|
+
var DEFAULT_REGISTRY2 = "ghcr.io/m8t-labs";
|
|
17300
17325
|
var DEFAULT_IMAGE2 = "m8t-azure-executor";
|
|
17301
17326
|
var DEFAULT_TAG2 = "v0.1.0";
|
|
17302
17327
|
var DEFAULT_MODEL2 = "gpt-5-mini";
|
|
@@ -17305,11 +17330,11 @@ var AzureExecDeployCommand = class extends M8tCommand {
|
|
|
17305
17330
|
static paths = [["azure-exec", "deploy"]];
|
|
17306
17331
|
static usage = Command30.Usage({
|
|
17307
17332
|
description: "Deploy the Azure executor as a hosted Foundry worker (az CLI + tiered ops).",
|
|
17308
|
-
details: "Creates a hosted agent version from a container image (defaults to the public GHCR image ghcr.io/m8t-
|
|
17333
|
+
details: "Creates a hosted agent version from a container image (defaults to the public GHCR image ghcr.io/m8t-labs/m8t-azure-executor \u2014 no local build needed), grants its identity Foundry User + Contributor (at --scope) + Key Vault Secrets User (brain KV), polls to active, and a2a-enables it as a target. Override with --image/--image-tag for a bring-your-own-registry image (e.g. a private ACR ref, which must be pushed first). Contributor scope is REQUIRED \u2014 pass --scope or --resource-group. Pass --grant-access-admin to additionally grant User Access Administrator (enables human-approved Tier-2 role/delete ops). Post-2026-06-25 Foundry projects require an authenticated pull, so the public image (default ghcr.io/m8t-labs/m8t-azure-executor) is staged into the customer's Azure Container Registry first (created if missing, then `az acr import` \u2014 server-side, no local build) and deployed from that ACR ref; re-running with a newer --image-tag updates the image.",
|
|
17309
17334
|
examples: [
|
|
17310
17335
|
[
|
|
17311
17336
|
"Deploy scoped to a resource group",
|
|
17312
|
-
"$0 azure-exec deploy azexec --resource-group rg-test --brain m8t-
|
|
17337
|
+
"$0 azure-exec deploy azexec --resource-group rg-test --brain m8t-labs/azure-exec-smoke-brain --gateway-url https://<gw>/api/a2a/mcp"
|
|
17313
17338
|
]
|
|
17314
17339
|
]
|
|
17315
17340
|
});
|
|
@@ -17341,7 +17366,7 @@ var AzureExecDeployCommand = class extends M8tCommand {
|
|
|
17341
17366
|
throw new LocalCliError({
|
|
17342
17367
|
code: "USAGE",
|
|
17343
17368
|
message: "--brain owner/repo is required (the executor delivers proof to a brain).",
|
|
17344
|
-
hint: "Example: --brain m8t-
|
|
17369
|
+
hint: "Example: --brain m8t-labs/azure-exec-smoke-brain"
|
|
17345
17370
|
});
|
|
17346
17371
|
}
|
|
17347
17372
|
const size = (this.size ?? "large").toLowerCase();
|
|
@@ -17573,7 +17598,7 @@ import { DefaultAzureCredential as DefaultAzureCredential16 } from "@azure/ident
|
|
|
17573
17598
|
|
|
17574
17599
|
// src/lib/platform-update.ts
|
|
17575
17600
|
init_errors();
|
|
17576
|
-
var DEFAULT_IMAGE_REPO = "ghcr.io/m8t-
|
|
17601
|
+
var DEFAULT_IMAGE_REPO = "ghcr.io/m8t-labs/m8t";
|
|
17577
17602
|
function parseImageRef2(ref) {
|
|
17578
17603
|
const lastColon = ref.lastIndexOf(":");
|
|
17579
17604
|
const lastSlash = ref.lastIndexOf("/");
|
|
@@ -17806,13 +17831,13 @@ function entityToStamp(e) {
|
|
|
17806
17831
|
}
|
|
17807
17832
|
|
|
17808
17833
|
// ../../packages/platform-release/dist/esm/channel-url.js
|
|
17809
|
-
var CHANNEL_LATEST_URL = "https://github.com/m8t-
|
|
17834
|
+
var CHANNEL_LATEST_URL = "https://github.com/m8t-labs/m8t/releases/latest/download/manifest.json";
|
|
17810
17835
|
function platformTag(version) {
|
|
17811
17836
|
const bare = version.trim().replace(/^platform-/, "").replace(/^v/, "");
|
|
17812
17837
|
return `platform-v${bare}`;
|
|
17813
17838
|
}
|
|
17814
17839
|
function channelUrlForVersion(version) {
|
|
17815
|
-
return `https://github.com/m8t-
|
|
17840
|
+
return `https://github.com/m8t-labs/m8t/releases/download/${platformTag(version)}/manifest.json`;
|
|
17816
17841
|
}
|
|
17817
17842
|
|
|
17818
17843
|
// ../../packages/platform-release/dist/esm/apply-request.js
|
|
@@ -17902,7 +17927,7 @@ import * as os8 from "os";
|
|
|
17902
17927
|
import * as path19 from "path";
|
|
17903
17928
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
17904
17929
|
init_errors();
|
|
17905
|
-
var OWNER_REPO = "m8t-
|
|
17930
|
+
var OWNER_REPO = "m8t-labs/m8t";
|
|
17906
17931
|
function parseTreeResponse(body) {
|
|
17907
17932
|
const map = /* @__PURE__ */ new Map();
|
|
17908
17933
|
for (const e of body.tree ?? []) if (e.type === "tree") map.set(e.path, e.sha);
|
|
@@ -20750,7 +20775,7 @@ function classifyWhatIf(changes) {
|
|
|
20750
20775
|
}
|
|
20751
20776
|
|
|
20752
20777
|
// src/commands/deploy.ts
|
|
20753
|
-
var DEFAULT_IMAGE_REF = "ghcr.io/m8t-
|
|
20778
|
+
var DEFAULT_IMAGE_REF = "ghcr.io/m8t-labs/m8t:latest";
|
|
20754
20779
|
var DeployCommand = class extends M8tCommand {
|
|
20755
20780
|
static paths = [["deploy"]];
|
|
20756
20781
|
static usage = Command36.Usage({
|
|
@@ -21151,7 +21176,7 @@ function resolveJudgeDeployment(flag, env) {
|
|
|
21151
21176
|
warning: "no --deployment and no $EXAM_JUDGE_DEPLOYMENT \u2014 falling back to gpt-5-mini as the judge. Name the DISTINCT judge deployment before any blessing/calibration run (DESIGN \xA75.5)."
|
|
21152
21177
|
};
|
|
21153
21178
|
}
|
|
21154
|
-
var BRAIN_REPO_MARKERS = ["m8t-
|
|
21179
|
+
var BRAIN_REPO_MARKERS = ["m8t-labs/", "/azure-advisor-brain", "/stacey-brain", "exam-arm-"];
|
|
21155
21180
|
function assertOutNotInBrainRepo(out) {
|
|
21156
21181
|
if (BRAIN_REPO_MARKERS.some((m) => out.includes(m))) {
|
|
21157
21182
|
throw new LocalCliError({
|
|
@@ -22805,7 +22830,7 @@ function mapItems(raw) {
|
|
|
22805
22830
|
return acc.reverse();
|
|
22806
22831
|
}
|
|
22807
22832
|
function makeConversationSource(client, opts = {}) {
|
|
22808
|
-
const
|
|
22833
|
+
const sleep4 = opts.sleep ?? defaultSleep;
|
|
22809
22834
|
return {
|
|
22810
22835
|
async items(conversationId) {
|
|
22811
22836
|
for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt++) {
|
|
@@ -22823,7 +22848,7 @@ function makeConversationSource(client, opts = {}) {
|
|
|
22823
22848
|
throw new ConvFetchError("auth", `auth failed reading ${conversationId}`);
|
|
22824
22849
|
const retryable = status === void 0 || status === TRANSIENT;
|
|
22825
22850
|
if (retryable && attempt < MAX_ATTEMPTS - 1) {
|
|
22826
|
-
await
|
|
22851
|
+
await sleep4(attempt);
|
|
22827
22852
|
continue;
|
|
22828
22853
|
}
|
|
22829
22854
|
throw new ConvFetchError("terminal", `exhausted ${String(MAX_ATTEMPTS)} retries reading ${conversationId}: ${e?.message ?? String(e)}`);
|
|
@@ -23625,7 +23650,7 @@ function extractJson(text) {
|
|
|
23625
23650
|
return JSON.parse(candidate2.slice(start, end + 1));
|
|
23626
23651
|
}
|
|
23627
23652
|
async function propose(model, system, user, opts = {}) {
|
|
23628
|
-
const
|
|
23653
|
+
const sleep4 = opts.sleep ?? defaultSleep2;
|
|
23629
23654
|
const modelName = opts.model ?? MODEL_NAME_FALLBACK;
|
|
23630
23655
|
let inputTokens = 0;
|
|
23631
23656
|
let outputTokens = 0;
|
|
@@ -23641,7 +23666,7 @@ async function propose(model, system, user, opts = {}) {
|
|
|
23641
23666
|
} catch (e) {
|
|
23642
23667
|
lastErr = `parse: ${e.message}`;
|
|
23643
23668
|
if (attempt < MAX_MODEL_ATTEMPTS - 1) {
|
|
23644
|
-
await
|
|
23669
|
+
await sleep4(attempt);
|
|
23645
23670
|
continue;
|
|
23646
23671
|
}
|
|
23647
23672
|
break;
|
|
@@ -23650,7 +23675,7 @@ async function propose(model, system, user, opts = {}) {
|
|
|
23650
23675
|
if (!Array.isArray(rawDeltas)) {
|
|
23651
23676
|
lastErr = "schema: top-level { deltas: [] } missing";
|
|
23652
23677
|
if (attempt < MAX_MODEL_ATTEMPTS - 1) {
|
|
23653
|
-
await
|
|
23678
|
+
await sleep4(attempt);
|
|
23654
23679
|
continue;
|
|
23655
23680
|
}
|
|
23656
23681
|
break;
|
|
@@ -25605,8 +25630,8 @@ async function writeBootstrapState(state, home = os13.homedir()) {
|
|
|
25605
25630
|
|
|
25606
25631
|
// src/commands/bootstrap/launch.ts
|
|
25607
25632
|
var DEFAULT_RG = "rg-m8t-stack";
|
|
25608
|
-
var DEFAULT_INSTALLER = "ghcr.io/m8t-
|
|
25609
|
-
var DEFAULT_INSTALLER_TAG = "v0.1.
|
|
25633
|
+
var DEFAULT_INSTALLER = "ghcr.io/m8t-labs/m8t-installer";
|
|
25634
|
+
var DEFAULT_INSTALLER_TAG = "v0.1.30";
|
|
25610
25635
|
var ACI_NAME = "m8t-installer";
|
|
25611
25636
|
var MI_NAME = "m8t-installer-mi";
|
|
25612
25637
|
var BootstrapLaunchCommand = class extends M8tCommand {
|
|
@@ -25617,7 +25642,8 @@ var BootstrapLaunchCommand = class extends M8tCommand {
|
|
|
25617
25642
|
examples: [
|
|
25618
25643
|
["Launch in eastus2", "$0 bootstrap launch --location eastus2"],
|
|
25619
25644
|
["BYO app registration", "$0 bootstrap launch --location eastus2 --client-id <appId>"],
|
|
25620
|
-
["Pin a specific installer tag", "$0 bootstrap launch --location eastus2 --installer-tag v0.1.
|
|
25645
|
+
["Pin a specific installer tag", "$0 bootstrap launch --location eastus2 --installer-tag v0.1.30"],
|
|
25646
|
+
["Override the full installer image ref", "$0 bootstrap launch --location eastus2 --installer-image ghcr.io/m8t-labs/m8t-installer:v0.1.30"]
|
|
25621
25647
|
]
|
|
25622
25648
|
});
|
|
25623
25649
|
location = Option46.String("--location");
|
|
@@ -25625,6 +25651,10 @@ var BootstrapLaunchCommand = class extends M8tCommand {
|
|
|
25625
25651
|
clientId = Option46.String("--client-id");
|
|
25626
25652
|
subscription = Option46.String("--subscription");
|
|
25627
25653
|
installerTag = Option46.String("--installer-tag");
|
|
25654
|
+
// Full image ref override (registry + repo + tag) — an escape hatch when the
|
|
25655
|
+
// default org/tag is wrong for the current CLI (e.g. a stale published build).
|
|
25656
|
+
// Wins over --installer-tag / the pinned default.
|
|
25657
|
+
installerImage = Option46.String("--installer-image");
|
|
25628
25658
|
gatewayImageRef = Option46.String("--gateway-image-ref");
|
|
25629
25659
|
githubAppCreds = Option46.String("--github-app-creds");
|
|
25630
25660
|
async executeCommand() {
|
|
@@ -25635,6 +25665,8 @@ var BootstrapLaunchCommand = class extends M8tCommand {
|
|
|
25635
25665
|
const resourceGroup = (typeof this.resourceGroup === "string" ? this.resourceGroup : void 0) ?? DEFAULT_RG;
|
|
25636
25666
|
const clientIdOpt = typeof this.clientId === "string" ? this.clientId : void 0;
|
|
25637
25667
|
const installerTag = (typeof this.installerTag === "string" ? this.installerTag : void 0) ?? DEFAULT_INSTALLER_TAG;
|
|
25668
|
+
const installerImageOverride = typeof this.installerImage === "string" ? this.installerImage : void 0;
|
|
25669
|
+
const installerImage = installerImageOverride ?? `${DEFAULT_INSTALLER}:${installerTag}`;
|
|
25638
25670
|
const gatewayImageRef = typeof this.gatewayImageRef === "string" ? this.gatewayImageRef : void 0;
|
|
25639
25671
|
const account = await getAzAccount();
|
|
25640
25672
|
const subscriptionId = (typeof this.subscription === "string" ? this.subscription : void 0) ?? account.subscriptionId;
|
|
@@ -25685,10 +25717,24 @@ var BootstrapLaunchCommand = class extends M8tCommand {
|
|
|
25685
25717
|
out("granting Owner at subscription scope\u2026");
|
|
25686
25718
|
await grantOwnerAtSubscription({ principalId: mi.principalId, subscriptionId });
|
|
25687
25719
|
const roleAssignmentIds = await listAssignmentIds({ principalId: mi.principalId, subscriptionId });
|
|
25720
|
+
const saName = deriveStatusSaName(resourceGroup, subscriptionId);
|
|
25721
|
+
await writeBootstrapState({
|
|
25722
|
+
subscriptionId,
|
|
25723
|
+
resourceGroup,
|
|
25724
|
+
location,
|
|
25725
|
+
aciName: ACI_NAME,
|
|
25726
|
+
miName: MI_NAME,
|
|
25727
|
+
miClientId: mi.clientId,
|
|
25728
|
+
miPrincipalId: mi.principalId,
|
|
25729
|
+
roleAssignmentIds,
|
|
25730
|
+
appRegClientId: appReg.clientId,
|
|
25731
|
+
statusSaName: saName,
|
|
25732
|
+
statusBlobUrl: statusBlobUrl(saName),
|
|
25733
|
+
installerTag
|
|
25734
|
+
});
|
|
25688
25735
|
out("waiting for the installer identity to be usable (role propagation)\u2026");
|
|
25689
25736
|
const miReady = await waitForMiToken({ clientId: mi.clientId, subscriptionId, onProgress: out });
|
|
25690
25737
|
if (!miReady) out("identity not confirmed yet \u2014 launching anyway (the installer retries its own login)");
|
|
25691
|
-
const saName = deriveStatusSaName(resourceGroup, subscriptionId);
|
|
25692
25738
|
out("launching the cloud installer (ACI)\u2026");
|
|
25693
25739
|
await kickInstaller({
|
|
25694
25740
|
aciName: ACI_NAME,
|
|
@@ -25698,25 +25744,11 @@ var BootstrapLaunchCommand = class extends M8tCommand {
|
|
|
25698
25744
|
miResourceId: mi.resourceId,
|
|
25699
25745
|
miClientId: mi.clientId,
|
|
25700
25746
|
appRegClientId: appReg.clientId,
|
|
25701
|
-
image:
|
|
25747
|
+
image: installerImage,
|
|
25702
25748
|
gatewayImageRef,
|
|
25703
25749
|
foundryTracing: "skip",
|
|
25704
25750
|
githubApp
|
|
25705
25751
|
});
|
|
25706
|
-
await writeBootstrapState({
|
|
25707
|
-
subscriptionId,
|
|
25708
|
-
resourceGroup,
|
|
25709
|
-
location,
|
|
25710
|
-
aciName: ACI_NAME,
|
|
25711
|
-
miName: MI_NAME,
|
|
25712
|
-
miClientId: mi.clientId,
|
|
25713
|
-
miPrincipalId: mi.principalId,
|
|
25714
|
-
roleAssignmentIds,
|
|
25715
|
-
appRegClientId: appReg.clientId,
|
|
25716
|
-
statusSaName: saName,
|
|
25717
|
-
statusBlobUrl: statusBlobUrl(saName),
|
|
25718
|
-
installerTag
|
|
25719
|
-
});
|
|
25720
25752
|
this.context.stdout.write(
|
|
25721
25753
|
`${colors.success("\u2713")} installer launched in ${colors.field(resourceGroup)} (${location}).
|
|
25722
25754
|
${colors.hint("next:")} m8t bootstrap status --watch ${colors.dim("# watch the install to done")}
|
|
@@ -25775,7 +25807,7 @@ var BootstrapStatusCommand = class extends M8tCommand {
|
|
|
25775
25807
|
typeof this.output === "string" ? this.output : void 0,
|
|
25776
25808
|
this.context.stdout
|
|
25777
25809
|
);
|
|
25778
|
-
const
|
|
25810
|
+
const sleep4 = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
25779
25811
|
const watch = this.watch === true;
|
|
25780
25812
|
for (; ; ) {
|
|
25781
25813
|
let doc;
|
|
@@ -25785,7 +25817,7 @@ var BootstrapStatusCommand = class extends M8tCommand {
|
|
|
25785
25817
|
if (watch && e instanceof LocalCliError && e.code === "BOOTSTRAP_STATUS_UNREADABLE") {
|
|
25786
25818
|
if (mode === "pretty") this.context.stderr.write(` ${colors.dim("waiting for the installer to start\u2026")}
|
|
25787
25819
|
`);
|
|
25788
|
-
await
|
|
25820
|
+
await sleep4(1e4);
|
|
25789
25821
|
continue;
|
|
25790
25822
|
}
|
|
25791
25823
|
throw e;
|
|
@@ -25810,7 +25842,7 @@ var BootstrapStatusCommand = class extends M8tCommand {
|
|
|
25810
25842
|
);
|
|
25811
25843
|
return 1;
|
|
25812
25844
|
}
|
|
25813
|
-
await
|
|
25845
|
+
await sleep4(1e4);
|
|
25814
25846
|
}
|
|
25815
25847
|
}
|
|
25816
25848
|
};
|
|
@@ -25944,24 +25976,43 @@ Found ${String(found.length)} orphaned Owner@sub assignment(s) (dry-run). ${colo
|
|
|
25944
25976
|
}
|
|
25945
25977
|
const state = await readBootstrapState();
|
|
25946
25978
|
if (!state) {
|
|
25947
|
-
|
|
25979
|
+
if (this.force === true) {
|
|
25980
|
+
const { subscriptionId: sub } = await getAzAccount();
|
|
25981
|
+
if (!sub) {
|
|
25982
|
+
throw new LocalCliError({ code: "BOOTSTRAP_SWEEP_NO_SUB", message: "No active subscription.", hint: "Run 'az account set --subscription <id>'." });
|
|
25983
|
+
}
|
|
25984
|
+
const found = await sweepOrphanOwnerAssignments({ subscriptionId: sub, execute: true });
|
|
25985
|
+
this.context.stdout.write(
|
|
25986
|
+
found.length === 0 ? `${colors.success("\u2713")} No bootstrap state and no orphaned installer Owner@sub assignments. Nothing to reap.
|
|
25987
|
+
` : `${colors.success("\u2713")} No bootstrap state found; swept ${String(found.length)} orphaned installer Owner@sub assignment(s).
|
|
25988
|
+
`
|
|
25989
|
+
);
|
|
25990
|
+
return 0;
|
|
25991
|
+
}
|
|
25992
|
+
throw new LocalCliError({
|
|
25993
|
+
code: "BOOTSTRAP_NO_STATE",
|
|
25994
|
+
message: "No bootstrap state to reap.",
|
|
25995
|
+
hint: "Nothing to do. If a launch failed early it may have orphaned an installer Owner@sub grant \u2014 run 'm8t bootstrap reap --force' (or 'm8t bootstrap reap --sweep-orphans --yes') to clean it."
|
|
25996
|
+
});
|
|
25948
25997
|
}
|
|
25949
|
-
|
|
25950
|
-
|
|
25951
|
-
if (doc.status
|
|
25998
|
+
if (this.force !== true) {
|
|
25999
|
+
const doc = await readStatusBlob({ saName: state.statusSaName, resourceGroup: state.resourceGroup, subscriptionId: state.subscriptionId });
|
|
26000
|
+
if (doc.status !== "done") {
|
|
26001
|
+
if (doc.status === "failed") {
|
|
26002
|
+
throw new LocalCliError({
|
|
26003
|
+
code: "BOOTSTRAP_REAP_FAILED_INSTALL",
|
|
26004
|
+
message: `The install failed at '${doc.error?.phase ?? doc.phase}'. Leaving the installer up for diagnosis.`,
|
|
26005
|
+
hint: `Inspect: az container logs -n ${state.aciName} -g ${state.resourceGroup}. Reap anyway with --force.`
|
|
26006
|
+
});
|
|
26007
|
+
}
|
|
26008
|
+
const aci = await getAciState({ aciName: state.aciName, resourceGroup: state.resourceGroup, subscriptionId: state.subscriptionId }).catch(() => null);
|
|
26009
|
+
const deadHint = aci?.terminated ? `The installer container has terminated (exit ${String(aci.exitCode ?? "?")}) without reaching done \u2014 reap with --force.` : `Wait for 'm8t bootstrap status --watch' to reach done, or reap with --force if the install is stuck.`;
|
|
25952
26010
|
throw new LocalCliError({
|
|
25953
|
-
code: "
|
|
25954
|
-
message: `The install
|
|
25955
|
-
hint:
|
|
26011
|
+
code: "BOOTSTRAP_REAP_NOT_DONE",
|
|
26012
|
+
message: `The install is not done yet (status: ${doc.status}, phase: ${doc.phase}).`,
|
|
26013
|
+
hint: deadHint
|
|
25956
26014
|
});
|
|
25957
26015
|
}
|
|
25958
|
-
const aci = await getAciState({ aciName: state.aciName, resourceGroup: state.resourceGroup, subscriptionId: state.subscriptionId }).catch(() => null);
|
|
25959
|
-
const deadHint = aci?.terminated ? `The installer container has terminated (exit ${String(aci.exitCode ?? "?")}) without reaching done \u2014 reap with --force.` : `Wait for 'm8t bootstrap status --watch' to reach done, or reap with --force if the install is stuck.`;
|
|
25960
|
-
throw new LocalCliError({
|
|
25961
|
-
code: "BOOTSTRAP_REAP_NOT_DONE",
|
|
25962
|
-
message: `The install is not done yet (status: ${doc.status}, phase: ${doc.phase}).`,
|
|
25963
|
-
hint: deadHint
|
|
25964
|
-
});
|
|
25965
26016
|
}
|
|
25966
26017
|
await reapInstaller({
|
|
25967
26018
|
subscriptionId: state.subscriptionId,
|
|
@@ -26419,11 +26470,108 @@ import * as path35 from "path";
|
|
|
26419
26470
|
import { spawn as spawn7 } from "child_process";
|
|
26420
26471
|
init_errors();
|
|
26421
26472
|
init_rbac();
|
|
26473
|
+
|
|
26474
|
+
// src/lib/simple-stacey.ts
|
|
26475
|
+
var SIMPLE_STACEY_PERSONA = "startup-advisor-intake";
|
|
26476
|
+
var SIMPLE_STACEY_AGENT = "stacey-intake";
|
|
26477
|
+
async function deploySimpleStacey(args) {
|
|
26478
|
+
try {
|
|
26479
|
+
return await deployPromptAdvisor({
|
|
26480
|
+
credential: args.credential,
|
|
26481
|
+
endpoint: args.endpoint,
|
|
26482
|
+
repoRoot: args.repoRoot,
|
|
26483
|
+
persona: SIMPLE_STACEY_PERSONA,
|
|
26484
|
+
agentName: SIMPLE_STACEY_AGENT,
|
|
26485
|
+
fieldOverrides: args.fieldOverrides
|
|
26486
|
+
});
|
|
26487
|
+
} catch (e) {
|
|
26488
|
+
if (e && typeof e === "object" && "code" in e) {
|
|
26489
|
+
const err = e;
|
|
26490
|
+
if (err.code === "ADVISOR_PERSONA_MISSING") {
|
|
26491
|
+
const { LocalCliError: LocalCliError2 } = await Promise.resolve().then(() => (init_errors(), errors_exports));
|
|
26492
|
+
throw new LocalCliError2({
|
|
26493
|
+
code: "SIMPLE_STACEY_PERSONA_MISSING",
|
|
26494
|
+
message: err.message,
|
|
26495
|
+
hint: err.hint,
|
|
26496
|
+
cause: err.cause
|
|
26497
|
+
});
|
|
26498
|
+
}
|
|
26499
|
+
if (err.code === "ADVISOR_NO_MODEL") {
|
|
26500
|
+
const { LocalCliError: LocalCliError2 } = await Promise.resolve().then(() => (init_errors(), errors_exports));
|
|
26501
|
+
throw new LocalCliError2({
|
|
26502
|
+
code: "SIMPLE_STACEY_NO_MODEL",
|
|
26503
|
+
message: err.message,
|
|
26504
|
+
hint: err.hint,
|
|
26505
|
+
cause: err.cause
|
|
26506
|
+
});
|
|
26507
|
+
}
|
|
26508
|
+
if (err.code === "ADVISOR_BAD_EFFORT") {
|
|
26509
|
+
const { LocalCliError: LocalCliError2 } = await Promise.resolve().then(() => (init_errors(), errors_exports));
|
|
26510
|
+
throw new LocalCliError2({
|
|
26511
|
+
code: "SIMPLE_STACEY_BAD_EFFORT",
|
|
26512
|
+
message: err.message,
|
|
26513
|
+
hint: err.hint,
|
|
26514
|
+
cause: err.cause
|
|
26515
|
+
});
|
|
26516
|
+
}
|
|
26517
|
+
}
|
|
26518
|
+
throw e;
|
|
26519
|
+
}
|
|
26520
|
+
}
|
|
26521
|
+
|
|
26522
|
+
// src/lib/bootstrap-ui.ts
|
|
26523
|
+
function sleep3(ms) {
|
|
26524
|
+
return new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
26525
|
+
}
|
|
26526
|
+
function isAuthorizationShapedError(error) {
|
|
26527
|
+
const seen = /* @__PURE__ */ new Set();
|
|
26528
|
+
let current = error;
|
|
26529
|
+
while (current != null && !seen.has(current)) {
|
|
26530
|
+
seen.add(current);
|
|
26531
|
+
if (typeof current === "object") {
|
|
26532
|
+
const record = current;
|
|
26533
|
+
if (record.statusCode === 403) return true;
|
|
26534
|
+
if (typeof record.message === "string" && /403|Forbidden|PermissionDenied|not authorized/i.test(record.message)) return true;
|
|
26535
|
+
current = record.cause;
|
|
26536
|
+
continue;
|
|
26537
|
+
}
|
|
26538
|
+
if (typeof current === "string" && /403|Forbidden|PermissionDenied|not authorized/i.test(current)) return true;
|
|
26539
|
+
break;
|
|
26540
|
+
}
|
|
26541
|
+
return false;
|
|
26542
|
+
}
|
|
26543
|
+
async function deploySimpleStaceyWithRetry(args) {
|
|
26544
|
+
const maxWaitMs = args.maxWaitMs ?? 3e5;
|
|
26545
|
+
const intervalMs = args.intervalMs ?? 1e4;
|
|
26546
|
+
const deadline = Date.now() + maxWaitMs;
|
|
26547
|
+
for (; ; ) {
|
|
26548
|
+
try {
|
|
26549
|
+
return await deploySimpleStacey({
|
|
26550
|
+
credential: args.credential,
|
|
26551
|
+
endpoint: args.endpoint,
|
|
26552
|
+
repoRoot: args.repoRoot,
|
|
26553
|
+
fieldOverrides: args.fieldOverrides
|
|
26554
|
+
});
|
|
26555
|
+
} catch (error) {
|
|
26556
|
+
if (!isAuthorizationShapedError(error)) throw error;
|
|
26557
|
+
const remainingMs = deadline - Date.now();
|
|
26558
|
+
if (remainingMs <= 0) {
|
|
26559
|
+
throw new LocalCliError({
|
|
26560
|
+
code: "BOOTSTRAP_UI_ROLE_PROPAGATION_TIMEOUT",
|
|
26561
|
+
message: "Timed out waiting for Azure role propagation before deploying Simple Stacey.",
|
|
26562
|
+
hint: "Azure role propagation can take a few minutes - re-run 'm8t bootstrap ui' (idempotent).",
|
|
26563
|
+
cause: error
|
|
26564
|
+
});
|
|
26565
|
+
}
|
|
26566
|
+
args.onWait?.("waiting for Azure role propagation...");
|
|
26567
|
+
await sleep3(Math.min(intervalMs, remainingMs));
|
|
26568
|
+
}
|
|
26569
|
+
}
|
|
26570
|
+
}
|
|
26422
26571
|
async function resolveFoundryEndpointWithWait(args, opts = {}) {
|
|
26423
26572
|
const pollMs = opts.pollMs ?? 1e4;
|
|
26424
26573
|
const timeoutMs = opts.timeoutMs ?? 15 * 6e4;
|
|
26425
26574
|
const deadline = Date.now() + timeoutMs;
|
|
26426
|
-
const sleep3 = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
26427
26575
|
for (; ; ) {
|
|
26428
26576
|
try {
|
|
26429
26577
|
const p = await resolveFoundryProject({
|
|
@@ -26598,9 +26746,9 @@ async function serveOnboardingUiDetached(args) {
|
|
|
26598
26746
|
child.unref();
|
|
26599
26747
|
fs32.writeFileSync(pidPath, String(child.pid), "utf8");
|
|
26600
26748
|
const deadline = Date.now() + 45e3;
|
|
26601
|
-
const
|
|
26749
|
+
const sleep4 = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
26602
26750
|
while (Date.now() < deadline) {
|
|
26603
|
-
await
|
|
26751
|
+
await sleep4(500);
|
|
26604
26752
|
if (await isPortOpen()) break;
|
|
26605
26753
|
}
|
|
26606
26754
|
return { alreadyRunning: false, logPath };
|
|
@@ -26638,9 +26786,9 @@ async function serveOnboardingRelayDetached(args) {
|
|
|
26638
26786
|
child.unref();
|
|
26639
26787
|
fs32.writeFileSync(pidPath, String(child.pid), "utf8");
|
|
26640
26788
|
const deadline = Date.now() + 45e3;
|
|
26641
|
-
const
|
|
26789
|
+
const sleep4 = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
26642
26790
|
while (Date.now() < deadline) {
|
|
26643
|
-
await
|
|
26791
|
+
await sleep4(500);
|
|
26644
26792
|
if (await isLocalPortOpen(portNum)) break;
|
|
26645
26793
|
}
|
|
26646
26794
|
return { alreadyRunning: false, logPath };
|
|
@@ -26682,55 +26830,21 @@ function stopOnboardingUi(home = os17.homedir()) {
|
|
|
26682
26830
|
return uiStopped || relayStopped;
|
|
26683
26831
|
}
|
|
26684
26832
|
|
|
26685
|
-
// src/lib/simple-stacey.ts
|
|
26686
|
-
var SIMPLE_STACEY_PERSONA = "startup-advisor-intake";
|
|
26687
|
-
var SIMPLE_STACEY_AGENT = "stacey-intake";
|
|
26688
|
-
async function deploySimpleStacey(args) {
|
|
26689
|
-
try {
|
|
26690
|
-
return await deployPromptAdvisor({
|
|
26691
|
-
credential: args.credential,
|
|
26692
|
-
endpoint: args.endpoint,
|
|
26693
|
-
repoRoot: args.repoRoot,
|
|
26694
|
-
persona: SIMPLE_STACEY_PERSONA,
|
|
26695
|
-
agentName: SIMPLE_STACEY_AGENT,
|
|
26696
|
-
fieldOverrides: args.fieldOverrides
|
|
26697
|
-
});
|
|
26698
|
-
} catch (e) {
|
|
26699
|
-
if (e && typeof e === "object" && "code" in e) {
|
|
26700
|
-
const err = e;
|
|
26701
|
-
if (err.code === "ADVISOR_PERSONA_MISSING") {
|
|
26702
|
-
const { LocalCliError: LocalCliError2 } = await Promise.resolve().then(() => (init_errors(), errors_exports));
|
|
26703
|
-
throw new LocalCliError2({
|
|
26704
|
-
code: "SIMPLE_STACEY_PERSONA_MISSING",
|
|
26705
|
-
message: err.message,
|
|
26706
|
-
hint: err.hint,
|
|
26707
|
-
cause: err.cause
|
|
26708
|
-
});
|
|
26709
|
-
}
|
|
26710
|
-
if (err.code === "ADVISOR_NO_MODEL") {
|
|
26711
|
-
const { LocalCliError: LocalCliError2 } = await Promise.resolve().then(() => (init_errors(), errors_exports));
|
|
26712
|
-
throw new LocalCliError2({
|
|
26713
|
-
code: "SIMPLE_STACEY_NO_MODEL",
|
|
26714
|
-
message: err.message,
|
|
26715
|
-
hint: err.hint,
|
|
26716
|
-
cause: err.cause
|
|
26717
|
-
});
|
|
26718
|
-
}
|
|
26719
|
-
if (err.code === "ADVISOR_BAD_EFFORT") {
|
|
26720
|
-
const { LocalCliError: LocalCliError2 } = await Promise.resolve().then(() => (init_errors(), errors_exports));
|
|
26721
|
-
throw new LocalCliError2({
|
|
26722
|
-
code: "SIMPLE_STACEY_BAD_EFFORT",
|
|
26723
|
-
message: err.message,
|
|
26724
|
-
hint: err.hint,
|
|
26725
|
-
cause: err.cause
|
|
26726
|
-
});
|
|
26727
|
-
}
|
|
26728
|
-
}
|
|
26729
|
-
throw e;
|
|
26730
|
-
}
|
|
26731
|
-
}
|
|
26732
|
-
|
|
26733
26833
|
// src/commands/bootstrap/ui.ts
|
|
26834
|
+
function renderDeploySuccess(version, envPath) {
|
|
26835
|
+
return `${colors.success("\u2713")} Simple Stacey is live (stacey-intake v${version}).
|
|
26836
|
+
env: ${envPath}
|
|
26837
|
+
Opening ${colors.field("http://localhost:3000")} in your browser \u2192 Sign in with Microsoft \u2192 chat with Stacey.
|
|
26838
|
+
${colors.dim("(If it doesn't open, browse to http://localhost:3000 yourself.)")}
|
|
26839
|
+
${colors.dim("First turn may say 'warming up' for a few minutes while access propagates \u2014 that's expected.")}
|
|
26840
|
+
`;
|
|
26841
|
+
}
|
|
26842
|
+
function renderDeployFailure(error) {
|
|
26843
|
+
const hint = error instanceof LocalCliError && error.hint ? error.hint : "Re-run 'm8t bootstrap ui' (idempotent).";
|
|
26844
|
+
return `${colors.error("\u2717")} Simple Stacey deploy failed: ${error.message}
|
|
26845
|
+
${colors.hint(hint)}
|
|
26846
|
+
`;
|
|
26847
|
+
}
|
|
26734
26848
|
var BootstrapUiCommand = class extends M8tCommand {
|
|
26735
26849
|
static paths = [["bootstrap", "ui"]];
|
|
26736
26850
|
static usage = Command53.Usage({
|
|
@@ -26810,14 +26924,18 @@ var BootstrapUiCommand = class extends M8tCommand {
|
|
|
26810
26924
|
out("granting you Foundry data-plane access\u2026");
|
|
26811
26925
|
const oid = await getSignedInUserOid();
|
|
26812
26926
|
await ensureFounderFoundryRole({ credential: credential2, subscriptionId: state.subscriptionId, principalId: oid, accountScope });
|
|
26813
|
-
out("deploying Simple Stacey (stacey-intake)\u2026");
|
|
26814
26927
|
const identity = await getSignedInUserIdentity();
|
|
26815
|
-
|
|
26928
|
+
out("deploying Simple Stacey (stacey-intake) in the background...");
|
|
26929
|
+
const deployOutcome = deploySimpleStaceyWithRetry({
|
|
26816
26930
|
credential: credential2,
|
|
26817
26931
|
endpoint,
|
|
26818
26932
|
repoRoot,
|
|
26819
|
-
fieldOverrides: { founder_identity_note: composeFounderIdentityNote(identity) }
|
|
26820
|
-
|
|
26933
|
+
fieldOverrides: { founder_identity_note: composeFounderIdentityNote(identity) },
|
|
26934
|
+
onWait: out
|
|
26935
|
+
}).then(
|
|
26936
|
+
(version) => ({ ok: true, version }),
|
|
26937
|
+
(error) => ({ ok: false, error: error instanceof Error ? error : new Error(String(error)) })
|
|
26938
|
+
);
|
|
26821
26939
|
const envPath = writeWebEnvLocal({
|
|
26822
26940
|
repoRoot,
|
|
26823
26941
|
tenantId: account.tenantId,
|
|
@@ -26828,15 +26946,10 @@ var BootstrapUiCommand = class extends M8tCommand {
|
|
|
26828
26946
|
out("installing apps/web dependencies (pnpm)\u2026");
|
|
26829
26947
|
await installWebDeps(repoRoot);
|
|
26830
26948
|
}
|
|
26831
|
-
this.context.stdout.write(
|
|
26832
|
-
`${colors.success("\u2713")} Simple Stacey is live (stacey-intake v${version}).
|
|
26833
|
-
env: ${envPath}
|
|
26834
|
-
Opening ${colors.field("http://localhost:3000")} in your browser \u2192 Sign in with Microsoft \u2192 chat with Stacey.
|
|
26835
|
-
${colors.dim("(If it doesn't open, browse to http://localhost:3000 yourself.)")}
|
|
26836
|
-
${colors.dim("First turn may say 'warming up' for a few minutes while access propagates \u2014 that's expected.")}
|
|
26837
|
-
`
|
|
26838
|
-
);
|
|
26839
26949
|
if (this.prepOnly === true) {
|
|
26950
|
+
const outcome2 = await deployOutcome;
|
|
26951
|
+
if (!outcome2.ok) throw outcome2.error;
|
|
26952
|
+
this.context.stdout.write(renderDeploySuccess(outcome2.version, envPath));
|
|
26840
26953
|
this.context.stdout.write(` ${colors.hint("serve it yourself:")} pnpm --filter web dev
|
|
26841
26954
|
`);
|
|
26842
26955
|
return 0;
|
|
@@ -26850,6 +26963,12 @@ var BootstrapUiCommand = class extends M8tCommand {
|
|
|
26850
26963
|
clientId: state.appRegClientId
|
|
26851
26964
|
});
|
|
26852
26965
|
out("voice relay on :8790");
|
|
26966
|
+
const outcome2 = await deployOutcome;
|
|
26967
|
+
if (!outcome2.ok) {
|
|
26968
|
+
this.context.stderr.write(renderDeployFailure(outcome2.error));
|
|
26969
|
+
return 1;
|
|
26970
|
+
}
|
|
26971
|
+
this.context.stdout.write(renderDeploySuccess(outcome2.version, envPath));
|
|
26853
26972
|
out("starting the webapp on :3000 (Ctrl-C to stop)\u2026");
|
|
26854
26973
|
await runInherit("pnpm", ["--filter", "web", "dev"], repoRoot, "BOOTSTRAP_UI_DEV_FAILED");
|
|
26855
26974
|
return 0;
|
|
@@ -26877,6 +26996,12 @@ var BootstrapUiCommand = class extends M8tCommand {
|
|
|
26877
26996
|
);
|
|
26878
26997
|
}
|
|
26879
26998
|
autoOpenOnboardingUi(`http://localhost:${this.port}`);
|
|
26999
|
+
const outcome = await deployOutcome;
|
|
27000
|
+
if (!outcome.ok) {
|
|
27001
|
+
this.context.stderr.write(renderDeployFailure(outcome.error));
|
|
27002
|
+
return 1;
|
|
27003
|
+
}
|
|
27004
|
+
this.context.stdout.write(renderDeploySuccess(outcome.version, envPath));
|
|
26880
27005
|
return 0;
|
|
26881
27006
|
}
|
|
26882
27007
|
};
|
|
@@ -26914,7 +27039,7 @@ var BootstrapSeedProfileCommand = class extends M8tCommand {
|
|
|
26914
27039
|
const parsedTimeout = Number(rawTimeout);
|
|
26915
27040
|
const timeoutMin = rawTimeout !== "" && Number.isFinite(parsedTimeout) ? parsedTimeout : 20;
|
|
26916
27041
|
const deadline = Date.now() + timeoutMin * 6e4;
|
|
26917
|
-
const
|
|
27042
|
+
const sleep4 = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
26918
27043
|
for (; ; ) {
|
|
26919
27044
|
const token = await getFoundryToken();
|
|
26920
27045
|
const { hadIntake, block } = await findOnboardingProfile({ endpoint: ctx.endpoint, token });
|
|
@@ -26937,7 +27062,7 @@ var BootstrapSeedProfileCommand = class extends M8tCommand {
|
|
|
26937
27062
|
}
|
|
26938
27063
|
this.context.stderr.write(` ${colors.dim("waiting for the questionnaire to complete\u2026")}
|
|
26939
27064
|
`);
|
|
26940
|
-
await
|
|
27065
|
+
await sleep4(2e4);
|
|
26941
27066
|
}
|
|
26942
27067
|
}
|
|
26943
27068
|
};
|