@m8t-stack/cli 0.2.40 → 0.2.42
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/cli.js +603 -253
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1298,7 +1298,7 @@ var init_enable_hosted_brain = __esm({
|
|
|
1298
1298
|
import { Builtins, Cli } from "clipanion";
|
|
1299
1299
|
|
|
1300
1300
|
// src/lib/package-version.ts
|
|
1301
|
-
var CLI_VERSION = "0.2.
|
|
1301
|
+
var CLI_VERSION = "0.2.42";
|
|
1302
1302
|
|
|
1303
1303
|
// src/lib/render-error.ts
|
|
1304
1304
|
init_errors();
|
|
@@ -17955,6 +17955,21 @@ function entityToApplyRequest(e) {
|
|
|
17955
17955
|
return JSON.parse(e.value);
|
|
17956
17956
|
}
|
|
17957
17957
|
|
|
17958
|
+
// ../../packages/platform-release/dist/esm/update-policy.js
|
|
17959
|
+
var DEFAULT_POLICY_MODE = "auto-critical";
|
|
17960
|
+
var UPDATE_POLICY_PK = "system";
|
|
17961
|
+
var UPDATE_POLICY_RK = "update-policy";
|
|
17962
|
+
var MODES = ["notify-only", "auto-critical", "auto-all"];
|
|
17963
|
+
function isPolicyMode(x) {
|
|
17964
|
+
return typeof x === "string" && MODES.includes(x);
|
|
17965
|
+
}
|
|
17966
|
+
function updatePolicyToEntity(p) {
|
|
17967
|
+
return { partitionKey: UPDATE_POLICY_PK, rowKey: UPDATE_POLICY_RK, value: JSON.stringify(p) };
|
|
17968
|
+
}
|
|
17969
|
+
function entityToUpdatePolicy(e) {
|
|
17970
|
+
return JSON.parse(e.value);
|
|
17971
|
+
}
|
|
17972
|
+
|
|
17958
17973
|
// ../../packages/platform-release/dist/esm/infra-params.js
|
|
17959
17974
|
var INFRA_PARAMS_PK = "system";
|
|
17960
17975
|
var INFRA_PARAMS_RK = "infra-params";
|
|
@@ -18236,25 +18251,31 @@ async function writeStamp(opts) {
|
|
|
18236
18251
|
...opts.onProgress ? { onProgress: opts.onProgress } : {}
|
|
18237
18252
|
});
|
|
18238
18253
|
}
|
|
18239
|
-
async function
|
|
18254
|
+
async function readStampOutcome(opts) {
|
|
18240
18255
|
const { tableEndpoint, accountResourceId, accountName } = await discoverStampStorage(opts);
|
|
18241
18256
|
const aad = new TableClient2(tableEndpoint, TABLE, opts.credential);
|
|
18242
18257
|
try {
|
|
18243
18258
|
const row = await aad.getEntity(PK, RK);
|
|
18244
|
-
|
|
18259
|
+
const stamp = entityToStamp(row);
|
|
18260
|
+
return stamp ? { source: "explicit", stamp } : { source: "unreadable" };
|
|
18245
18261
|
} catch (e) {
|
|
18246
|
-
if (is404(e)) return
|
|
18247
|
-
if (!is403(e)) return
|
|
18262
|
+
if (is404(e)) return { source: "absent" };
|
|
18263
|
+
if (!is403(e)) return { source: "unreadable" };
|
|
18248
18264
|
}
|
|
18249
18265
|
try {
|
|
18250
18266
|
const shared = await makeSharedKeyClient({ tableEndpoint, accountResourceId, accountName });
|
|
18251
|
-
if (!shared) return
|
|
18267
|
+
if (!shared) return { source: "unreadable" };
|
|
18252
18268
|
const row = await shared.getEntity(PK, RK);
|
|
18253
|
-
|
|
18269
|
+
const stamp = entityToStamp(row);
|
|
18270
|
+
return stamp ? { source: "explicit", stamp } : { source: "unreadable" };
|
|
18254
18271
|
} catch {
|
|
18255
|
-
return
|
|
18272
|
+
return { source: "unreadable" };
|
|
18256
18273
|
}
|
|
18257
18274
|
}
|
|
18275
|
+
async function readStamp(opts) {
|
|
18276
|
+
const result = await readStampOutcome(opts);
|
|
18277
|
+
return result.source === "explicit" ? result.stamp : null;
|
|
18278
|
+
}
|
|
18258
18279
|
|
|
18259
18280
|
// src/lib/platform-converge.ts
|
|
18260
18281
|
import * as fs22 from "fs";
|
|
@@ -18278,6 +18299,16 @@ function parseFoundryTracingMode(v) {
|
|
|
18278
18299
|
}
|
|
18279
18300
|
return v;
|
|
18280
18301
|
}
|
|
18302
|
+
function parseAssignSubscriptionRoles(v) {
|
|
18303
|
+
if (v === void 0) return void 0;
|
|
18304
|
+
if (v === "true") return true;
|
|
18305
|
+
if (v === "false") return false;
|
|
18306
|
+
throw new LocalCliError({
|
|
18307
|
+
code: "DEPLOY_INVALID_ASSIGN_SUBSCRIPTION_ROLES",
|
|
18308
|
+
message: `Invalid --assign-subscription-roles value: '${v}'.`,
|
|
18309
|
+
hint: "Use one of: true, false."
|
|
18310
|
+
});
|
|
18311
|
+
}
|
|
18281
18312
|
function buildBicepParams(p) {
|
|
18282
18313
|
const params = [
|
|
18283
18314
|
`location=${p.location}`,
|
|
@@ -20462,8 +20493,215 @@ var PlatformSeedStampCommand = class extends M8tCommand {
|
|
|
20462
20493
|
}
|
|
20463
20494
|
};
|
|
20464
20495
|
|
|
20465
|
-
// src/commands/platform/
|
|
20496
|
+
// src/commands/platform/stamp-build.ts
|
|
20466
20497
|
import { Command as Command35, Option as Option32 } from "clipanion";
|
|
20498
|
+
import { DefaultAzureCredential as DefaultAzureCredential19, ManagedIdentityCredential as ManagedIdentityCredential3 } from "@azure/identity";
|
|
20499
|
+
init_errors();
|
|
20500
|
+
|
|
20501
|
+
// src/lib/platform-stamp-build.ts
|
|
20502
|
+
var BARE_SEMVER2 = /^\d+\.\d+\.\d+$/;
|
|
20503
|
+
function buildRunningBuildStamp(input) {
|
|
20504
|
+
if (!BARE_SEMVER2.test(input.version)) {
|
|
20505
|
+
throw new Error(
|
|
20506
|
+
`platform version must be bare X.Y.Z, got "${input.version}" \u2014 a build tag cannot be represented as a version.`
|
|
20507
|
+
);
|
|
20508
|
+
}
|
|
20509
|
+
return {
|
|
20510
|
+
schemaVersion: 1,
|
|
20511
|
+
platformVersion: platformTag(input.version),
|
|
20512
|
+
previousPlatformVersion: input.previousPlatformVersion,
|
|
20513
|
+
updatedAt: input.nowIso,
|
|
20514
|
+
lastResult: "success",
|
|
20515
|
+
cli: input.cliVersion,
|
|
20516
|
+
origin: "cd",
|
|
20517
|
+
components: {
|
|
20518
|
+
gateway: { tag: input.gatewayTag, digest: input.gatewayDigest, state: "managed" },
|
|
20519
|
+
codingAgent: { tag: "", digest: "", state: "external" },
|
|
20520
|
+
azureExecutor: { tag: "", digest: "", state: "external" },
|
|
20521
|
+
personas: input.personas,
|
|
20522
|
+
infra: { treeSha: input.infraTreeSha },
|
|
20523
|
+
...input.brainSeeds ? { brainSeeds: input.brainSeeds } : {}
|
|
20524
|
+
}
|
|
20525
|
+
};
|
|
20526
|
+
}
|
|
20527
|
+
|
|
20528
|
+
// src/commands/platform/stamp-build.ts
|
|
20529
|
+
var PlatformStampBuildCommand = class extends M8tCommand {
|
|
20530
|
+
static paths = [["platform", "stamp-build"]];
|
|
20531
|
+
static usage = Command35.Usage({
|
|
20532
|
+
description: "Record the currently running build as this install's platform version.",
|
|
20533
|
+
details: "For installs that are deployed continuously rather than from a published release. Unlike the install-time record, this overwrites on every run \u2014 the running build is the truth. Only components this writer deploys are reported; the rest are marked as managed elsewhere."
|
|
20534
|
+
});
|
|
20535
|
+
version = Option32.String("--version", { description: "The running build's own version, bare X.Y.Z." });
|
|
20536
|
+
gatewayTag = Option32.String("--gateway-tag", { description: "The tag of the gateway image this build deployed." });
|
|
20537
|
+
gatewayDigest = Option32.String("--gateway-digest", { description: "The digest of the gateway image this build deployed." });
|
|
20538
|
+
subscription = Option32.String("--subscription");
|
|
20539
|
+
resourceGroup = Option32.String("--resource-group");
|
|
20540
|
+
miClientId = Option32.String("--mi-client-id", { description: "Authenticate as this user-assigned managed identity instead of the ambient credential." });
|
|
20541
|
+
output = Option32.String("--output");
|
|
20542
|
+
async executeCommand() {
|
|
20543
|
+
const mode = resolveOutputMode(this.output, this.context.stdout);
|
|
20544
|
+
const need = (v, flag) => {
|
|
20545
|
+
if (typeof v !== "string" || v.trim().length === 0) {
|
|
20546
|
+
throw new LocalCliError({ code: "PLATFORM_STAMP_BUILD_ARG_MISSING", message: `${flag} is required.` });
|
|
20547
|
+
}
|
|
20548
|
+
return v.trim();
|
|
20549
|
+
};
|
|
20550
|
+
const onProgress = (m) => {
|
|
20551
|
+
this.context.stderr.write(`${m}
|
|
20552
|
+
`);
|
|
20553
|
+
};
|
|
20554
|
+
const credential2 = typeof this.miClientId === "string" && this.miClientId.trim().length > 0 ? new ManagedIdentityCredential3({ clientId: this.miClientId.trim() }) : new DefaultAzureCredential19();
|
|
20555
|
+
const ctx = {
|
|
20556
|
+
credential: credential2,
|
|
20557
|
+
subscriptionId: need(this.subscription, "--subscription"),
|
|
20558
|
+
resourceGroup: need(this.resourceGroup, "--resource-group")
|
|
20559
|
+
};
|
|
20560
|
+
const { accountName } = await discoverStampStorage(ctx);
|
|
20561
|
+
const existing = await readStampOutcome(ctx);
|
|
20562
|
+
if (existing.source === "unreadable") {
|
|
20563
|
+
throw new LocalCliError({
|
|
20564
|
+
code: "PLATFORM_STAMP_BUILD_PRIOR_UNREADABLE",
|
|
20565
|
+
message: "Could not read the existing platform stamp; refusing to overwrite it blind.",
|
|
20566
|
+
hint: "The running build is the truth about the CURRENT version, not about whether a previous one existed \u2014 retry once the prior record can be read."
|
|
20567
|
+
});
|
|
20568
|
+
}
|
|
20569
|
+
const previousPlatformVersion = existing.source === "explicit" ? existing.stamp.platformVersion : null;
|
|
20570
|
+
const priorComponents = existing.source === "explicit" ? existing.stamp.components : void 0;
|
|
20571
|
+
const stamp = buildRunningBuildStamp({
|
|
20572
|
+
version: need(this.version, "--version"),
|
|
20573
|
+
gatewayTag: need(this.gatewayTag, "--gateway-tag"),
|
|
20574
|
+
gatewayDigest: this.gatewayDigest ?? "",
|
|
20575
|
+
previousPlatformVersion,
|
|
20576
|
+
cliVersion: CLI_VERSION,
|
|
20577
|
+
nowIso: (/* @__PURE__ */ new Date()).toISOString(),
|
|
20578
|
+
personas: priorComponents?.personas ?? {},
|
|
20579
|
+
infraTreeSha: priorComponents?.infra.treeSha ?? "",
|
|
20580
|
+
...priorComponents?.brainSeeds ? { brainSeeds: priorComponents.brainSeeds } : {}
|
|
20581
|
+
});
|
|
20582
|
+
await writeStamp({ ...ctx, stamp, onProgress });
|
|
20583
|
+
const result = { platformVersion: stamp.platformVersion, previous: previousPlatformVersion, storageAccount: accountName };
|
|
20584
|
+
this.context.stdout.write(
|
|
20585
|
+
mode === "json" ? renderJson(result) + "\n" : `platform stamp: ${result.platformVersion} (previous ${result.previous ?? "none"}, storage ${result.storageAccount})
|
|
20586
|
+
`
|
|
20587
|
+
);
|
|
20588
|
+
return 0;
|
|
20589
|
+
}
|
|
20590
|
+
};
|
|
20591
|
+
|
|
20592
|
+
// src/commands/platform/policy.ts
|
|
20593
|
+
import { Command as Command36, Option as Option33 } from "clipanion";
|
|
20594
|
+
import { DefaultAzureCredential as DefaultAzureCredential20, ManagedIdentityCredential as ManagedIdentityCredential4 } from "@azure/identity";
|
|
20595
|
+
init_errors();
|
|
20596
|
+
|
|
20597
|
+
// src/lib/platform-policy.ts
|
|
20598
|
+
import { TableClient as TableClient5 } from "@azure/data-tables";
|
|
20599
|
+
init_errors();
|
|
20600
|
+
function buildPolicy(mode, nowIso, updatedBy) {
|
|
20601
|
+
if (!isPolicyMode(mode)) {
|
|
20602
|
+
throw new LocalCliError({
|
|
20603
|
+
code: "PLATFORM_POLICY_MODE_INVALID",
|
|
20604
|
+
message: `Unrecognized update mode "${String(mode)}".`,
|
|
20605
|
+
hint: "Use one of: notify-only, auto-critical, auto-all."
|
|
20606
|
+
});
|
|
20607
|
+
}
|
|
20608
|
+
return { schemaVersion: 1, mode, updatedAt: nowIso, updatedBy };
|
|
20609
|
+
}
|
|
20610
|
+
async function writePolicy(opts) {
|
|
20611
|
+
const entity = updatePolicyToEntity(opts.policy);
|
|
20612
|
+
await upsertMetadataEntity({
|
|
20613
|
+
credential: opts.credential,
|
|
20614
|
+
subscriptionId: opts.subscriptionId,
|
|
20615
|
+
resourceGroup: opts.resourceGroup,
|
|
20616
|
+
entity,
|
|
20617
|
+
label: "update policy",
|
|
20618
|
+
errorCode: "PLATFORM_POLICY_NO_ACCESS",
|
|
20619
|
+
retryHint: "The role assignment persists \u2014 retry in a few minutes.",
|
|
20620
|
+
...opts.onProgress ? { onProgress: opts.onProgress } : {}
|
|
20621
|
+
});
|
|
20622
|
+
}
|
|
20623
|
+
async function readPolicy(opts) {
|
|
20624
|
+
const discover = opts.discoverImpl ?? discoverStampStorage;
|
|
20625
|
+
const makeAad = opts.aadClientImpl ?? ((endpoint, credential2) => new TableClient5(endpoint, TABLE, credential2));
|
|
20626
|
+
const makeShared = opts.sharedClientImpl ?? makeSharedKeyClient;
|
|
20627
|
+
const { tableEndpoint, accountResourceId, accountName } = await discover(opts);
|
|
20628
|
+
const aad = makeAad(tableEndpoint, opts.credential);
|
|
20629
|
+
try {
|
|
20630
|
+
const row = await aad.getEntity(UPDATE_POLICY_PK, UPDATE_POLICY_RK);
|
|
20631
|
+
return { source: "explicit", policy: entityToUpdatePolicy(row) };
|
|
20632
|
+
} catch (e) {
|
|
20633
|
+
if (is404(e)) return { source: "absent" };
|
|
20634
|
+
if (!is403(e)) return { source: "unreadable" };
|
|
20635
|
+
}
|
|
20636
|
+
try {
|
|
20637
|
+
const shared = await makeShared({ tableEndpoint, accountResourceId, accountName });
|
|
20638
|
+
if (!shared) return { source: "unreadable" };
|
|
20639
|
+
const row = await shared.getEntity(UPDATE_POLICY_PK, UPDATE_POLICY_RK);
|
|
20640
|
+
return { source: "explicit", policy: entityToUpdatePolicy(row) };
|
|
20641
|
+
} catch {
|
|
20642
|
+
return { source: "unreadable" };
|
|
20643
|
+
}
|
|
20644
|
+
}
|
|
20645
|
+
|
|
20646
|
+
// src/commands/platform/policy.ts
|
|
20647
|
+
var PlatformPolicyCommand = class extends M8tCommand {
|
|
20648
|
+
static paths = [["platform", "policy"]];
|
|
20649
|
+
static usage = Command36.Usage({
|
|
20650
|
+
description: "Show or set how this install handles available platform updates.",
|
|
20651
|
+
details: "Modes: 'notify-only' shows updates but never applies them; 'auto-critical' (the default when unset) applies critical releases without asking; 'auto-all' applies every release. Use 'notify-only' where something else already controls what is deployed.",
|
|
20652
|
+
examples: [["Show the current mode", "m8t platform policy"], ["Never apply automatically", "m8t platform policy --set notify-only"]]
|
|
20653
|
+
});
|
|
20654
|
+
set = Option33.String("--set", { description: "notify-only | auto-critical | auto-all" });
|
|
20655
|
+
subscription = Option33.String("--subscription");
|
|
20656
|
+
resourceGroup = Option33.String("--resource-group");
|
|
20657
|
+
miClientId = Option33.String("--mi-client-id");
|
|
20658
|
+
output = Option33.String("--output");
|
|
20659
|
+
async executeCommand() {
|
|
20660
|
+
const mode = resolveOutputMode(this.output, this.context.stdout);
|
|
20661
|
+
const need = (v, flag) => {
|
|
20662
|
+
if (typeof v !== "string" || v.trim().length === 0) {
|
|
20663
|
+
throw new LocalCliError({ code: "PLATFORM_POLICY_ARG_MISSING", message: `${flag} is required.` });
|
|
20664
|
+
}
|
|
20665
|
+
return v.trim();
|
|
20666
|
+
};
|
|
20667
|
+
const onProgress = (m) => {
|
|
20668
|
+
this.context.stderr.write(`${m}
|
|
20669
|
+
`);
|
|
20670
|
+
};
|
|
20671
|
+
const credential2 = typeof this.miClientId === "string" && this.miClientId.trim().length > 0 ? new ManagedIdentityCredential4({ clientId: this.miClientId.trim() }) : new DefaultAzureCredential20();
|
|
20672
|
+
const ctx = {
|
|
20673
|
+
credential: credential2,
|
|
20674
|
+
subscriptionId: need(this.subscription, "--subscription"),
|
|
20675
|
+
resourceGroup: need(this.resourceGroup, "--resource-group")
|
|
20676
|
+
};
|
|
20677
|
+
if (typeof this.set === "string" && this.set.length > 0) {
|
|
20678
|
+
const policy = buildPolicy(this.set, (/* @__PURE__ */ new Date()).toISOString(), "cli");
|
|
20679
|
+
await writePolicy({ ...ctx, policy, onProgress });
|
|
20680
|
+
const result2 = { mode: policy.mode, updatedAt: policy.updatedAt };
|
|
20681
|
+
this.context.stdout.write(mode === "json" ? renderJson(result2) + "\n" : `update policy: ${policy.mode}
|
|
20682
|
+
`);
|
|
20683
|
+
return 0;
|
|
20684
|
+
}
|
|
20685
|
+
const current = await readPolicy(ctx);
|
|
20686
|
+
if (current.source === "unreadable") {
|
|
20687
|
+
const result2 = { outcome: "unreadable" };
|
|
20688
|
+
this.context.stdout.write(
|
|
20689
|
+
mode === "json" ? renderJson(result2) + "\n" : `update policy: could not be read \u2014 the current setting is unknown; do not assume it is on the default (${DEFAULT_POLICY_MODE}).
|
|
20690
|
+
`
|
|
20691
|
+
);
|
|
20692
|
+
return 0;
|
|
20693
|
+
}
|
|
20694
|
+
const result = current.source === "explicit" ? { mode: current.policy.mode, outcome: "explicit" } : { mode: DEFAULT_POLICY_MODE, outcome: "absent" };
|
|
20695
|
+
this.context.stdout.write(
|
|
20696
|
+
mode === "json" ? renderJson(result) + "\n" : `update policy: ${result.mode}${result.outcome === "absent" ? " (default \u2014 never set)" : ""}
|
|
20697
|
+
`
|
|
20698
|
+
);
|
|
20699
|
+
return 0;
|
|
20700
|
+
}
|
|
20701
|
+
};
|
|
20702
|
+
|
|
20703
|
+
// src/commands/platform/enable-cost-report.ts
|
|
20704
|
+
import { Command as Command37, Option as Option34 } from "clipanion";
|
|
20467
20705
|
|
|
20468
20706
|
// src/lib/wire-gateway-acs.ts
|
|
20469
20707
|
init_rbac();
|
|
@@ -20503,18 +20741,18 @@ async function wireGatewayForAcs(args) {
|
|
|
20503
20741
|
init_errors();
|
|
20504
20742
|
var PlatformEnableCostReportCommand = class extends M8tCommand {
|
|
20505
20743
|
static paths = [["platform", "enable-cost-report"]];
|
|
20506
|
-
static usage =
|
|
20744
|
+
static usage = Command37.Usage({
|
|
20507
20745
|
description: "Wire the deployed gateway to send the bi-weekly cost report via ACS Email.",
|
|
20508
20746
|
details: "Discovers the live gateway Container App, grants its managed identity Contributor at the ACS resource scope (authorising the ACS Email send), and sets M8T_ACS_ENDPOINT / M8T_ACS_SENDER / M8T_ENABLE_COST_REPORTER=1 on the gateway. Idempotent \u2014 safely re-runnable. ACS is created during the executor deploy; pass its endpoint, sender, and resource id (from that deploy or 'az communication list')."
|
|
20509
20747
|
});
|
|
20510
|
-
subscription =
|
|
20511
|
-
resourceGroup =
|
|
20748
|
+
subscription = Option34.String("--subscription");
|
|
20749
|
+
resourceGroup = Option34.String("--resource-group", {
|
|
20512
20750
|
description: "m8t resource group to disambiguate the gateway (multi-deployment subscriptions)."
|
|
20513
20751
|
});
|
|
20514
|
-
acsEndpoint =
|
|
20515
|
-
acsSender =
|
|
20516
|
-
acsResourceId =
|
|
20517
|
-
output =
|
|
20752
|
+
acsEndpoint = Option34.String("--acs-endpoint", { required: true, description: "ACS data-plane endpoint, e.g. https://acs-<name>.communication.azure.com/" });
|
|
20753
|
+
acsSender = Option34.String("--acs-sender", { required: true, description: "Managed-domain sender address, e.g. DoNotReply@<guid>.azurecomm.net" });
|
|
20754
|
+
acsResourceId = Option34.String("--acs-resource-id", { required: true, description: "ARM resource id of the acs-<name> Communication Service \u2014 the role-grant scope." });
|
|
20755
|
+
output = Option34.String("--output");
|
|
20518
20756
|
async executeCommand() {
|
|
20519
20757
|
const mode = resolveOutputMode(
|
|
20520
20758
|
this.output,
|
|
@@ -20588,45 +20826,45 @@ var PlatformEnableCostReportCommand = class extends M8tCommand {
|
|
|
20588
20826
|
};
|
|
20589
20827
|
|
|
20590
20828
|
// src/commands/platform/enable-auto-update.ts
|
|
20591
|
-
import { Command as
|
|
20829
|
+
import { Command as Command38, Option as Option35 } from "clipanion";
|
|
20592
20830
|
import { confirm as confirm6 } from "@inquirer/prompts";
|
|
20593
|
-
import { DefaultAzureCredential as
|
|
20831
|
+
import { DefaultAzureCredential as DefaultAzureCredential21 } from "@azure/identity";
|
|
20594
20832
|
init_errors();
|
|
20595
20833
|
var PlatformEnableAutoUpdateCommand = class extends M8tCommand {
|
|
20596
20834
|
static paths = [["platform", "enable-auto-update"]];
|
|
20597
|
-
static usage =
|
|
20835
|
+
static usage = Command38.Usage({
|
|
20598
20836
|
category: "Platform",
|
|
20599
20837
|
description: "Retrofit the auto-updater (MI + cron job + role assignments) onto an existing install.",
|
|
20600
20838
|
details: "For an install that predates the Platform Update Framework: recovers the deployment's resource-name suffix (from the stamped system/infra-params row, or by verified derivation from the live gateway), recovers the other bicep params from live state (WITHOUT changing the deployed gateway image), and re-runs deploy/main.bicep with provisionUpdater=true \u2014 which provisions the updater managed identity, the cron Container Apps Job, and every role assignment (Owner@RG + Foundry User@account + Storage Table + Storage Blob + AcrPull), all scoped to the resource group. On success, backfills system/infra-params so future converges never have to re-derive the suffix. Idempotent \u2014 safe to re-run."
|
|
20601
20839
|
});
|
|
20602
|
-
subscription =
|
|
20603
|
-
resourceGroup =
|
|
20840
|
+
subscription = Option35.String("--subscription");
|
|
20841
|
+
resourceGroup = Option35.String("--resource-group", {
|
|
20604
20842
|
description: "m8t resource group to disambiguate the gateway (multi-deployment subscriptions)."
|
|
20605
20843
|
});
|
|
20606
|
-
suffix =
|
|
20844
|
+
suffix = Option35.String("--suffix", {
|
|
20607
20845
|
description: "The existing deployment's resource-name suffix. Required when it cannot be recovered from system/infra-params or the live gateway."
|
|
20608
20846
|
});
|
|
20609
|
-
installerImage =
|
|
20847
|
+
installerImage = Option35.String("--installer-image", {
|
|
20610
20848
|
required: true,
|
|
20611
20849
|
description: "Updater CA-Job image ref (the converge engine at the current release). Required \u2014 an empty image would skip provisioning."
|
|
20612
20850
|
});
|
|
20613
|
-
updateCron =
|
|
20851
|
+
updateCron = Option35.String("--update-cron", {
|
|
20614
20852
|
description: "Cron schedule for the updater job (bicep default applies when omitted)."
|
|
20615
20853
|
});
|
|
20616
|
-
channelUrl =
|
|
20854
|
+
channelUrl = Option35.String("--channel-url", {
|
|
20617
20855
|
description: "Release-channel URL the updater job polls (bicep default applies when omitted)."
|
|
20618
20856
|
});
|
|
20619
|
-
location =
|
|
20857
|
+
location = Option35.String("--location", {
|
|
20620
20858
|
description: "Region for the updater identity + job. Defaults to the resource group's existing resources."
|
|
20621
20859
|
});
|
|
20622
|
-
foundryTracing =
|
|
20860
|
+
foundryTracing = Option35.String("--foundry-tracing", {
|
|
20623
20861
|
description: "project | account | skip. Pass the value the install was deployed with \u2014 omitting it lets the bicep default (project) switch tracing on."
|
|
20624
20862
|
});
|
|
20625
|
-
endpoint =
|
|
20863
|
+
endpoint = Option35.String("--endpoint", {
|
|
20626
20864
|
description: "Foundry project endpoint URL. Disambiguates the project in a multi-project subscription."
|
|
20627
20865
|
});
|
|
20628
|
-
yes =
|
|
20629
|
-
output =
|
|
20866
|
+
yes = Option35.Boolean("--yes", false);
|
|
20867
|
+
output = Option35.String("--output");
|
|
20630
20868
|
async executeCommand() {
|
|
20631
20869
|
const mode = resolveOutputMode(
|
|
20632
20870
|
this.output,
|
|
@@ -20645,7 +20883,7 @@ var PlatformEnableAutoUpdateCommand = class extends M8tCommand {
|
|
|
20645
20883
|
resourceGroup: this.resourceGroup
|
|
20646
20884
|
});
|
|
20647
20885
|
const { resourceGroup, name: gatewayName } = parseContainerAppResourceId(gw.containerAppResourceId);
|
|
20648
|
-
const credential2 = new
|
|
20886
|
+
const credential2 = new DefaultAzureCredential21();
|
|
20649
20887
|
const account = await getAzAccount();
|
|
20650
20888
|
const subscriptionId = this.subscription ?? account.subscriptionId;
|
|
20651
20889
|
const explicitSuffix = typeof this.suffix === "string" && this.suffix.length > 0 ? this.suffix : void 0;
|
|
@@ -20763,7 +21001,7 @@ var PlatformEnableAutoUpdateCommand = class extends M8tCommand {
|
|
|
20763
21001
|
};
|
|
20764
21002
|
|
|
20765
21003
|
// src/commands/deploy.ts
|
|
20766
|
-
import { Command as
|
|
21004
|
+
import { Command as Command39, Option as Option36 } from "clipanion";
|
|
20767
21005
|
|
|
20768
21006
|
// src/lib/app-reg.ts
|
|
20769
21007
|
init_errors();
|
|
@@ -21038,6 +21276,51 @@ init_errors();
|
|
|
21038
21276
|
|
|
21039
21277
|
// src/lib/whatif.ts
|
|
21040
21278
|
import * as path27 from "path";
|
|
21279
|
+
|
|
21280
|
+
// src/lib/identifier-patterns.ts
|
|
21281
|
+
var IDENTIFIER_PATTERNS = [
|
|
21282
|
+
/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi,
|
|
21283
|
+
// any GUID (tenant/client/subscription id)
|
|
21284
|
+
/\bsha256:[0-9a-f]{8,}/gi,
|
|
21285
|
+
// image digests
|
|
21286
|
+
/\.azurecr\.io/gi,
|
|
21287
|
+
// registry hosts
|
|
21288
|
+
/\bsubscriptions\/[^\s'"]+/gi,
|
|
21289
|
+
// ARM ids (subscription path)
|
|
21290
|
+
/\bresourceGroups\/[^\s'"]+/gi
|
|
21291
|
+
];
|
|
21292
|
+
function scrubIdentifiers(text) {
|
|
21293
|
+
let out = text;
|
|
21294
|
+
for (const pattern of IDENTIFIER_PATTERNS) out = out.replace(pattern, "[redacted]");
|
|
21295
|
+
return out;
|
|
21296
|
+
}
|
|
21297
|
+
|
|
21298
|
+
// src/lib/whatif-redact.ts
|
|
21299
|
+
function redactForLog(r) {
|
|
21300
|
+
const lines = [];
|
|
21301
|
+
const section = (title, items) => {
|
|
21302
|
+
if (items.length === 0) return;
|
|
21303
|
+
lines.push(`${title} (${items.length.toString()}):`);
|
|
21304
|
+
for (const c of items) {
|
|
21305
|
+
const reason = c.reason ? ` [${c.reason}]` : "";
|
|
21306
|
+
lines.push(` \u2022 ${c.resourceType} ${c.resourceName} ${c.path}${reason}`);
|
|
21307
|
+
}
|
|
21308
|
+
};
|
|
21309
|
+
section("Unexpected", r.unexpected);
|
|
21310
|
+
section("Known pending", r.pending);
|
|
21311
|
+
lines.push(`Noise suppressed: ${r.noise.length.toString()}`);
|
|
21312
|
+
return lines.join("\n");
|
|
21313
|
+
}
|
|
21314
|
+
function redactForReport(r) {
|
|
21315
|
+
return { unexpected: r.unexpected.length, pending: r.pending.length, noise: r.noise.length };
|
|
21316
|
+
}
|
|
21317
|
+
function redactWhatIfFailure(message) {
|
|
21318
|
+
const commandLineFailure = /^'.*?' failed: ([\s\S]*)$/.exec(message);
|
|
21319
|
+
const tail = commandLineFailure ? commandLineFailure[1] : message;
|
|
21320
|
+
return `the underlying comparison command failed (command line withheld): ${scrubIdentifiers(tail)}`;
|
|
21321
|
+
}
|
|
21322
|
+
|
|
21323
|
+
// src/lib/whatif.ts
|
|
21041
21324
|
function deriveResourceType(resourceId) {
|
|
21042
21325
|
if (resourceId.startsWith("[")) return "";
|
|
21043
21326
|
const afterProviders = resourceId.split("/providers/")[1];
|
|
@@ -21069,6 +21352,10 @@ async function runWhatIf(opts) {
|
|
|
21069
21352
|
var fmt = (c) => ` \u2022 ${c.resourceType} ${c.path}: ${JSON.stringify(c.before ?? null)} \u2192 ${JSON.stringify(c.after ?? null)}${c.reason ? ` [${c.reason}]` : ""}`;
|
|
21070
21353
|
function reportWhatIf(r, opts) {
|
|
21071
21354
|
const exitCode = r.unexpected.length === 0 ? 0 : 1;
|
|
21355
|
+
if (opts.redact) {
|
|
21356
|
+
const output = opts.json ? JSON.stringify({ summary: redactForReport(r), exitCode }, null, 2) : redactForLog(r);
|
|
21357
|
+
return { output, exitCode };
|
|
21358
|
+
}
|
|
21072
21359
|
if (opts.json) {
|
|
21073
21360
|
return { output: JSON.stringify({ summary: { noise: r.noise.length, pending: r.pending.length, unexpected: r.unexpected.length }, pending: r.pending, unexpected: r.unexpected, exitCode }, null, 2), exitCode };
|
|
21074
21361
|
}
|
|
@@ -21088,6 +21375,16 @@ function reportWhatIf(r, opts) {
|
|
|
21088
21375
|
}
|
|
21089
21376
|
return { output: lines.join("\n"), exitCode };
|
|
21090
21377
|
}
|
|
21378
|
+
var WHATIF_RUN_FAILED_EXIT_CODE = 3;
|
|
21379
|
+
function reportWhatIfFailure(err, opts) {
|
|
21380
|
+
const raw = err instanceof Error ? err.message : String(err);
|
|
21381
|
+
const message = opts.redact ? redactWhatIfFailure(raw) : raw;
|
|
21382
|
+
const exitCode = WHATIF_RUN_FAILED_EXIT_CODE;
|
|
21383
|
+
if (opts.json) {
|
|
21384
|
+
return { output: JSON.stringify({ ranToCompletion: false, error: message, exitCode }, null, 2), exitCode };
|
|
21385
|
+
}
|
|
21386
|
+
return { output: `comparison did not run to completion \u2014 NOT a drift finding: ${message}`, exitCode };
|
|
21387
|
+
}
|
|
21091
21388
|
|
|
21092
21389
|
// src/lib/whatif-noise.ts
|
|
21093
21390
|
var KNOWN_PENDING = [
|
|
@@ -21100,10 +21397,29 @@ var KNOWN_NOISE = [
|
|
|
21100
21397
|
{ resourceType: "Microsoft.App/containerApps", pathPattern: /(^|\.)runningStatus$/, reason: "RP runtime status" },
|
|
21101
21398
|
{ resourceType: "Microsoft.App/managedEnvironments", pathPattern: /(^|\.)peerAuthentication$/, reason: "RP default" },
|
|
21102
21399
|
{ resourceType: "Microsoft.App/managedEnvironments", pathPattern: /(^|\.)peerTrafficConfiguration$/, reason: "RP default" },
|
|
21400
|
+
// Connections can be account-scoped or project-scoped depending on the deployment's tracing mode.
|
|
21401
|
+
// Rules below match both resource type variants to ensure consistent noise classification.
|
|
21103
21402
|
{ resourceType: "Microsoft.CognitiveServices/accounts/connections", pathPattern: /(^|\.)credentials$/, reason: "write-only credential \u2014 always re-shows" },
|
|
21104
21403
|
{ resourceType: "Microsoft.CognitiveServices/accounts/connections", pathPattern: /(^|\.)(group|isDefault|peRequirement|peStatus|useWorkspaceManagedIdentity)$/, reason: "RP connection metadata" },
|
|
21404
|
+
{ resourceType: "Microsoft.CognitiveServices/accounts/projects/connections", pathPattern: /(^|\.)credentials$/, reason: "write-only credential \u2014 always re-shows" },
|
|
21405
|
+
{ resourceType: "Microsoft.CognitiveServices/accounts/projects/connections", pathPattern: /(^|\.)(group|isDefault|peRequirement|peStatus|useWorkspaceManagedIdentity)$/, reason: "RP connection metadata" },
|
|
21105
21406
|
{ resourceType: "Microsoft.Insights/components", pathPattern: /(^|\.)(Flow_Type|Request_Source)$/, reason: "RP-stamped" },
|
|
21106
|
-
{ resourceType: "Microsoft.ServiceBus/namespaces/queues", pathPattern: /(^|\.)(autoDeleteOnIdle|duplicateDetectionHistoryTimeWindow|maxMessageSizeInKilobytes|maxSizeInMegabytes)$/, reason: "RP default the bicep doesn't declare" }
|
|
21407
|
+
{ resourceType: "Microsoft.ServiceBus/namespaces/queues", pathPattern: /(^|\.)(autoDeleteOnIdle|duplicateDetectionHistoryTimeWindow|maxMessageSizeInKilobytes|maxSizeInMegabytes)$/, reason: "RP default the bicep doesn't declare" },
|
|
21408
|
+
// The template regenerates the relay's shared secret on every deployment unless the
|
|
21409
|
+
// current value is passed through, so a comparison that omits it reports a fresh
|
|
21410
|
+
// difference every run. Ownership of that parameter sits with the voice work, not
|
|
21411
|
+
// here — this comparison neither reads it nor asserts on it.
|
|
21412
|
+
//
|
|
21413
|
+
// The indexed rule is deliberately end-anchored to `.value` ONLY: an unanchored
|
|
21414
|
+
// pattern would also swallow `configuration.secrets[N].name`,
|
|
21415
|
+
// `.keyVaultUrl`/vault reference, and `.identity` — a repointed vault reference or a
|
|
21416
|
+
// swapped backing identity on ANY container app would then be invisible to the very
|
|
21417
|
+
// check meant to catch it, not just the regenerated secret's own value.
|
|
21418
|
+
//
|
|
21419
|
+
// REMOVE THESE TWO RULES when the deployment path stops regenerating the value.
|
|
21420
|
+
// Their presence is the marker that it still does.
|
|
21421
|
+
{ resourceType: "Microsoft.App/containerApps", pathPattern: /(^|\.)configuration\.secrets$/, reason: "shared relay secret is regenerated on every deployment \u2014 owned elsewhere" },
|
|
21422
|
+
{ resourceType: "Microsoft.App/containerApps", pathPattern: /(^|\.)configuration\.secrets\[\d+\]\.value$/, reason: "shared relay secret is regenerated on every deployment \u2014 owned elsewhere" }
|
|
21107
21423
|
];
|
|
21108
21424
|
var shortName = (resourceId) => resourceId.startsWith("[") ? "(role assignment)" : resourceId.split("/").pop() ?? resourceId;
|
|
21109
21425
|
function isArmExpression(v) {
|
|
@@ -21165,40 +21481,52 @@ function classifyWhatIf(changes) {
|
|
|
21165
21481
|
var DEFAULT_IMAGE_REF = "ghcr.io/m8t-labs/m8t:latest";
|
|
21166
21482
|
var DeployCommand = class extends M8tCommand {
|
|
21167
21483
|
static paths = [["deploy"]];
|
|
21168
|
-
static usage =
|
|
21484
|
+
static usage = Command39.Usage({
|
|
21169
21485
|
description: "Deploy (or update) the m8t gateway/webapp stack via Bicep.",
|
|
21170
21486
|
details: "Ensures the Entra app reg (or pass --client-id to reuse an existing one \u2014 required if you can't create app regs), writes ~/.m8t/config.yaml, ensures the resource group, and runs deploy/main.bicep. The repo is located via ~/.m8t/repo-root."
|
|
21171
21487
|
});
|
|
21172
|
-
subscription =
|
|
21173
|
-
resourceGroup =
|
|
21174
|
-
location =
|
|
21175
|
-
suffix =
|
|
21176
|
-
imageRef =
|
|
21177
|
-
acrPullIdentity =
|
|
21178
|
-
acrResourceId =
|
|
21179
|
-
foundryEndpoint =
|
|
21180
|
-
foundryResourceId =
|
|
21181
|
-
foundryTracing =
|
|
21488
|
+
subscription = Option36.String("--subscription");
|
|
21489
|
+
resourceGroup = Option36.String("--resource-group", "rg-m8t-stack");
|
|
21490
|
+
location = Option36.String("--location", "eastus");
|
|
21491
|
+
suffix = Option36.String("--suffix", "");
|
|
21492
|
+
imageRef = Option36.String("--image-ref", DEFAULT_IMAGE_REF);
|
|
21493
|
+
acrPullIdentity = Option36.String("--acrpull-identity");
|
|
21494
|
+
acrResourceId = Option36.String("--acr-resource-id");
|
|
21495
|
+
foundryEndpoint = Option36.String("--foundry-endpoint");
|
|
21496
|
+
foundryResourceId = Option36.String("--foundry-resource-id");
|
|
21497
|
+
foundryTracing = Option36.String("--foundry-tracing");
|
|
21182
21498
|
// project | account | skip (bicep default: project)
|
|
21183
|
-
clientId =
|
|
21184
|
-
whatIf =
|
|
21185
|
-
|
|
21499
|
+
clientId = Option36.String("--client-id");
|
|
21500
|
+
whatIf = Option36.Boolean("--what-if", false);
|
|
21501
|
+
// Only meaningful with --what-if. Routes the comparison through the
|
|
21502
|
+
// value-free renderers (see ./lib/whatif-redact.js) instead of the default
|
|
21503
|
+
// before/after renderer. Defaults false so a local, interactive run keeps
|
|
21504
|
+
// showing values — that is the whole diagnostic point of --what-if.
|
|
21505
|
+
// Automation that forwards this output anywhere non-private (a CI log, an
|
|
21506
|
+
// issue) MUST pass --redact.
|
|
21507
|
+
redact = Option36.Boolean("--redact", false);
|
|
21508
|
+
output = Option36.String("--output");
|
|
21509
|
+
// Subscription-scoped role assignments. Omitted ⇒ the template default (true).
|
|
21510
|
+
// Pass false when deploying as a principal scoped to the resource group only:
|
|
21511
|
+
// it cannot deploy at subscription scope, and those assignments persist
|
|
21512
|
+
// idempotently from the initial deployment anyway.
|
|
21513
|
+
assignSubscriptionRoles = Option36.String("--assign-subscription-roles");
|
|
21186
21514
|
// Referee — all optional, undefined by default ⇒ the bicep defaults
|
|
21187
21515
|
// apply (dormant: gatewayCpu=0.25, gatewayMemory=0.5Gi, every referee/exam var
|
|
21188
21516
|
// empty). Only pass these when explicitly enabling the referee exam stack.
|
|
21189
|
-
gatewayCpu =
|
|
21190
|
-
gatewayMemory =
|
|
21191
|
-
refereeEnabled =
|
|
21192
|
-
refereeBrainRepos =
|
|
21193
|
-
refereeFeedRepo =
|
|
21194
|
-
refereeInstallationId =
|
|
21195
|
-
refereeWebhookHmacKvUri =
|
|
21196
|
-
examKvUri =
|
|
21197
|
-
examLaWorkspaceId =
|
|
21198
|
-
brainEvalDeployment =
|
|
21199
|
-
brainAppLogin =
|
|
21200
|
-
refereeCheckpointDir =
|
|
21201
|
-
examApiBase =
|
|
21517
|
+
gatewayCpu = Option36.String("--gateway-cpu");
|
|
21518
|
+
gatewayMemory = Option36.String("--gateway-memory");
|
|
21519
|
+
refereeEnabled = Option36.String("--referee-enabled");
|
|
21520
|
+
refereeBrainRepos = Option36.String("--referee-brain-repos");
|
|
21521
|
+
refereeFeedRepo = Option36.String("--referee-feed-repo");
|
|
21522
|
+
refereeInstallationId = Option36.String("--referee-installation-id");
|
|
21523
|
+
refereeWebhookHmacKvUri = Option36.String("--referee-webhook-hmac-kv-uri");
|
|
21524
|
+
examKvUri = Option36.String("--exam-kv-uri");
|
|
21525
|
+
examLaWorkspaceId = Option36.String("--exam-la-workspace-id");
|
|
21526
|
+
brainEvalDeployment = Option36.String("--brain-eval-deployment");
|
|
21527
|
+
brainAppLogin = Option36.String("--brain-app-login");
|
|
21528
|
+
refereeCheckpointDir = Option36.String("--referee-checkpoint-dir");
|
|
21529
|
+
examApiBase = Option36.String("--exam-api-base");
|
|
21202
21530
|
async executeCommand() {
|
|
21203
21531
|
const mode = resolveOutputMode(
|
|
21204
21532
|
this.output,
|
|
@@ -21207,6 +21535,69 @@ var DeployCommand = class extends M8tCommand {
|
|
|
21207
21535
|
const log = (msg) => {
|
|
21208
21536
|
if (mode !== "json") this.context.stdout.write(msg + "\n");
|
|
21209
21537
|
};
|
|
21538
|
+
if (this.whatIf) {
|
|
21539
|
+
try {
|
|
21540
|
+
if (this.subscription) {
|
|
21541
|
+
await runAz(["account", "set", "--subscription", this.subscription]);
|
|
21542
|
+
}
|
|
21543
|
+
const account2 = await getAzAccount();
|
|
21544
|
+
const foundryEndpoint2 = this.foundryEndpoint ?? (await readFoundryConfig())?.projectEndpoint;
|
|
21545
|
+
if (!foundryEndpoint2) {
|
|
21546
|
+
throw new LocalCliError({
|
|
21547
|
+
code: "DEPLOY_NO_FOUNDRY_ENDPOINT",
|
|
21548
|
+
message: "No Foundry endpoint provided.",
|
|
21549
|
+
hint: "Pass --foundry-endpoint <url> or set projectEndpoint in ~/.m8t/config.yaml (m8t config set / m8t switch)."
|
|
21550
|
+
});
|
|
21551
|
+
}
|
|
21552
|
+
const clientId = this.clientId ?? (await readFoundryConfig())?.clientId;
|
|
21553
|
+
if (!clientId) {
|
|
21554
|
+
throw new LocalCliError({
|
|
21555
|
+
code: "DEPLOY_WHATIF_NO_CLIENT",
|
|
21556
|
+
message: "--what-if needs a client id but none was provided or configured.",
|
|
21557
|
+
hint: "Pass --client-id <appId>, or run from a host with ~/.m8t/config.yaml."
|
|
21558
|
+
});
|
|
21559
|
+
}
|
|
21560
|
+
const foundryResourceId2 = await resolveFoundryResourceId(foundryEndpoint2, this.foundryResourceId);
|
|
21561
|
+
const repoRoot2 = await resolveRepoRoot2();
|
|
21562
|
+
const acrPullIdentityResourceId2 = resolveAcrPullIdentity({ explicit: this.acrPullIdentity });
|
|
21563
|
+
const acrResourceId2 = acrPullIdentityResourceId2 ? "" : await resolveAcrResourceId({ imageRef: this.imageRef, explicit: this.acrResourceId });
|
|
21564
|
+
const params2 = buildBicepParams({
|
|
21565
|
+
location: this.location,
|
|
21566
|
+
suffix: this.suffix,
|
|
21567
|
+
imageRef: this.imageRef,
|
|
21568
|
+
tenantId: account2.tenantId,
|
|
21569
|
+
clientId,
|
|
21570
|
+
foundryResourceId: foundryResourceId2,
|
|
21571
|
+
foundryProjectEndpoint: foundryEndpoint2,
|
|
21572
|
+
acrPullIdentityResourceId: acrPullIdentityResourceId2,
|
|
21573
|
+
acrResourceId: acrResourceId2,
|
|
21574
|
+
foundryTracingMode: parseFoundryTracingMode(this.foundryTracing),
|
|
21575
|
+
gatewayCpu: this.gatewayCpu,
|
|
21576
|
+
gatewayMemory: this.gatewayMemory,
|
|
21577
|
+
refereeEnabled: this.refereeEnabled,
|
|
21578
|
+
refereeBrainRepos: this.refereeBrainRepos,
|
|
21579
|
+
refereeFeedRepo: this.refereeFeedRepo,
|
|
21580
|
+
refereeInstallationId: this.refereeInstallationId,
|
|
21581
|
+
refereeWebhookHmacKvUri: this.refereeWebhookHmacKvUri,
|
|
21582
|
+
examKvUri: this.examKvUri,
|
|
21583
|
+
examLaWorkspaceId: this.examLaWorkspaceId,
|
|
21584
|
+
brainEvalDeployment: this.brainEvalDeployment,
|
|
21585
|
+
brainAppLogin: this.brainAppLogin,
|
|
21586
|
+
refereeCheckpointDir: this.refereeCheckpointDir,
|
|
21587
|
+
examApiBase: this.examApiBase,
|
|
21588
|
+
...parseAssignSubscriptionRoles(this.assignSubscriptionRoles) === void 0 ? {} : { assignSubscriptionRoles: parseAssignSubscriptionRoles(this.assignSubscriptionRoles) }
|
|
21589
|
+
});
|
|
21590
|
+
const changes = await runWhatIf({ resourceGroup: this.resourceGroup, repoRoot: repoRoot2, params: params2 });
|
|
21591
|
+
const classified = classifyWhatIf(changes);
|
|
21592
|
+
const { output, exitCode } = reportWhatIf(classified, { json: mode === "json", redact: this.redact });
|
|
21593
|
+
this.context.stdout.write(output + "\n");
|
|
21594
|
+
return exitCode;
|
|
21595
|
+
} catch (e) {
|
|
21596
|
+
const { output, exitCode } = reportWhatIfFailure(e, { json: mode === "json", redact: this.redact });
|
|
21597
|
+
this.context.stdout.write(output + "\n");
|
|
21598
|
+
return exitCode;
|
|
21599
|
+
}
|
|
21600
|
+
}
|
|
21210
21601
|
if (this.subscription) {
|
|
21211
21602
|
await runAz(["account", "set", "--subscription", this.subscription]);
|
|
21212
21603
|
}
|
|
@@ -21219,50 +21610,6 @@ var DeployCommand = class extends M8tCommand {
|
|
|
21219
21610
|
hint: "Pass --foundry-endpoint <url> or set projectEndpoint in ~/.m8t/config.yaml (m8t config set / m8t switch)."
|
|
21220
21611
|
});
|
|
21221
21612
|
}
|
|
21222
|
-
if (this.whatIf) {
|
|
21223
|
-
const clientId = this.clientId ?? (await readFoundryConfig())?.clientId;
|
|
21224
|
-
if (!clientId) {
|
|
21225
|
-
throw new LocalCliError({
|
|
21226
|
-
code: "DEPLOY_WHATIF_NO_CLIENT",
|
|
21227
|
-
message: "--what-if needs a client id but none was provided or configured.",
|
|
21228
|
-
hint: "Pass --client-id <appId>, or run from a host with ~/.m8t/config.yaml."
|
|
21229
|
-
});
|
|
21230
|
-
}
|
|
21231
|
-
const foundryResourceId2 = await resolveFoundryResourceId(foundryEndpoint, this.foundryResourceId);
|
|
21232
|
-
const repoRoot2 = await resolveRepoRoot2();
|
|
21233
|
-
const acrPullIdentityResourceId2 = resolveAcrPullIdentity({ explicit: this.acrPullIdentity });
|
|
21234
|
-
const acrResourceId2 = acrPullIdentityResourceId2 ? "" : await resolveAcrResourceId({ imageRef: this.imageRef, explicit: this.acrResourceId });
|
|
21235
|
-
const params2 = buildBicepParams({
|
|
21236
|
-
location: this.location,
|
|
21237
|
-
suffix: this.suffix,
|
|
21238
|
-
imageRef: this.imageRef,
|
|
21239
|
-
tenantId: account.tenantId,
|
|
21240
|
-
clientId,
|
|
21241
|
-
foundryResourceId: foundryResourceId2,
|
|
21242
|
-
foundryProjectEndpoint: foundryEndpoint,
|
|
21243
|
-
acrPullIdentityResourceId: acrPullIdentityResourceId2,
|
|
21244
|
-
acrResourceId: acrResourceId2,
|
|
21245
|
-
foundryTracingMode: parseFoundryTracingMode(this.foundryTracing),
|
|
21246
|
-
gatewayCpu: this.gatewayCpu,
|
|
21247
|
-
gatewayMemory: this.gatewayMemory,
|
|
21248
|
-
refereeEnabled: this.refereeEnabled,
|
|
21249
|
-
refereeBrainRepos: this.refereeBrainRepos,
|
|
21250
|
-
refereeFeedRepo: this.refereeFeedRepo,
|
|
21251
|
-
refereeInstallationId: this.refereeInstallationId,
|
|
21252
|
-
refereeWebhookHmacKvUri: this.refereeWebhookHmacKvUri,
|
|
21253
|
-
examKvUri: this.examKvUri,
|
|
21254
|
-
examLaWorkspaceId: this.examLaWorkspaceId,
|
|
21255
|
-
brainEvalDeployment: this.brainEvalDeployment,
|
|
21256
|
-
brainAppLogin: this.brainAppLogin,
|
|
21257
|
-
refereeCheckpointDir: this.refereeCheckpointDir,
|
|
21258
|
-
examApiBase: this.examApiBase
|
|
21259
|
-
});
|
|
21260
|
-
const changes = await runWhatIf({ resourceGroup: this.resourceGroup, repoRoot: repoRoot2, params: params2 });
|
|
21261
|
-
const classified = classifyWhatIf(changes);
|
|
21262
|
-
const { output, exitCode } = reportWhatIf(classified, { json: mode === "json" });
|
|
21263
|
-
this.context.stdout.write(output + "\n");
|
|
21264
|
-
return exitCode;
|
|
21265
|
-
}
|
|
21266
21613
|
log(this.clientId ? `using existing app reg ${this.clientId}` : "ensuring Entra app reg\u2026");
|
|
21267
21614
|
const app = await ensureAppReg({ tenantId: account.tenantId, clientId: this.clientId });
|
|
21268
21615
|
if (app.appObjectId === null && this.clientId) {
|
|
@@ -21303,7 +21650,8 @@ var DeployCommand = class extends M8tCommand {
|
|
|
21303
21650
|
brainEvalDeployment: this.brainEvalDeployment,
|
|
21304
21651
|
brainAppLogin: this.brainAppLogin,
|
|
21305
21652
|
refereeCheckpointDir: this.refereeCheckpointDir,
|
|
21306
|
-
examApiBase: this.examApiBase
|
|
21653
|
+
examApiBase: this.examApiBase,
|
|
21654
|
+
...parseAssignSubscriptionRoles(this.assignSubscriptionRoles) === void 0 ? {} : { assignSubscriptionRoles: parseAssignSubscriptionRoles(this.assignSubscriptionRoles) }
|
|
21307
21655
|
});
|
|
21308
21656
|
log("running Bicep deployment (~3-5 min)\u2026");
|
|
21309
21657
|
const outputs = await runBicepDeployment({
|
|
@@ -21338,7 +21686,7 @@ var DeployCommand = class extends M8tCommand {
|
|
|
21338
21686
|
|
|
21339
21687
|
// src/commands/eval/skill.ts
|
|
21340
21688
|
import { spawnSync as spawnSync4 } from "child_process";
|
|
21341
|
-
import { Command as
|
|
21689
|
+
import { Command as Command40, Option as Option37 } from "clipanion";
|
|
21342
21690
|
init_errors();
|
|
21343
21691
|
var DECISIONS = /* @__PURE__ */ new Set(["promote", "reject", "needs_review"]);
|
|
21344
21692
|
var JUDGE_STATUSES = /* @__PURE__ */ new Set(["ok", "skipped", "unavailable"]);
|
|
@@ -21363,14 +21711,14 @@ function parseVerdict(stdout) {
|
|
|
21363
21711
|
}
|
|
21364
21712
|
var EvalSkillCommand = class extends M8tCommand {
|
|
21365
21713
|
static paths = [["eval", "skill"]];
|
|
21366
|
-
static usage =
|
|
21714
|
+
static usage = Command40.Usage({
|
|
21367
21715
|
description: "Vet one inbox skill candidate: promote / reject / needs_review. Shells out to the Python `brain-eval` core (override its path with $BRAIN_EVAL_BIN)."
|
|
21368
21716
|
});
|
|
21369
|
-
candidate =
|
|
21370
|
-
skillsDir =
|
|
21371
|
-
noJudge =
|
|
21372
|
-
deployment =
|
|
21373
|
-
output =
|
|
21717
|
+
candidate = Option37.String();
|
|
21718
|
+
skillsDir = Option37.String("--skills-dir");
|
|
21719
|
+
noJudge = Option37.Boolean("--no-judge", false);
|
|
21720
|
+
deployment = Option37.String("--deployment");
|
|
21721
|
+
output = Option37.String("--output");
|
|
21374
21722
|
executeCommand() {
|
|
21375
21723
|
return Promise.resolve(this._runCommand());
|
|
21376
21724
|
}
|
|
@@ -21429,7 +21777,7 @@ var EvalSkillCommand = class extends M8tCommand {
|
|
|
21429
21777
|
import { spawnSync as spawnSync5 } from "child_process";
|
|
21430
21778
|
import { writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, readFileSync as readFileSync18, existsSync as existsSync15, readdirSync as readdirSync2 } from "fs";
|
|
21431
21779
|
import { join as join27 } from "path";
|
|
21432
|
-
import { Command as
|
|
21780
|
+
import { Command as Command41, Option as Option38 } from "clipanion";
|
|
21433
21781
|
init_errors();
|
|
21434
21782
|
init_esm();
|
|
21435
21783
|
function parseArmToken(tok, opts) {
|
|
@@ -21659,24 +22007,24 @@ function buildPlan(args) {
|
|
|
21659
22007
|
}
|
|
21660
22008
|
var EvalExamCommand = class extends M8tCommand {
|
|
21661
22009
|
static paths = [["eval", "exam"]];
|
|
21662
|
-
static usage =
|
|
22010
|
+
static usage = Command41.Usage({
|
|
21663
22011
|
description: "Run a brain exam: impact A/B + dream-delta. Resolves the plan, then shells out to the Python `brain-exam` orchestrator (override its path with $BRAIN_EXAM_BIN). Renders an ExamVerdict: three-valued verdict + power note + per-task flips."
|
|
21664
22012
|
});
|
|
21665
|
-
worker =
|
|
21666
|
-
arms =
|
|
21667
|
-
taskSet =
|
|
21668
|
-
examType =
|
|
21669
|
-
skill =
|
|
21670
|
-
reps =
|
|
21671
|
-
probes =
|
|
21672
|
-
pool =
|
|
21673
|
-
out =
|
|
21674
|
-
dryRun =
|
|
21675
|
-
keepArms =
|
|
21676
|
-
allowStub =
|
|
21677
|
-
deployment =
|
|
21678
|
-
output =
|
|
21679
|
-
observeWaitS =
|
|
22013
|
+
worker = Option38.String();
|
|
22014
|
+
arms = Option38.String("--arms");
|
|
22015
|
+
taskSet = Option38.String("--task-set");
|
|
22016
|
+
examType = Option38.String("--exam-type");
|
|
22017
|
+
skill = Option38.String("--skill");
|
|
22018
|
+
reps = Option38.String("-n,--reps");
|
|
22019
|
+
probes = Option38.String("--probes");
|
|
22020
|
+
pool = Option38.String("--pool");
|
|
22021
|
+
out = Option38.String("--out");
|
|
22022
|
+
dryRun = Option38.Boolean("--dry-run", false);
|
|
22023
|
+
keepArms = Option38.Boolean("--keep-arms", false);
|
|
22024
|
+
allowStub = Option38.Boolean("--allow-stub", false);
|
|
22025
|
+
deployment = Option38.String("--deployment");
|
|
22026
|
+
output = Option38.String("--output");
|
|
22027
|
+
observeWaitS = Option38.String("--observe-wait-s");
|
|
21680
22028
|
async executeCommand() {
|
|
21681
22029
|
await Promise.resolve();
|
|
21682
22030
|
const worker = typeof this.worker === "string" ? this.worker : void 0;
|
|
@@ -21791,10 +22139,10 @@ var EvalExamCommand = class extends M8tCommand {
|
|
|
21791
22139
|
};
|
|
21792
22140
|
|
|
21793
22141
|
// src/commands/version.ts
|
|
21794
|
-
import { Command as
|
|
22142
|
+
import { Command as Command42, Option as Option39 } from "clipanion";
|
|
21795
22143
|
var VersionCommand = class extends M8tCommand {
|
|
21796
22144
|
static paths = [["version"], ["--version"], ["-v"]];
|
|
21797
|
-
static usage =
|
|
22145
|
+
static usage = Command42.Usage({
|
|
21798
22146
|
description: "Print the CLI version.",
|
|
21799
22147
|
details: "Prints the m8t CLI version. With --verbose, also prints Node version and platform.",
|
|
21800
22148
|
examples: [
|
|
@@ -21802,8 +22150,8 @@ var VersionCommand = class extends M8tCommand {
|
|
|
21802
22150
|
["Print as JSON", "$0 version --output json"]
|
|
21803
22151
|
]
|
|
21804
22152
|
});
|
|
21805
|
-
output =
|
|
21806
|
-
verbose =
|
|
22153
|
+
output = Option39.String("--output", { description: "pretty | json | auto (default)" });
|
|
22154
|
+
verbose = Option39.Boolean("--verbose", false);
|
|
21807
22155
|
executeCommand() {
|
|
21808
22156
|
const mode = resolveOutputMode(
|
|
21809
22157
|
this.output ?? "auto",
|
|
@@ -21834,18 +22182,18 @@ var VersionCommand = class extends M8tCommand {
|
|
|
21834
22182
|
};
|
|
21835
22183
|
|
|
21836
22184
|
// src/commands/whoami.ts
|
|
21837
|
-
import { Command as
|
|
22185
|
+
import { Command as Command43, Option as Option40 } from "clipanion";
|
|
21838
22186
|
var WhoamiCommand = class extends M8tCommand {
|
|
21839
22187
|
static paths = [["whoami"]];
|
|
21840
|
-
static usage =
|
|
22188
|
+
static usage = Command43.Usage({
|
|
21841
22189
|
description: "Show your identity + the gateway you'll talk to. Probes the backend."
|
|
21842
22190
|
});
|
|
21843
|
-
output =
|
|
21844
|
-
verbose =
|
|
21845
|
-
subscription =
|
|
22191
|
+
output = Option40.String("--output");
|
|
22192
|
+
verbose = Option40.Boolean("--verbose", false);
|
|
22193
|
+
subscription = Option40.String("--subscription", {
|
|
21846
22194
|
description: "Azure subscription ID to discover gateway in (defaults to active az subscription)."
|
|
21847
22195
|
});
|
|
21848
|
-
resourceGroup =
|
|
22196
|
+
resourceGroup = Option40.String("--resource-group", {
|
|
21849
22197
|
description: "m8t resource group to disambiguate the gateway (multi-deployment subscriptions)."
|
|
21850
22198
|
});
|
|
21851
22199
|
async executeCommand() {
|
|
@@ -21910,7 +22258,7 @@ var WhoamiCommand = class extends M8tCommand {
|
|
|
21910
22258
|
};
|
|
21911
22259
|
|
|
21912
22260
|
// src/commands/status.ts
|
|
21913
|
-
import { Command as
|
|
22261
|
+
import { Command as Command44, Option as Option41 } from "clipanion";
|
|
21914
22262
|
|
|
21915
22263
|
// src/lib/azd.ts
|
|
21916
22264
|
init_errors();
|
|
@@ -21975,10 +22323,10 @@ async function resolveLocalContext() {
|
|
|
21975
22323
|
// src/commands/status.ts
|
|
21976
22324
|
var StatusCommand = class extends M8tCommand {
|
|
21977
22325
|
static paths = [["status"]];
|
|
21978
|
-
static usage =
|
|
22326
|
+
static usage = Command44.Usage({
|
|
21979
22327
|
description: "Show the local m8t context: identity, config.yaml, gateway cache, azd mode."
|
|
21980
22328
|
});
|
|
21981
|
-
output =
|
|
22329
|
+
output = Option41.String("--output");
|
|
21982
22330
|
async executeCommand() {
|
|
21983
22331
|
const mode = resolveOutputMode(
|
|
21984
22332
|
this.output,
|
|
@@ -22016,8 +22364,8 @@ var StatusCommand = class extends M8tCommand {
|
|
|
22016
22364
|
};
|
|
22017
22365
|
|
|
22018
22366
|
// src/commands/doctor.ts
|
|
22019
|
-
import { Command as
|
|
22020
|
-
import { DefaultAzureCredential as
|
|
22367
|
+
import { Command as Command45, Option as Option42 } from "clipanion";
|
|
22368
|
+
import { DefaultAzureCredential as DefaultAzureCredential22 } from "@azure/identity";
|
|
22021
22369
|
import * as fs26 from "fs";
|
|
22022
22370
|
import * as os11 from "os";
|
|
22023
22371
|
import * as path28 from "path";
|
|
@@ -22292,12 +22640,12 @@ function probeLegacyStateDir() {
|
|
|
22292
22640
|
}
|
|
22293
22641
|
var DoctorCommand = class extends M8tCommand {
|
|
22294
22642
|
static paths = [["doctor"]];
|
|
22295
|
-
static usage =
|
|
22643
|
+
static usage = Command45.Usage({
|
|
22296
22644
|
description: "Diagnose the local m8t setup: az login, config.yaml, gateway, Foundry data-plane."
|
|
22297
22645
|
});
|
|
22298
|
-
output =
|
|
22299
|
-
agent =
|
|
22300
|
-
resourceGroup =
|
|
22646
|
+
output = Option42.String("--output");
|
|
22647
|
+
agent = Option42.String("--agent");
|
|
22648
|
+
resourceGroup = Option42.String("--resource-group", {
|
|
22301
22649
|
description: "m8t resource group to disambiguate the gateway (multi-deployment subscriptions)."
|
|
22302
22650
|
});
|
|
22303
22651
|
async executeCommand() {
|
|
@@ -22371,7 +22719,7 @@ var DoctorCommand = class extends M8tCommand {
|
|
|
22371
22719
|
if (typeof this.agent === "string" && this.agent) {
|
|
22372
22720
|
checking(`delivery grant for ${this.agent}`);
|
|
22373
22721
|
try {
|
|
22374
|
-
const credential2 = new
|
|
22722
|
+
const credential2 = new DefaultAzureCredential22();
|
|
22375
22723
|
const cur = await getAgentVersion({
|
|
22376
22724
|
credential: credential2,
|
|
22377
22725
|
projectEndpoint: foundry.projectEndpoint,
|
|
@@ -22414,7 +22762,7 @@ var DoctorCommand = class extends M8tCommand {
|
|
|
22414
22762
|
};
|
|
22415
22763
|
|
|
22416
22764
|
// src/commands/switch.ts
|
|
22417
|
-
import { Command as
|
|
22765
|
+
import { Command as Command46, Option as Option43 } from "clipanion";
|
|
22418
22766
|
|
|
22419
22767
|
// src/lib/profiles.ts
|
|
22420
22768
|
import * as fs27 from "fs/promises";
|
|
@@ -22554,14 +22902,14 @@ async function profileSwitch(name, asName) {
|
|
|
22554
22902
|
init_errors();
|
|
22555
22903
|
var SwitchCommand = class extends M8tCommand {
|
|
22556
22904
|
static paths = [["switch"]];
|
|
22557
|
-
static usage =
|
|
22905
|
+
static usage = Command46.Usage({
|
|
22558
22906
|
description: "Re-point local config at another deployment: --subscription <id|name> (discovery) or <profile>."
|
|
22559
22907
|
});
|
|
22560
|
-
profile =
|
|
22561
|
-
subscription =
|
|
22562
|
-
list =
|
|
22563
|
-
as =
|
|
22564
|
-
output =
|
|
22908
|
+
profile = Option43.String({ required: false });
|
|
22909
|
+
subscription = Option43.String("--subscription");
|
|
22910
|
+
list = Option43.Boolean("--list", false);
|
|
22911
|
+
as = Option43.String("--as");
|
|
22912
|
+
output = Option43.String("--output");
|
|
22565
22913
|
async executeCommand() {
|
|
22566
22914
|
const mode = resolveOutputMode(
|
|
22567
22915
|
this.output,
|
|
@@ -22618,7 +22966,7 @@ var SwitchCommand = class extends M8tCommand {
|
|
|
22618
22966
|
|
|
22619
22967
|
// src/commands/open.ts
|
|
22620
22968
|
import { spawn as spawn5 } from "child_process";
|
|
22621
|
-
import { Command as
|
|
22969
|
+
import { Command as Command47, Option as Option44 } from "clipanion";
|
|
22622
22970
|
|
|
22623
22971
|
// src/lib/open-targets.ts
|
|
22624
22972
|
init_errors();
|
|
@@ -22664,14 +23012,14 @@ function openUrl(url) {
|
|
|
22664
23012
|
}
|
|
22665
23013
|
var OpenCommand = class extends M8tCommand {
|
|
22666
23014
|
static paths = [["open"]];
|
|
22667
|
-
static usage =
|
|
23015
|
+
static usage = Command47.Usage({
|
|
22668
23016
|
description: "Open the deployed webapp (default), the Foundry portal, or the resource group.",
|
|
22669
23017
|
details: "Targets: webapp (deployed app, default) | foundry (ai.azure.com) | portal (resource group in the Azure portal). Pass --print to emit the URL instead of launching a browser (also the default when stdout isn't a TTY)."
|
|
22670
23018
|
});
|
|
22671
|
-
target =
|
|
22672
|
-
print =
|
|
22673
|
-
output =
|
|
22674
|
-
resourceGroup =
|
|
23019
|
+
target = Option44.String({ required: false });
|
|
23020
|
+
print = Option44.Boolean("--print", false);
|
|
23021
|
+
output = Option44.String("--output");
|
|
23022
|
+
resourceGroup = Option44.String("--resource-group", {
|
|
22675
23023
|
description: "m8t resource group to disambiguate the gateway (multi-deployment subscriptions)."
|
|
22676
23024
|
});
|
|
22677
23025
|
async executeCommand() {
|
|
@@ -22715,9 +23063,9 @@ var OpenCommand = class extends M8tCommand {
|
|
|
22715
23063
|
};
|
|
22716
23064
|
|
|
22717
23065
|
// src/commands/dream/run.ts
|
|
22718
|
-
import { Command as
|
|
23066
|
+
import { Command as Command48, Option as Option45 } from "clipanion";
|
|
22719
23067
|
import { AzureCliCredential } from "@azure/identity";
|
|
22720
|
-
import { TableClient as
|
|
23068
|
+
import { TableClient as TableClient7 } from "@azure/data-tables";
|
|
22721
23069
|
import { AIProjectClient as AIProjectClient3 } from "@azure/ai-projects";
|
|
22722
23070
|
import { LogsQueryClient as LogsQueryClient3, LogsQueryResultStatus as LogsQueryResultStatus3 } from "@azure/monitor-query";
|
|
22723
23071
|
|
|
@@ -23026,7 +23374,7 @@ var ConvFetchError = class extends Error {
|
|
|
23026
23374
|
};
|
|
23027
23375
|
|
|
23028
23376
|
// ../../packages/brain/engine/dist/esm/cursor.js
|
|
23029
|
-
import { TableClient as
|
|
23377
|
+
import { TableClient as TableClient6 } from "@azure/data-tables";
|
|
23030
23378
|
|
|
23031
23379
|
// ../../packages/agent-ledger/dist/esm/row-key.js
|
|
23032
23380
|
var MAX_MS = 864e13;
|
|
@@ -23166,7 +23514,7 @@ async function commitCursorAdvance(plan, cursor) {
|
|
|
23166
23514
|
}
|
|
23167
23515
|
var CURSOR_TABLE_NAME = "BrainDreamCursor";
|
|
23168
23516
|
function makeTableCursor(credential2, tableEndpoint) {
|
|
23169
|
-
const client = new
|
|
23517
|
+
const client = new TableClient6(tableEndpoint, CURSOR_TABLE_NAME, credential2);
|
|
23170
23518
|
return new TableCursor(client);
|
|
23171
23519
|
}
|
|
23172
23520
|
function formatCursorPreview(cursor) {
|
|
@@ -24942,20 +25290,20 @@ function redactTranscripts(input) {
|
|
|
24942
25290
|
}
|
|
24943
25291
|
var DreamRunCommand = class extends M8tCommand {
|
|
24944
25292
|
static paths = [["dream", "run"]];
|
|
24945
|
-
static usage =
|
|
25293
|
+
static usage = Command48.Usage({
|
|
24946
25294
|
description: "Dry-run the brain consumption pipeline for one worker (no model call, no writes).",
|
|
24947
25295
|
details: "Builds AzureCliCredential + resolves the Foundry project, ledger table, and Log Analytics workspace, runs the consumption pipeline, and prints the skip-ledger, the partition invariant, and harvest stats. Transcripts are metadata-only unless --show-transcripts is passed."
|
|
24948
25296
|
});
|
|
24949
|
-
worker =
|
|
24950
|
-
dryRun =
|
|
24951
|
-
since =
|
|
24952
|
-
reset =
|
|
24953
|
-
showTranscripts =
|
|
25297
|
+
worker = Option45.String("--worker", { description: "Worker (canonical name) to harvest. Required." });
|
|
25298
|
+
dryRun = Option45.Boolean("--dry-run", false, { description: "Read-only harvest; no model call, no writes." });
|
|
25299
|
+
since = Option45.String("--since", { description: "ISO-8601 start override (rejected if malformed or future)." });
|
|
25300
|
+
reset = Option45.Boolean("--reset", false, { description: "Ignore the stored cursor; read from the beginning." });
|
|
25301
|
+
showTranscripts = Option45.Boolean("--show-transcripts", false, {
|
|
24954
25302
|
description: "Print transcript bodies (default: metadata only)."
|
|
24955
25303
|
});
|
|
24956
|
-
subscription =
|
|
24957
|
-
endpoint =
|
|
24958
|
-
output =
|
|
25304
|
+
subscription = Option45.String("--subscription");
|
|
25305
|
+
endpoint = Option45.String("--endpoint");
|
|
25306
|
+
output = Option45.String("--output");
|
|
24959
25307
|
// Resolution seam — overridden by tests; built lazily at runtime otherwise.
|
|
24960
25308
|
deps;
|
|
24961
25309
|
async executeCommand() {
|
|
@@ -25150,7 +25498,7 @@ AppDependencies
|
|
|
25150
25498
|
};
|
|
25151
25499
|
}
|
|
25152
25500
|
function buildLiveSources(context, credential2) {
|
|
25153
|
-
const ledgerClient = new
|
|
25501
|
+
const ledgerClient = new TableClient7(context.ledgerTableEndpoint, LEDGER_TABLE_NAME, credential2);
|
|
25154
25502
|
const ledger = makeLedgerSource(
|
|
25155
25503
|
async (pk, sinceTs) => fetchLedgerRows(
|
|
25156
25504
|
{ workers: [pk], source: "all", from: sinceTs, to: "9999-12-31T23:59:59.999Z" },
|
|
@@ -25303,7 +25651,7 @@ function defaultDeps(overrides) {
|
|
|
25303
25651
|
}
|
|
25304
25652
|
|
|
25305
25653
|
// src/commands/foundry/create.ts
|
|
25306
|
-
import { Command as
|
|
25654
|
+
import { Command as Command49, Option as Option46 } from "clipanion";
|
|
25307
25655
|
|
|
25308
25656
|
// src/lib/foundry-create.ts
|
|
25309
25657
|
init_errors();
|
|
@@ -25541,7 +25889,7 @@ async function createFoundryProject(args) {
|
|
|
25541
25889
|
init_errors();
|
|
25542
25890
|
var FoundryCreateCommand = class extends M8tCommand {
|
|
25543
25891
|
static paths = [["foundry", "create"]];
|
|
25544
|
-
static usage =
|
|
25892
|
+
static usage = Command49.Usage({
|
|
25545
25893
|
description: "Create an AI Foundry (AIServices) account + project + model deployment from scratch.",
|
|
25546
25894
|
details: "Non-interactive and idempotent. Creates the AIServices account (custom subdomain + project management), a project, and a model deployment (default gpt-4.1-mini @ capacity 50). Region must be hosted-agent-eligible. Emits the project endpoint as structured output. Re-run is a clean no-op (account/project skipped if present; deployment capacity converges UP, never down).",
|
|
25547
25895
|
examples: [
|
|
@@ -25550,16 +25898,16 @@ var FoundryCreateCommand = class extends M8tCommand {
|
|
|
25550
25898
|
["Higher capacity for a reasoning model", "$0 foundry create --resource-group rg-m8t-stack --location eastus2 --model gpt-5-mini --capacity 250"]
|
|
25551
25899
|
]
|
|
25552
25900
|
});
|
|
25553
|
-
resourceGroup =
|
|
25554
|
-
location =
|
|
25555
|
-
account =
|
|
25556
|
-
project =
|
|
25557
|
-
model =
|
|
25558
|
-
modelVersion =
|
|
25559
|
-
capacity =
|
|
25560
|
-
subscription =
|
|
25561
|
-
skipQuotaCheck =
|
|
25562
|
-
output =
|
|
25901
|
+
resourceGroup = Option46.String("--resource-group");
|
|
25902
|
+
location = Option46.String("--location");
|
|
25903
|
+
account = Option46.String("--account");
|
|
25904
|
+
project = Option46.String("--project", "m8t");
|
|
25905
|
+
model = Option46.String("--model", "gpt-4.1-mini");
|
|
25906
|
+
modelVersion = Option46.String("--model-version", "2025-04-14");
|
|
25907
|
+
capacity = Option46.String("--capacity", "50");
|
|
25908
|
+
subscription = Option46.String("--subscription");
|
|
25909
|
+
skipQuotaCheck = Option46.Boolean("--skip-quota-check", false);
|
|
25910
|
+
output = Option46.String("--output");
|
|
25563
25911
|
async executeCommand() {
|
|
25564
25912
|
const mode = resolveOutputMode(
|
|
25565
25913
|
this.output,
|
|
@@ -25631,22 +25979,22 @@ var FoundryCreateCommand = class extends M8tCommand {
|
|
|
25631
25979
|
};
|
|
25632
25980
|
|
|
25633
25981
|
// src/commands/foundry/await-ready.ts
|
|
25634
|
-
import { Command as
|
|
25982
|
+
import { Command as Command50, Option as Option47 } from "clipanion";
|
|
25635
25983
|
import { AzureCliCredential as AzureCliCredential2 } from "@azure/identity";
|
|
25636
25984
|
init_errors();
|
|
25637
25985
|
var FoundryAwaitReadyCommand = class extends M8tCommand {
|
|
25638
25986
|
static paths = [["foundry", "await-ready"]];
|
|
25639
|
-
static usage =
|
|
25987
|
+
static usage = Command50.Usage({
|
|
25640
25988
|
description: "Wait until a freshly-created Foundry project's data plane reliably serves it.",
|
|
25641
25989
|
details: "Probes the project (GET /agents) until it returns 200 on a few consecutive tries, or fails clearly after a bounded budget. A newly-created account can serve intermittent 404 'Project not found' for minutes; run this after 'foundry create' and before deploying agents so the worker phase doesn't catch the unstable window.",
|
|
25642
25990
|
examples: [["Wait for a project to be ready", "$0 foundry await-ready --endpoint https://acc.services.ai.azure.com/api/projects/m8t"]]
|
|
25643
25991
|
});
|
|
25644
|
-
endpoint =
|
|
25645
|
-
consecutive =
|
|
25646
|
-
attempts =
|
|
25647
|
-
interval =
|
|
25648
|
-
subscription =
|
|
25649
|
-
output =
|
|
25992
|
+
endpoint = Option47.String("--endpoint");
|
|
25993
|
+
consecutive = Option47.String("--consecutive", "3");
|
|
25994
|
+
attempts = Option47.String("--attempts", "60");
|
|
25995
|
+
interval = Option47.String("--interval", "5");
|
|
25996
|
+
subscription = Option47.String("--subscription");
|
|
25997
|
+
output = Option47.String("--output");
|
|
25650
25998
|
async executeCommand() {
|
|
25651
25999
|
const mode = resolveOutputMode(this.output, this.context.stdout);
|
|
25652
26000
|
const endpoint = typeof this.endpoint === "string" ? this.endpoint : void 0;
|
|
@@ -25680,7 +26028,7 @@ var FoundryAwaitReadyCommand = class extends M8tCommand {
|
|
|
25680
26028
|
};
|
|
25681
26029
|
|
|
25682
26030
|
// src/commands/bootstrap/preflight.ts
|
|
25683
|
-
import { Command as
|
|
26031
|
+
import { Command as Command51, Option as Option48 } from "clipanion";
|
|
25684
26032
|
|
|
25685
26033
|
// ../../packages/telemetry-contract/artifact/tier-map.ts
|
|
25686
26034
|
var EVENT_TIERS = {
|
|
@@ -25791,7 +26139,7 @@ function buildPreflightBanner(who) {
|
|
|
25791
26139
|
// src/commands/bootstrap/preflight.ts
|
|
25792
26140
|
var BootstrapPreflightCommand = class extends M8tCommand {
|
|
25793
26141
|
static paths = [["bootstrap", "preflight"]];
|
|
25794
|
-
static usage =
|
|
26142
|
+
static usage = Command51.Usage({
|
|
25795
26143
|
description: "Loudly verify you can install m8t (Owner/UAA + directory admin) and hard-stop if not.",
|
|
25796
26144
|
details: "Step 1 of `m8t bootstrap`. Prints an unmissable admin-credentials notice, then checks: Owner or User Access Administrator at subscription scope (hard requirement), directory-admin capability to register the app (or pass --client-id), and registers Microsoft.ContainerInstance. Exits non-zero with the exact failing check + remedy.",
|
|
25797
26145
|
examples: [
|
|
@@ -25799,8 +26147,8 @@ var BootstrapPreflightCommand = class extends M8tCommand {
|
|
|
25799
26147
|
["BYO app registration (directory guests)", "$0 bootstrap preflight --client-id <appId>"]
|
|
25800
26148
|
]
|
|
25801
26149
|
});
|
|
25802
|
-
clientId =
|
|
25803
|
-
subscription =
|
|
26150
|
+
clientId = Option48.String("--client-id");
|
|
26151
|
+
subscription = Option48.String("--subscription");
|
|
25804
26152
|
async executeCommand() {
|
|
25805
26153
|
const clientId = typeof this.clientId === "string" ? this.clientId : void 0;
|
|
25806
26154
|
const account = await getAzAccount();
|
|
@@ -25863,7 +26211,7 @@ ${colors.error(" " + why)}
|
|
|
25863
26211
|
import * as fs30 from "fs";
|
|
25864
26212
|
import * as os14 from "os";
|
|
25865
26213
|
import * as path32 from "path";
|
|
25866
|
-
import { Command as
|
|
26214
|
+
import { Command as Command52, Option as Option49 } from "clipanion";
|
|
25867
26215
|
init_errors();
|
|
25868
26216
|
|
|
25869
26217
|
// src/lib/bootstrap-mi.ts
|
|
@@ -26210,7 +26558,7 @@ var ACI_NAME = "m8t-installer";
|
|
|
26210
26558
|
var MI_NAME = "m8t-installer-mi";
|
|
26211
26559
|
var BootstrapLaunchCommand = class extends M8tCommand {
|
|
26212
26560
|
static paths = [["bootstrap", "launch"]];
|
|
26213
|
-
static usage =
|
|
26561
|
+
static usage = Command52.Usage({
|
|
26214
26562
|
description: "Create + authorize the installer managed identity, then kick the cloud installer.",
|
|
26215
26563
|
details: "Step 2 of `m8t bootstrap` (run after `preflight`). Ensures the resource group, creates the m8t app registration (or uses --client-id), creates a user-assigned managed identity granted Owner at subscription scope, and launches the published m8t-installer image as an ACI run-to-completion job under that identity. Writes ~/.m8t/bootstrap.json for `status`/`reap`/`finish`.",
|
|
26216
26564
|
examples: [
|
|
@@ -26221,24 +26569,24 @@ var BootstrapLaunchCommand = class extends M8tCommand {
|
|
|
26221
26569
|
["Share a support contact", "$0 bootstrap launch --location eastus2 --contact-email you@example.com --company 'Acme'"]
|
|
26222
26570
|
]
|
|
26223
26571
|
});
|
|
26224
|
-
location =
|
|
26225
|
-
resourceGroup =
|
|
26226
|
-
clientId =
|
|
26227
|
-
subscription =
|
|
26228
|
-
installerTag =
|
|
26572
|
+
location = Option49.String("--location");
|
|
26573
|
+
resourceGroup = Option49.String("--resource-group");
|
|
26574
|
+
clientId = Option49.String("--client-id");
|
|
26575
|
+
subscription = Option49.String("--subscription");
|
|
26576
|
+
installerTag = Option49.String("--installer-tag");
|
|
26229
26577
|
// Full image ref override (registry + repo + tag) — an escape hatch when the
|
|
26230
26578
|
// default org/tag is wrong for the current CLI (e.g. a stale published build).
|
|
26231
26579
|
// Wins over --installer-tag / the pinned default.
|
|
26232
|
-
installerImage =
|
|
26233
|
-
gatewayImageRef =
|
|
26234
|
-
githubAppCreds =
|
|
26235
|
-
contactEmail =
|
|
26236
|
-
company =
|
|
26580
|
+
installerImage = Option49.String("--installer-image");
|
|
26581
|
+
gatewayImageRef = Option49.String("--gateway-image-ref");
|
|
26582
|
+
githubAppCreds = Option49.String("--github-app-creds");
|
|
26583
|
+
contactEmail = Option49.String("--contact-email", { description: "Share a contact email with m8t support. Not sent unless you pass it." });
|
|
26584
|
+
company = Option49.String("--company", { description: "Share your company name with m8t support. Not sent unless you pass it." });
|
|
26237
26585
|
// Value-carrying on purpose: a bare --force would be cargo-culted into
|
|
26238
26586
|
// runbooks and harness prompts and erode the protection, whereas a faithful
|
|
26239
26587
|
// paste can never accidentally carry the victim group's name. It AUTHORIZES
|
|
26240
26588
|
// the target; --resource-group is what CHOOSES it.
|
|
26241
|
-
reinstallInto =
|
|
26589
|
+
reinstallInto = Option49.String("--reinstall-into", { description: "Consent to installing into --resource-group even though it already holds resources. Must match the target group's name." });
|
|
26242
26590
|
async executeCommand() {
|
|
26243
26591
|
const location = typeof this.location === "string" ? this.location : void 0;
|
|
26244
26592
|
if (!location) {
|
|
@@ -26370,7 +26718,7 @@ var BootstrapLaunchCommand = class extends M8tCommand {
|
|
|
26370
26718
|
};
|
|
26371
26719
|
|
|
26372
26720
|
// src/commands/bootstrap/status.ts
|
|
26373
|
-
import { Command as
|
|
26721
|
+
import { Command as Command53, Option as Option50 } from "clipanion";
|
|
26374
26722
|
init_errors();
|
|
26375
26723
|
|
|
26376
26724
|
// src/lib/bootstrap-aci-state.ts
|
|
@@ -26398,13 +26746,13 @@ async function getAciState(opts) {
|
|
|
26398
26746
|
// src/commands/bootstrap/status.ts
|
|
26399
26747
|
var BootstrapStatusCommand = class extends M8tCommand {
|
|
26400
26748
|
static paths = [["bootstrap", "status"]];
|
|
26401
|
-
static usage =
|
|
26749
|
+
static usage = Command53.Usage({
|
|
26402
26750
|
description: "Show the cloud installer's live status (phase, progress, result).",
|
|
26403
26751
|
details: "Reads the durable status blob written by the installer. --watch polls until the install reaches done or failed.",
|
|
26404
26752
|
examples: [["One read", "$0 bootstrap status"], ["Watch to completion", "$0 bootstrap status --watch"]]
|
|
26405
26753
|
});
|
|
26406
|
-
watch =
|
|
26407
|
-
output =
|
|
26754
|
+
watch = Option50.Boolean("--watch", false);
|
|
26755
|
+
output = Option50.String("--output");
|
|
26408
26756
|
async executeCommand() {
|
|
26409
26757
|
const state = await readBootstrapState();
|
|
26410
26758
|
if (!state) {
|
|
@@ -26475,7 +26823,7 @@ function formatStatus(d) {
|
|
|
26475
26823
|
}
|
|
26476
26824
|
|
|
26477
26825
|
// src/commands/bootstrap/reap.ts
|
|
26478
|
-
import { Command as
|
|
26826
|
+
import { Command as Command54, Option as Option51 } from "clipanion";
|
|
26479
26827
|
init_errors();
|
|
26480
26828
|
|
|
26481
26829
|
// src/lib/bootstrap-reap.ts
|
|
@@ -26569,14 +26917,14 @@ async function reapInstaller(opts) {
|
|
|
26569
26917
|
// src/commands/bootstrap/reap.ts
|
|
26570
26918
|
var BootstrapReapCommand = class extends M8tCommand {
|
|
26571
26919
|
static paths = [["bootstrap", "reap"]];
|
|
26572
|
-
static usage =
|
|
26920
|
+
static usage = Command54.Usage({
|
|
26573
26921
|
description: "Tear down the installer scaffolding (ACI \u2192 MI \u2192 its role assignments) after a successful install.",
|
|
26574
26922
|
details: "Runs locally on the 'done' signal (the installer can't delete its own identity). The platform RG and the gateway's own assignments persist. A failed install is left intact for diagnosis unless --force.",
|
|
26575
26923
|
examples: [["Reap after done", "$0 bootstrap reap"]]
|
|
26576
26924
|
});
|
|
26577
|
-
force =
|
|
26578
|
-
sweepOrphans =
|
|
26579
|
-
yes =
|
|
26925
|
+
force = Option51.Boolean("--force", false);
|
|
26926
|
+
sweepOrphans = Option51.Boolean("--sweep-orphans", false);
|
|
26927
|
+
yes = Option51.Boolean("--yes", false);
|
|
26580
26928
|
async executeCommand() {
|
|
26581
26929
|
if (this.sweepOrphans === true) {
|
|
26582
26930
|
const { subscriptionId: sub } = await getAzAccount();
|
|
@@ -26673,7 +27021,7 @@ Found ${String(total)} orphaned assignment(s) (${breakdown}) (dry-run). ${colors
|
|
|
26673
27021
|
import * as fs31 from "fs/promises";
|
|
26674
27022
|
import * as os16 from "os";
|
|
26675
27023
|
import * as path34 from "path";
|
|
26676
|
-
import { Command as
|
|
27024
|
+
import { Command as Command55, Option as Option52 } from "clipanion";
|
|
26677
27025
|
init_errors();
|
|
26678
27026
|
|
|
26679
27027
|
// src/lib/company-profile-seed.ts
|
|
@@ -27330,14 +27678,14 @@ function renderInstallSummary(args) {
|
|
|
27330
27678
|
// src/commands/bootstrap/finish.ts
|
|
27331
27679
|
var BootstrapFinishCommand = class extends M8tCommand {
|
|
27332
27680
|
static paths = [["bootstrap", "finish"]];
|
|
27333
|
-
static usage =
|
|
27681
|
+
static usage = Command55.Usage({
|
|
27334
27682
|
description: "Point your local tools at the now-live platform (repo-root marker, discovery cache, next steps).",
|
|
27335
27683
|
details: "Final step of `m8t bootstrap` (after the install reaches done). Writes ~/.m8t/repo-root, points your local tools at the live gateway, and \u2014 if you completed the onboarding questionnaire \u2014 seeds your brain-backed advisor's brain with your company profile (best-effort; never blocks finish). Run `m8t bootstrap seed-profile` to seed manually later.",
|
|
27336
27684
|
examples: [["Finish local", "$0 bootstrap finish --repo-root /path/to/m8t"]]
|
|
27337
27685
|
});
|
|
27338
|
-
repoRoot =
|
|
27339
|
-
subscription =
|
|
27340
|
-
resourceGroup =
|
|
27686
|
+
repoRoot = Option52.String("--repo-root");
|
|
27687
|
+
subscription = Option52.String("--subscription");
|
|
27688
|
+
resourceGroup = Option52.String("--resource-group");
|
|
27341
27689
|
async executeCommand() {
|
|
27342
27690
|
const state = await readBootstrapState();
|
|
27343
27691
|
if (!state) {
|
|
@@ -27440,8 +27788,8 @@ ${colors.field("Then open a brand new chat/session")} \u2014 new skills + MCP se
|
|
|
27440
27788
|
import * as fs33 from "fs";
|
|
27441
27789
|
import * as os18 from "os";
|
|
27442
27790
|
import * as path36 from "path";
|
|
27443
|
-
import { Command as
|
|
27444
|
-
import { DefaultAzureCredential as
|
|
27791
|
+
import { Command as Command56, Option as Option53 } from "clipanion";
|
|
27792
|
+
import { DefaultAzureCredential as DefaultAzureCredential23 } from "@azure/identity";
|
|
27445
27793
|
init_errors();
|
|
27446
27794
|
|
|
27447
27795
|
// src/lib/bootstrap-ui.ts
|
|
@@ -28199,7 +28547,7 @@ function renderDeployFailure(error) {
|
|
|
28199
28547
|
}
|
|
28200
28548
|
var BootstrapUiCommand = class extends M8tCommand {
|
|
28201
28549
|
static paths = [["bootstrap", "ui"]];
|
|
28202
|
-
static usage =
|
|
28550
|
+
static usage = Command56.Usage({
|
|
28203
28551
|
description: "Deploy Simple Stacey + start the local onboarding chat UI in the background (returns immediately).",
|
|
28204
28552
|
details: [
|
|
28205
28553
|
"Run after `m8t bootstrap launch`, in parallel with `status --watch`. Waits for the cloud",
|
|
@@ -28219,16 +28567,16 @@ var BootstrapUiCommand = class extends M8tCommand {
|
|
|
28219
28567
|
["Experimental: enable the intake voice call", "$0 bootstrap ui --repo-root /path/to/m8t --voice"]
|
|
28220
28568
|
]
|
|
28221
28569
|
});
|
|
28222
|
-
repoRoot =
|
|
28223
|
-
port =
|
|
28224
|
-
endpoint =
|
|
28570
|
+
repoRoot = Option53.String("--repo-root");
|
|
28571
|
+
port = Option53.String("--port", "3000");
|
|
28572
|
+
endpoint = Option53.String("--endpoint", {
|
|
28225
28573
|
description: "Foundry project endpoint to target \u2014 disambiguates when the subscription has multiple projects."
|
|
28226
28574
|
});
|
|
28227
|
-
prepOnly =
|
|
28228
|
-
skipInstall =
|
|
28229
|
-
stop =
|
|
28230
|
-
foreground =
|
|
28231
|
-
voice =
|
|
28575
|
+
prepOnly = Option53.Boolean("--prep-only", false);
|
|
28576
|
+
skipInstall = Option53.Boolean("--skip-install", false);
|
|
28577
|
+
stop = Option53.Boolean("--stop", false);
|
|
28578
|
+
foreground = Option53.Boolean("--foreground", false);
|
|
28579
|
+
voice = Option53.Boolean("--voice", false, {
|
|
28232
28580
|
description: "Experimental/preview: enable the intake voice call and start the voice relay on :8790. Not a supported founder path \u2014 the intake is text-only by default."
|
|
28233
28581
|
});
|
|
28234
28582
|
async executeCommand() {
|
|
@@ -28266,7 +28614,7 @@ var BootstrapUiCommand = class extends M8tCommand {
|
|
|
28266
28614
|
if (fs33.existsSync(path36.join(os18.homedir(), ".m8t", "config.yaml"))) {
|
|
28267
28615
|
out(colors.error("\u26A0 an existing ~/.m8t/config.yaml will override the onboarding app registration in apps/web \u2014 if Microsoft sign-in fails, move it aside and retry."));
|
|
28268
28616
|
}
|
|
28269
|
-
const credential2 = new
|
|
28617
|
+
const credential2 = new DefaultAzureCredential23();
|
|
28270
28618
|
const account = await getAzAccount();
|
|
28271
28619
|
assertNodeVersion();
|
|
28272
28620
|
out("waiting for Foundry (the installer's foundry-create phase)\u2026");
|
|
@@ -28382,10 +28730,10 @@ var BootstrapUiCommand = class extends M8tCommand {
|
|
|
28382
28730
|
};
|
|
28383
28731
|
|
|
28384
28732
|
// src/commands/bootstrap/seed-profile.ts
|
|
28385
|
-
import { Command as
|
|
28733
|
+
import { Command as Command57, Option as Option54 } from "clipanion";
|
|
28386
28734
|
var BootstrapSeedProfileCommand = class extends M8tCommand {
|
|
28387
28735
|
static paths = [["bootstrap", "seed-profile"]];
|
|
28388
|
-
static usage =
|
|
28736
|
+
static usage = Command57.Usage({
|
|
28389
28737
|
description: "Seed your advisors' brains with the founder + company profile from the onboarding questionnaire.",
|
|
28390
28738
|
details: "Reads the latest stacey-intake conversation, renders memory/founder.md + memory/company-profile.md (+ their MEMORY.md index lines), and commits them to both <org>/stacey-brain and <org>/azzy-brain via the GitHub App. Idempotent. --watch polls until the founder completes the questionnaire.",
|
|
28391
28739
|
examples: [
|
|
@@ -28393,11 +28741,11 @@ var BootstrapSeedProfileCommand = class extends M8tCommand {
|
|
|
28393
28741
|
["Wait for the founder to finish", "$0 bootstrap seed-profile --watch"]
|
|
28394
28742
|
]
|
|
28395
28743
|
});
|
|
28396
|
-
endpoint =
|
|
28397
|
-
brain =
|
|
28398
|
-
watch =
|
|
28399
|
-
timeout =
|
|
28400
|
-
githubAppCreds =
|
|
28744
|
+
endpoint = Option54.String("--endpoint", { description: "Override the Foundry endpoint (else read from the install status)." });
|
|
28745
|
+
brain = Option54.String("--brain", { description: "Override the brain repo (default <org>/stacey-brain)." });
|
|
28746
|
+
watch = Option54.Boolean("--watch", false, { description: "Poll until the questionnaire completes (or --timeout)." });
|
|
28747
|
+
timeout = Option54.String("--timeout", { description: "Watch timeout in minutes (default 20)." });
|
|
28748
|
+
githubAppCreds = Option54.String("--github-app-creds");
|
|
28401
28749
|
async executeCommand() {
|
|
28402
28750
|
const ctx = await resolveSeedContext({
|
|
28403
28751
|
endpointOverride: typeof this.endpoint === "string" ? this.endpoint : void 0,
|
|
@@ -28451,7 +28799,7 @@ var BootstrapSeedProfileCommand = class extends M8tCommand {
|
|
|
28451
28799
|
import * as fs34 from "fs";
|
|
28452
28800
|
import * as os19 from "os";
|
|
28453
28801
|
import * as path37 from "path";
|
|
28454
|
-
import { Command as
|
|
28802
|
+
import { Command as Command58, Option as Option55 } from "clipanion";
|
|
28455
28803
|
init_errors();
|
|
28456
28804
|
|
|
28457
28805
|
// src/lib/telemetry-enroll.ts
|
|
@@ -28533,7 +28881,7 @@ async function resolveKeyVaultName(containerAppResourceId) {
|
|
|
28533
28881
|
}
|
|
28534
28882
|
var TelemetryEnrollCommand = class extends M8tCommand {
|
|
28535
28883
|
static paths = [["telemetry", "enroll"]];
|
|
28536
|
-
static usage =
|
|
28884
|
+
static usage = Command58.Usage({
|
|
28537
28885
|
description: "Enroll this installation for operational telemetry (pre-existing installs).",
|
|
28538
28886
|
details: "Generates an instance id + ingest key from the m8t telemetry ingest and stores the key in your platform Key Vault, the same place the installer writes it on a fresh install. Your installation is identified only by that random instance id \u2014 no contact, company, or subscription details are sent unless you pass them explicitly. Idempotent: refuses if a key already exists.",
|
|
28539
28887
|
examples: [
|
|
@@ -28541,11 +28889,11 @@ var TelemetryEnrollCommand = class extends M8tCommand {
|
|
|
28541
28889
|
["Enroll and share a support contact", "$0 telemetry enroll --contact-email you@example.com --company 'Acme'"]
|
|
28542
28890
|
]
|
|
28543
28891
|
});
|
|
28544
|
-
company =
|
|
28545
|
-
contactEmail =
|
|
28546
|
-
subscription =
|
|
28547
|
-
resourceGroup =
|
|
28548
|
-
force =
|
|
28892
|
+
company = Option55.String("--company", { description: "Share your company name with m8t support. Not sent unless you pass it." });
|
|
28893
|
+
contactEmail = Option55.String("--contact-email", { description: "Share a contact email with m8t support. Not sent unless you pass it." });
|
|
28894
|
+
subscription = Option55.String("--subscription", { description: "Azure subscription id used to find your deployment. Never sent to m8t." });
|
|
28895
|
+
resourceGroup = Option55.String("--resource-group", { description: "Resource group to disambiguate discovery, if you have more than one m8t deployment." });
|
|
28896
|
+
force = Option55.Boolean("--force", false, { description: "Enroll even when a key is already stored. Use only when m8t support asks you to." });
|
|
28549
28897
|
async executeCommand() {
|
|
28550
28898
|
const account = await getAzAccount();
|
|
28551
28899
|
const subscriptionId = (typeof this.subscription === "string" ? this.subscription : void 0) ?? account.subscriptionId;
|
|
@@ -28636,6 +28984,8 @@ cli.register(PlatformStatusCommand);
|
|
|
28636
28984
|
cli.register(PlatformUpdateCommand);
|
|
28637
28985
|
cli.register(PlatformConvergeCommand);
|
|
28638
28986
|
cli.register(PlatformSeedStampCommand);
|
|
28987
|
+
cli.register(PlatformStampBuildCommand);
|
|
28988
|
+
cli.register(PlatformPolicyCommand);
|
|
28639
28989
|
cli.register(PlatformEnableCostReportCommand);
|
|
28640
28990
|
cli.register(PlatformEnableAutoUpdateCommand);
|
|
28641
28991
|
cli.register(DeployCommand);
|