@m8t-stack/cli 0.2.46 → 0.2.48
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 +546 -349
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1329,7 +1329,7 @@ var init_enable_hosted_brain = __esm({
|
|
|
1329
1329
|
import { Builtins, Cli } from "clipanion";
|
|
1330
1330
|
|
|
1331
1331
|
// src/lib/package-version.ts
|
|
1332
|
-
var CLI_VERSION = "0.2.
|
|
1332
|
+
var CLI_VERSION = "0.2.48";
|
|
1333
1333
|
|
|
1334
1334
|
// src/lib/render-error.ts
|
|
1335
1335
|
init_errors();
|
|
@@ -16225,19 +16225,135 @@ var BrainListCommand = class extends M8tCommand {
|
|
|
16225
16225
|
}
|
|
16226
16226
|
};
|
|
16227
16227
|
|
|
16228
|
-
// src/commands/brain/
|
|
16228
|
+
// src/commands/brain/orgs.ts
|
|
16229
16229
|
import { Command as Command21, Option as Option20 } from "clipanion";
|
|
16230
|
+
|
|
16231
|
+
// src/lib/github-orgs.ts
|
|
16232
|
+
var ORG_QUERY = "{ viewer { organizations(first:50) { nodes { login viewerCanAdminister enterpriseOwners(first:1) { totalCount } } } } }";
|
|
16233
|
+
function classifyOrgs(result) {
|
|
16234
|
+
if (!result.ok) return { verdict: "undetermined", candidates: [], orgs: [] };
|
|
16235
|
+
const orgs = result.orgs;
|
|
16236
|
+
if (orgs.length === 0) return { verdict: "no-orgs", candidates: [], orgs };
|
|
16237
|
+
const enterprise = orgs.filter((o) => o.enterprise);
|
|
16238
|
+
if (enterprise.length === 1) {
|
|
16239
|
+
return { verdict: "enterprise-single", selected: enterprise[0].login, candidates: enterprise, orgs };
|
|
16240
|
+
}
|
|
16241
|
+
if (enterprise.length > 1) {
|
|
16242
|
+
return { verdict: "enterprise-multiple", candidates: enterprise, orgs };
|
|
16243
|
+
}
|
|
16244
|
+
return { verdict: "no-enterprise", candidates: orgs, orgs };
|
|
16245
|
+
}
|
|
16246
|
+
async function fetchOrgGraph(exec = defaultGhExec) {
|
|
16247
|
+
const r = await exec("gh", ["api", "graphql", "-f", `query=${ORG_QUERY}`]);
|
|
16248
|
+
if (r.exitCode !== 0) {
|
|
16249
|
+
return { ok: false, reason: r.stderr.trim() || `gh exited ${r.exitCode.toString()}` };
|
|
16250
|
+
}
|
|
16251
|
+
let parsed;
|
|
16252
|
+
try {
|
|
16253
|
+
parsed = JSON.parse(r.stdout);
|
|
16254
|
+
} catch {
|
|
16255
|
+
return { ok: false, reason: "gh returned output that is not JSON" };
|
|
16256
|
+
}
|
|
16257
|
+
if (Array.isArray(parsed.errors) && parsed.errors.length > 0) {
|
|
16258
|
+
return { ok: false, reason: "the org query returned a partial result" };
|
|
16259
|
+
}
|
|
16260
|
+
const nodes = parsed.data?.viewer?.organizations?.nodes;
|
|
16261
|
+
if (!Array.isArray(nodes)) return { ok: false, reason: "unexpected response shape" };
|
|
16262
|
+
const orgs = [];
|
|
16263
|
+
for (const raw of nodes) {
|
|
16264
|
+
if (raw === null) return { ok: false, reason: "unexpected response shape" };
|
|
16265
|
+
const login = raw.login;
|
|
16266
|
+
const total = raw.enterpriseOwners?.totalCount;
|
|
16267
|
+
if (typeof login !== "string" || typeof total !== "number") {
|
|
16268
|
+
return { ok: false, reason: "unexpected response shape" };
|
|
16269
|
+
}
|
|
16270
|
+
orgs.push({ login, enterprise: total > 0, canAdminister: raw.viewerCanAdminister === true });
|
|
16271
|
+
}
|
|
16272
|
+
return { ok: true, orgs };
|
|
16273
|
+
}
|
|
16274
|
+
|
|
16275
|
+
// src/lib/github-orgs-copy.ts
|
|
16276
|
+
function enterpriseSingleNotice(org) {
|
|
16277
|
+
return `Using your GitHub Enterprise org ${org} for your workers' brains.`;
|
|
16278
|
+
}
|
|
16279
|
+
function enterpriseMultiplePrompt(logins) {
|
|
16280
|
+
return `You belong to more than one GitHub Enterprise org: ${logins.join(", ")}. Which one should your workers' brains live in?`;
|
|
16281
|
+
}
|
|
16282
|
+
function noEnterpriseNotice(selectedOrg) {
|
|
16283
|
+
return `No GitHub Enterprise org detected; if you have the Microsoft for Startups benefit, your workers' brains can live there - continuing with ${selectedOrg} for now.`;
|
|
16284
|
+
}
|
|
16285
|
+
function undeterminedNotice() {
|
|
16286
|
+
return `Could not check your GitHub orgs automatically - listing them instead.`;
|
|
16287
|
+
}
|
|
16288
|
+
function noOrgsRefusal() {
|
|
16289
|
+
return `Your workers' brains are created by a GitHub App, which can only make repositories in an organization, and this account belongs to none. Creating a free GitHub organization and then running \`m8t brain app-create --org <org>\` is enough.`;
|
|
16290
|
+
}
|
|
16291
|
+
|
|
16292
|
+
// src/commands/brain/orgs.ts
|
|
16293
|
+
var BrainOrgsCommand = class extends M8tCommand {
|
|
16294
|
+
static paths = [["brain", "orgs"]];
|
|
16295
|
+
static usage = Command21.Usage({
|
|
16296
|
+
description: "Show which GitHub org your workers' brains should live in.",
|
|
16297
|
+
details: "Read-only. Lists the organizations you belong to and prefers one linked to a GitHub Enterprise account. Advisory: `m8t brain app-create --org <org>` decides where the App is installed, so an explicit choice always wins.",
|
|
16298
|
+
examples: [
|
|
16299
|
+
["Show the recommendation", "$0 brain orgs"],
|
|
16300
|
+
["Machine-readable", "$0 brain orgs --output json"]
|
|
16301
|
+
]
|
|
16302
|
+
});
|
|
16303
|
+
output = Option20.String("--output");
|
|
16304
|
+
async executeCommand() {
|
|
16305
|
+
const outputFlag = this.output === "json" || this.output === "auto" || this.output === "pretty" ? this.output : "pretty";
|
|
16306
|
+
const mode = resolveOutputMode(outputFlag, this.context.stdout);
|
|
16307
|
+
const classification = classifyOrgs(await fetchOrgGraph());
|
|
16308
|
+
if (mode === "json") {
|
|
16309
|
+
this.context.stdout.write(renderJson(classification) + "\n");
|
|
16310
|
+
return exitCodeFor(classification);
|
|
16311
|
+
}
|
|
16312
|
+
this.renderPretty(classification);
|
|
16313
|
+
return exitCodeFor(classification);
|
|
16314
|
+
}
|
|
16315
|
+
renderPretty(c) {
|
|
16316
|
+
const out = (s) => this.context.stdout.write(s + "\n");
|
|
16317
|
+
switch (c.verdict) {
|
|
16318
|
+
case "enterprise-single":
|
|
16319
|
+
out(`${colors.success("\u2713")} ${enterpriseSingleNotice(c.selected ?? "")}`);
|
|
16320
|
+
return;
|
|
16321
|
+
case "enterprise-multiple":
|
|
16322
|
+
out(enterpriseMultiplePrompt(c.candidates.map((o) => o.login)));
|
|
16323
|
+
return;
|
|
16324
|
+
case "no-enterprise":
|
|
16325
|
+
out(noEnterpriseNotice(c.candidates[0]?.login ?? ""));
|
|
16326
|
+
if (c.candidates.length > 1) {
|
|
16327
|
+
out(` ${colors.dim(`orgs: ${c.candidates.map((o) => o.login).join(", ")}`)}`);
|
|
16328
|
+
}
|
|
16329
|
+
return;
|
|
16330
|
+
case "undetermined":
|
|
16331
|
+
out(undeterminedNotice());
|
|
16332
|
+
return;
|
|
16333
|
+
case "no-orgs":
|
|
16334
|
+
this.context.stderr.write(`${colors.error("\u2717")} ${noOrgsRefusal()}
|
|
16335
|
+
`);
|
|
16336
|
+
return;
|
|
16337
|
+
}
|
|
16338
|
+
}
|
|
16339
|
+
};
|
|
16340
|
+
function exitCodeFor(c) {
|
|
16341
|
+
return c.verdict === "no-orgs" ? 1 : 0;
|
|
16342
|
+
}
|
|
16343
|
+
|
|
16344
|
+
// src/commands/brain/show.ts
|
|
16345
|
+
import { Command as Command22, Option as Option21 } from "clipanion";
|
|
16230
16346
|
import { DefaultAzureCredential as DefaultAzureCredential7 } from "@azure/identity";
|
|
16231
16347
|
init_errors();
|
|
16232
16348
|
init_foundry_agent_get();
|
|
16233
16349
|
init_esm();
|
|
16234
16350
|
var BrainShowCommand = class extends M8tCommand {
|
|
16235
16351
|
static paths = [["brain", "show"]];
|
|
16236
|
-
static usage =
|
|
16237
|
-
worker =
|
|
16238
|
-
subscription =
|
|
16239
|
-
endpoint =
|
|
16240
|
-
output =
|
|
16352
|
+
static usage = Command22.Usage({ description: "Show a worker's brain link + connection diagnostics." });
|
|
16353
|
+
worker = Option21.String();
|
|
16354
|
+
subscription = Option21.String("--subscription");
|
|
16355
|
+
endpoint = Option21.String("--endpoint");
|
|
16356
|
+
output = Option21.String("--output");
|
|
16241
16357
|
async executeCommand() {
|
|
16242
16358
|
const worker = typeof this.worker === "string" ? this.worker : void 0;
|
|
16243
16359
|
if (!worker) {
|
|
@@ -16296,7 +16412,7 @@ var BrainShowCommand = class extends M8tCommand {
|
|
|
16296
16412
|
};
|
|
16297
16413
|
|
|
16298
16414
|
// src/commands/brain/unlink.ts
|
|
16299
|
-
import { Command as
|
|
16415
|
+
import { Command as Command23, Option as Option22 } from "clipanion";
|
|
16300
16416
|
import { DefaultAzureCredential as DefaultAzureCredential8 } from "@azure/identity";
|
|
16301
16417
|
init_errors();
|
|
16302
16418
|
|
|
@@ -16456,7 +16572,7 @@ ${text.slice(0, 300)}`
|
|
|
16456
16572
|
// src/commands/brain/unlink.ts
|
|
16457
16573
|
var BrainUnlinkCommand = class extends M8tCommand {
|
|
16458
16574
|
static paths = [["brain", "unlink"]];
|
|
16459
|
-
static usage =
|
|
16575
|
+
static usage = Command23.Usage({
|
|
16460
16576
|
description: "Unlink a worker from its brain repo (cascade teardown).",
|
|
16461
16577
|
details: "Re-deploys the agent without the brain loader + MCP tool, deletes the Foundry connection, and (unless --keep-app-install) uninstalls the GitHub App on the repo. The repo itself is NOT deleted.",
|
|
16462
16578
|
examples: [
|
|
@@ -16464,13 +16580,13 @@ var BrainUnlinkCommand = class extends M8tCommand {
|
|
|
16464
16580
|
["Unlink but keep the App install", "$0 brain unlink cmo --yes --keep-app-install"]
|
|
16465
16581
|
]
|
|
16466
16582
|
});
|
|
16467
|
-
worker =
|
|
16468
|
-
yes =
|
|
16469
|
-
keepAppInstall =
|
|
16470
|
-
kvUri =
|
|
16471
|
-
subscription =
|
|
16472
|
-
endpoint =
|
|
16473
|
-
output =
|
|
16583
|
+
worker = Option22.String();
|
|
16584
|
+
yes = Option22.Boolean("--yes", false);
|
|
16585
|
+
keepAppInstall = Option22.Boolean("--keep-app-install", false);
|
|
16586
|
+
kvUri = Option22.String("--kv-uri");
|
|
16587
|
+
subscription = Option22.String("--subscription");
|
|
16588
|
+
endpoint = Option22.String("--endpoint");
|
|
16589
|
+
output = Option22.String("--output");
|
|
16474
16590
|
async executeCommand() {
|
|
16475
16591
|
const worker = typeof this.worker === "string" ? this.worker : void 0;
|
|
16476
16592
|
if (!worker) {
|
|
@@ -16560,7 +16676,7 @@ var BrainUnlinkCommand = class extends M8tCommand {
|
|
|
16560
16676
|
};
|
|
16561
16677
|
|
|
16562
16678
|
// src/commands/agent/deploy-advisor.ts
|
|
16563
|
-
import { Command as
|
|
16679
|
+
import { Command as Command24, Option as Option23 } from "clipanion";
|
|
16564
16680
|
import { DefaultAzureCredential as DefaultAzureCredential9 } from "@azure/identity";
|
|
16565
16681
|
init_errors();
|
|
16566
16682
|
|
|
@@ -16651,7 +16767,7 @@ async function deployPromptAdvisor(args) {
|
|
|
16651
16767
|
// src/commands/agent/deploy-advisor.ts
|
|
16652
16768
|
var AgentDeployAdvisorCommand = class extends M8tCommand {
|
|
16653
16769
|
static paths = [["agent", "deploy-advisor"]];
|
|
16654
|
-
static usage =
|
|
16770
|
+
static usage = Command24.Usage({
|
|
16655
16771
|
description: "Deploy a brain-eligible prompt advisor headlessly from its persona frontmatter.",
|
|
16656
16772
|
details: "Reads the persona frontmatter (model, reasoning effort, fillable-field defaults) from personas/<persona>/persona.md, renders the instructions, and creates a new Foundry prompt-agent version under <name>. Idempotent \u2014 re-running creates a new version. Used by the cloud installer to seed the default advisor worker set.",
|
|
16657
16773
|
examples: [
|
|
@@ -16669,25 +16785,25 @@ var AgentDeployAdvisorCommand = class extends M8tCommand {
|
|
|
16669
16785
|
]
|
|
16670
16786
|
]
|
|
16671
16787
|
});
|
|
16672
|
-
persona =
|
|
16788
|
+
persona = Option23.String("--persona", {
|
|
16673
16789
|
description: "Persona directory name under personas/ (e.g. startup-advisor)."
|
|
16674
16790
|
});
|
|
16675
|
-
name =
|
|
16791
|
+
name = Option23.String("--name", {
|
|
16676
16792
|
description: "The agent instance name to deploy as (e.g. stacey)."
|
|
16677
16793
|
});
|
|
16678
|
-
model =
|
|
16794
|
+
model = Option23.String("--model", {
|
|
16679
16795
|
description: "Override the model from persona frontmatter."
|
|
16680
16796
|
});
|
|
16681
|
-
endpoint =
|
|
16797
|
+
endpoint = Option23.String("--endpoint", {
|
|
16682
16798
|
description: "Foundry project endpoint URL. If omitted, resolved from the subscription."
|
|
16683
16799
|
});
|
|
16684
|
-
subscription =
|
|
16800
|
+
subscription = Option23.String("--subscription", {
|
|
16685
16801
|
description: "Azure subscription ID. Defaults to the current az account."
|
|
16686
16802
|
});
|
|
16687
|
-
repoRootFlag =
|
|
16803
|
+
repoRootFlag = Option23.String("--repo-root", {
|
|
16688
16804
|
description: "Path to the m8t repo checkout. Defaults to the ~/.m8t/repo-root marker."
|
|
16689
16805
|
});
|
|
16690
|
-
output =
|
|
16806
|
+
output = Option23.String("--output", {
|
|
16691
16807
|
description: "Output format: pretty (default) or json."
|
|
16692
16808
|
});
|
|
16693
16809
|
async executeCommand() {
|
|
@@ -16753,7 +16869,7 @@ var AgentDeployAdvisorCommand = class extends M8tCommand {
|
|
|
16753
16869
|
};
|
|
16754
16870
|
|
|
16755
16871
|
// src/commands/agent/remove.ts
|
|
16756
|
-
import { Command as
|
|
16872
|
+
import { Command as Command25, Option as Option24 } from "clipanion";
|
|
16757
16873
|
import { DefaultAzureCredential as DefaultAzureCredential10 } from "@azure/identity";
|
|
16758
16874
|
init_errors();
|
|
16759
16875
|
|
|
@@ -17213,7 +17329,7 @@ function defaultRemoveAgentDeps(args) {
|
|
|
17213
17329
|
// src/commands/agent/remove.ts
|
|
17214
17330
|
var AgentRemoveCommand = class extends M8tCommand {
|
|
17215
17331
|
static paths = [["agent", "remove"]];
|
|
17216
|
-
static usage =
|
|
17332
|
+
static usage = Command25.Usage({
|
|
17217
17333
|
description: "Cascade-remove an agent and all its associated resources.",
|
|
17218
17334
|
details: "Removes, in order: channel bindings (table row + KV secret + conversations), a2a connection, brain connection (GitHub repo kept by default), the agent itself, and its local yaml. Idempotent and partial-failure resilient.",
|
|
17219
17335
|
examples: [
|
|
@@ -17222,18 +17338,18 @@ var AgentRemoveCommand = class extends M8tCommand {
|
|
|
17222
17338
|
["Remove without touching bindings", "$0 agent remove my-agent --yes --keep-bindings"]
|
|
17223
17339
|
]
|
|
17224
17340
|
});
|
|
17225
|
-
name =
|
|
17226
|
-
yes =
|
|
17227
|
-
keepBindings =
|
|
17228
|
-
keepA2a =
|
|
17229
|
-
deleteBrainRepo =
|
|
17230
|
-
endpoint =
|
|
17231
|
-
subscription =
|
|
17232
|
-
kvUri =
|
|
17233
|
-
resourceGroup =
|
|
17341
|
+
name = Option24.String();
|
|
17342
|
+
yes = Option24.Boolean("--yes", false);
|
|
17343
|
+
keepBindings = Option24.Boolean("--keep-bindings", false);
|
|
17344
|
+
keepA2a = Option24.Boolean("--keep-a2a", false);
|
|
17345
|
+
deleteBrainRepo = Option24.Boolean("--delete-brain-repo", false);
|
|
17346
|
+
endpoint = Option24.String("--endpoint");
|
|
17347
|
+
subscription = Option24.String("--subscription");
|
|
17348
|
+
kvUri = Option24.String("--kv-uri");
|
|
17349
|
+
resourceGroup = Option24.String("--resource-group", {
|
|
17234
17350
|
description: "m8t resource group to disambiguate the gateway (multi-deployment subscriptions)."
|
|
17235
17351
|
});
|
|
17236
|
-
output =
|
|
17352
|
+
output = Option24.String("--output");
|
|
17237
17353
|
async executeCommand() {
|
|
17238
17354
|
const name = typeof this.name === "string" ? this.name : void 0;
|
|
17239
17355
|
if (!name) {
|
|
@@ -17348,7 +17464,7 @@ ${colors.success("\u2713")} removed ${colors.field(name)}.
|
|
|
17348
17464
|
|
|
17349
17465
|
// src/commands/a2a/enable.ts
|
|
17350
17466
|
import * as path14 from "path";
|
|
17351
|
-
import { Command as
|
|
17467
|
+
import { Command as Command26, Option as Option25 } from "clipanion";
|
|
17352
17468
|
import { DefaultAzureCredential as DefaultAzureCredential11 } from "@azure/identity";
|
|
17353
17469
|
init_errors();
|
|
17354
17470
|
|
|
@@ -17391,17 +17507,17 @@ function readConfigGatewayUrl(home) {
|
|
|
17391
17507
|
// src/commands/a2a/enable.ts
|
|
17392
17508
|
var A2aEnableCommand = class extends M8tCommand {
|
|
17393
17509
|
static paths = [["a2a", "enable"]];
|
|
17394
|
-
static usage =
|
|
17510
|
+
static usage = Command26.Usage({
|
|
17395
17511
|
description: "Enable a worker for agent-to-agent delegation (caller + callee). Idempotent (rotates the bearer).",
|
|
17396
17512
|
details: "Attaches the A2A tool[type:mcp] (discover_workers + invoke_worker), provisions a CustomKeys connection holding a freshly-minted bearer, and projects the persona's a2a-card + sha256(bearer) into Foundry agent metadata. The bridge then lists this worker in discover_workers and recognizes it as a caller by the bearer hash.",
|
|
17397
17513
|
examples: [["Enable the cmo persona", "$0 a2a enable cmo --persona cmo --gateway-url https://<gateway-fqdn>"]]
|
|
17398
17514
|
});
|
|
17399
|
-
worker =
|
|
17400
|
-
persona =
|
|
17401
|
-
gatewayUrl =
|
|
17402
|
-
endpoint =
|
|
17403
|
-
subscription =
|
|
17404
|
-
output =
|
|
17515
|
+
worker = Option25.String();
|
|
17516
|
+
persona = Option25.String("--persona");
|
|
17517
|
+
gatewayUrl = Option25.String("--gateway-url");
|
|
17518
|
+
endpoint = Option25.String("--endpoint");
|
|
17519
|
+
subscription = Option25.String("--subscription");
|
|
17520
|
+
output = Option25.String("--output");
|
|
17405
17521
|
async executeCommand() {
|
|
17406
17522
|
const env = this.context.env;
|
|
17407
17523
|
const outputFlag = this.output === "json" || this.output === "auto" || this.output === "pretty" ? this.output : "pretty";
|
|
@@ -17461,18 +17577,18 @@ var A2aEnableCommand = class extends M8tCommand {
|
|
|
17461
17577
|
};
|
|
17462
17578
|
|
|
17463
17579
|
// src/commands/a2a/disable.ts
|
|
17464
|
-
import { Command as
|
|
17580
|
+
import { Command as Command27, Option as Option26 } from "clipanion";
|
|
17465
17581
|
import { DefaultAzureCredential as DefaultAzureCredential12 } from "@azure/identity";
|
|
17466
17582
|
var A2aDisableCommand = class extends M8tCommand {
|
|
17467
17583
|
static paths = [["a2a", "disable"]];
|
|
17468
|
-
static usage =
|
|
17584
|
+
static usage = Command27.Usage({
|
|
17469
17585
|
description: "Disable agent-to-agent delegation for a worker (remove tool + connection + metadata). Idempotent.",
|
|
17470
17586
|
examples: [["Disable the cmo persona", "$0 a2a disable cmo"]]
|
|
17471
17587
|
});
|
|
17472
|
-
worker =
|
|
17473
|
-
endpoint =
|
|
17474
|
-
subscription =
|
|
17475
|
-
output =
|
|
17588
|
+
worker = Option26.String();
|
|
17589
|
+
endpoint = Option26.String("--endpoint");
|
|
17590
|
+
subscription = Option26.String("--subscription");
|
|
17591
|
+
output = Option26.String("--output");
|
|
17476
17592
|
async executeCommand() {
|
|
17477
17593
|
const outputFlag = this.output === "json" || this.output === "auto" || this.output === "pretty" ? this.output : "pretty";
|
|
17478
17594
|
const mode = resolveOutputMode(outputFlag, this.context.stdout);
|
|
@@ -17506,7 +17622,7 @@ var A2aDisableCommand = class extends M8tCommand {
|
|
|
17506
17622
|
};
|
|
17507
17623
|
|
|
17508
17624
|
// src/commands/architect/check.ts
|
|
17509
|
-
import { Command as
|
|
17625
|
+
import { Command as Command28 } from "clipanion";
|
|
17510
17626
|
|
|
17511
17627
|
// src/lib/architect-version.ts
|
|
17512
17628
|
import { createHash as createHash2 } from "crypto";
|
|
@@ -17645,7 +17761,7 @@ function checkArchitectDrift() {
|
|
|
17645
17761
|
// src/commands/architect/check.ts
|
|
17646
17762
|
var ArchitectCheckCommand = class extends M8tCommand {
|
|
17647
17763
|
static paths = [["architect-check"]];
|
|
17648
|
-
static usage =
|
|
17764
|
+
static usage = Command28.Usage({
|
|
17649
17765
|
description: "Verify the installed m8t-architect persona matches the repo source.",
|
|
17650
17766
|
details: "Compares a render-time content hash (stored in a per-persona `<name>.m8t-skill.json` sidecar, checked across every host m8t can render into \u2014 Claude Code, VS Code Copilot Chat, GitHub Copilot CLI) against a fresh hash of <repo-root>/personas/m8t-architect/persona.md. Exits 0 when they match, 1 with remediation advice when they don't. Used as a pre-flight gate by the architect persona body and as a verification step in guides/install/m8t.md.",
|
|
17651
17767
|
examples: [
|
|
@@ -17672,7 +17788,7 @@ var ArchitectCheckCommand = class extends M8tCommand {
|
|
|
17672
17788
|
// src/commands/coder/deploy.ts
|
|
17673
17789
|
init_esm2();
|
|
17674
17790
|
import * as path17 from "path";
|
|
17675
|
-
import { Command as
|
|
17791
|
+
import { Command as Command29, Option as Option27 } from "clipanion";
|
|
17676
17792
|
import { DefaultAzureCredential as DefaultAzureCredential13 } from "@azure/identity";
|
|
17677
17793
|
init_errors();
|
|
17678
17794
|
init_foundry_agent_get();
|
|
@@ -18086,7 +18202,7 @@ var DEFAULT_MODEL = "gpt-4.1-mini";
|
|
|
18086
18202
|
var NAME_RE = /^[a-z0-9-]+$/;
|
|
18087
18203
|
var CoderDeployCommand = class extends M8tCommand {
|
|
18088
18204
|
static paths = [["coder", "deploy"]];
|
|
18089
|
-
static usage =
|
|
18205
|
+
static usage = Command29.Usage({
|
|
18090
18206
|
description: "Deploy the curated coding agent as a hosted Foundry worker.",
|
|
18091
18207
|
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.",
|
|
18092
18208
|
examples: [
|
|
@@ -18095,22 +18211,22 @@ var CoderDeployCommand = class extends M8tCommand {
|
|
|
18095
18211
|
["Override the exec timeout", "$0 coder deploy my-coder --env M8T_CODER_EXEC_TIMEOUT_SECONDS=300"]
|
|
18096
18212
|
]
|
|
18097
18213
|
});
|
|
18098
|
-
name =
|
|
18099
|
-
persona =
|
|
18100
|
-
image =
|
|
18101
|
-
imageTag =
|
|
18102
|
-
size =
|
|
18103
|
-
modelDeployment =
|
|
18104
|
-
env =
|
|
18105
|
-
endpoint =
|
|
18106
|
-
subscription =
|
|
18107
|
-
output =
|
|
18108
|
-
brain =
|
|
18109
|
-
brainBranch =
|
|
18110
|
-
brainKv =
|
|
18111
|
-
allowNonReasoning =
|
|
18112
|
-
skipQuotaCheck =
|
|
18113
|
-
gatewayUrl =
|
|
18214
|
+
name = Option27.String();
|
|
18215
|
+
persona = Option27.String("--persona");
|
|
18216
|
+
image = Option27.String("--image");
|
|
18217
|
+
imageTag = Option27.String("--image-tag");
|
|
18218
|
+
size = Option27.String("--size");
|
|
18219
|
+
modelDeployment = Option27.String("--model-deployment");
|
|
18220
|
+
env = Option27.Array("--env");
|
|
18221
|
+
endpoint = Option27.String("--endpoint");
|
|
18222
|
+
subscription = Option27.String("--subscription");
|
|
18223
|
+
output = Option27.String("--output");
|
|
18224
|
+
brain = Option27.String("--brain");
|
|
18225
|
+
brainBranch = Option27.String("--branch");
|
|
18226
|
+
brainKv = Option27.String("--brain-kv");
|
|
18227
|
+
allowNonReasoning = Option27.Boolean("--allow-non-reasoning", false);
|
|
18228
|
+
skipQuotaCheck = Option27.Boolean("--skip-quota-check", false);
|
|
18229
|
+
gatewayUrl = Option27.String("--gateway-url", { description: "Base gateway URL for the a2a bridge (e.g. https://<gateway-fqdn>); enables this coder as an a2a target." });
|
|
18114
18230
|
async executeCommand() {
|
|
18115
18231
|
if (!NAME_RE.test(this.name)) {
|
|
18116
18232
|
throw new LocalCliError({
|
|
@@ -18345,13 +18461,13 @@ var CoderDeployCommand = class extends M8tCommand {
|
|
|
18345
18461
|
|
|
18346
18462
|
// src/commands/coder/teardown.ts
|
|
18347
18463
|
import { confirm as confirm4 } from "@inquirer/prompts";
|
|
18348
|
-
import { Command as
|
|
18464
|
+
import { Command as Command30, Option as Option28 } from "clipanion";
|
|
18349
18465
|
import { DefaultAzureCredential as DefaultAzureCredential14 } from "@azure/identity";
|
|
18350
18466
|
init_foundry_agents();
|
|
18351
18467
|
init_errors();
|
|
18352
18468
|
var CoderTeardownCommand = class extends M8tCommand {
|
|
18353
18469
|
static paths = [["coder", "teardown"]];
|
|
18354
|
-
static usage =
|
|
18470
|
+
static usage = Command30.Usage({
|
|
18355
18471
|
description: "Delete a deployed hosted coder (removes its container + identity + role assignment).",
|
|
18356
18472
|
details: "Idempotent: tearing down a missing coder reports 'already gone'. Only the named agent is touched. Discovery self-heals on the next worker list.",
|
|
18357
18473
|
examples: [
|
|
@@ -18359,11 +18475,11 @@ var CoderTeardownCommand = class extends M8tCommand {
|
|
|
18359
18475
|
["Skip the confirm (scripts)", "$0 coder teardown my-coder --yes"]
|
|
18360
18476
|
]
|
|
18361
18477
|
});
|
|
18362
|
-
name =
|
|
18363
|
-
yes =
|
|
18364
|
-
endpoint =
|
|
18365
|
-
subscription =
|
|
18366
|
-
output =
|
|
18478
|
+
name = Option28.String();
|
|
18479
|
+
yes = Option28.Boolean("--yes", false);
|
|
18480
|
+
endpoint = Option28.String("--endpoint");
|
|
18481
|
+
subscription = Option28.String("--subscription");
|
|
18482
|
+
output = Option28.String("--output");
|
|
18367
18483
|
async executeCommand() {
|
|
18368
18484
|
const mode = resolveOutputMode(
|
|
18369
18485
|
this.output,
|
|
@@ -18428,7 +18544,7 @@ var CoderTeardownCommand = class extends M8tCommand {
|
|
|
18428
18544
|
// src/commands/azure-exec/deploy.ts
|
|
18429
18545
|
init_esm2();
|
|
18430
18546
|
import * as path18 from "path";
|
|
18431
|
-
import { Command as
|
|
18547
|
+
import { Command as Command31, Option as Option29 } from "clipanion";
|
|
18432
18548
|
import { DefaultAzureCredential as DefaultAzureCredential15 } from "@azure/identity";
|
|
18433
18549
|
init_errors();
|
|
18434
18550
|
init_foundry_agent_get();
|
|
@@ -18490,7 +18606,7 @@ var DEFAULT_MODEL2 = "gpt-5-mini";
|
|
|
18490
18606
|
var NAME_RE2 = /^[a-z0-9-]+$/;
|
|
18491
18607
|
var AzureExecDeployCommand = class extends M8tCommand {
|
|
18492
18608
|
static paths = [["azure-exec", "deploy"]];
|
|
18493
|
-
static usage =
|
|
18609
|
+
static usage = Command31.Usage({
|
|
18494
18610
|
description: "Deploy the Azure executor as a hosted Foundry worker (az CLI + tiered ops).",
|
|
18495
18611
|
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.",
|
|
18496
18612
|
examples: [
|
|
@@ -18500,23 +18616,23 @@ var AzureExecDeployCommand = class extends M8tCommand {
|
|
|
18500
18616
|
]
|
|
18501
18617
|
]
|
|
18502
18618
|
});
|
|
18503
|
-
name =
|
|
18504
|
-
image =
|
|
18505
|
-
imageTag =
|
|
18506
|
-
size =
|
|
18507
|
-
scope =
|
|
18508
|
-
resourceGroup =
|
|
18509
|
-
modelDeployment =
|
|
18510
|
-
env =
|
|
18511
|
-
brain =
|
|
18512
|
-
kvUri =
|
|
18513
|
-
gatewayUrl =
|
|
18514
|
-
endpoint =
|
|
18515
|
-
subscription =
|
|
18516
|
-
output =
|
|
18517
|
-
skipQuotaCheck =
|
|
18518
|
-
grantAccessAdmin =
|
|
18519
|
-
enableEmail =
|
|
18619
|
+
name = Option29.String();
|
|
18620
|
+
image = Option29.String("--image");
|
|
18621
|
+
imageTag = Option29.String("--image-tag");
|
|
18622
|
+
size = Option29.String("--size");
|
|
18623
|
+
scope = Option29.String("--scope");
|
|
18624
|
+
resourceGroup = Option29.String("--resource-group");
|
|
18625
|
+
modelDeployment = Option29.String("--model-deployment");
|
|
18626
|
+
env = Option29.Array("--env");
|
|
18627
|
+
brain = Option29.String("--brain");
|
|
18628
|
+
kvUri = Option29.String("--kv-uri");
|
|
18629
|
+
gatewayUrl = Option29.String("--gateway-url");
|
|
18630
|
+
endpoint = Option29.String("--endpoint");
|
|
18631
|
+
subscription = Option29.String("--subscription");
|
|
18632
|
+
output = Option29.String("--output");
|
|
18633
|
+
skipQuotaCheck = Option29.Boolean("--skip-quota-check", false);
|
|
18634
|
+
grantAccessAdmin = Option29.Boolean("--grant-access-admin", false);
|
|
18635
|
+
enableEmail = Option29.Boolean("--enable-email", false);
|
|
18520
18636
|
async executeCommand() {
|
|
18521
18637
|
if (!NAME_RE2.test(this.name)) {
|
|
18522
18638
|
throw new LocalCliError({
|
|
@@ -18761,7 +18877,7 @@ var AzureExecDeployCommand = class extends M8tCommand {
|
|
|
18761
18877
|
};
|
|
18762
18878
|
|
|
18763
18879
|
// src/commands/platform/status.ts
|
|
18764
|
-
import { Command as
|
|
18880
|
+
import { Command as Command32, Option as Option30 } from "clipanion";
|
|
18765
18881
|
import { DefaultAzureCredential as DefaultAzureCredential16 } from "@azure/identity";
|
|
18766
18882
|
|
|
18767
18883
|
// src/lib/platform-update.ts
|
|
@@ -19958,30 +20074,30 @@ async function applyPersona(a, ctx, opts) {
|
|
|
19958
20074
|
// src/commands/platform/status.ts
|
|
19959
20075
|
var PlatformStatusCommand = class extends M8tCommand {
|
|
19960
20076
|
static paths = [["platform", "status"]];
|
|
19961
|
-
static usage =
|
|
20077
|
+
static usage = Command32.Usage({
|
|
19962
20078
|
description: "Show per-component platform drift against a release manifest.",
|
|
19963
20079
|
details: "Fetches a release manifest (the current channel by default), reads the installed-state stamp, and reports each component's installed vs target version and drift status. Read-only \u2014 never writes the stamp, never converges anything (use 'm8t platform update' for that). --verify additionally probes the live gateway (image tag + /api/version) best-effort."
|
|
19964
20080
|
});
|
|
19965
|
-
subscription =
|
|
19966
|
-
resourceGroup =
|
|
20081
|
+
subscription = Option30.String("--subscription");
|
|
20082
|
+
resourceGroup = Option30.String("--resource-group", {
|
|
19967
20083
|
description: "m8t resource group to disambiguate the gateway (multi-deployment subscriptions)."
|
|
19968
20084
|
});
|
|
19969
|
-
to =
|
|
20085
|
+
to = Option30.String("--to", {
|
|
19970
20086
|
description: "Check status against a pinned platform version (defaults to the current release channel)."
|
|
19971
20087
|
});
|
|
19972
|
-
contentDir =
|
|
20088
|
+
contentDir = Option30.String("--content-dir", {
|
|
19973
20089
|
description: "Path to a local m8t repo checkout (skips the tarball tree-SHA fetch)."
|
|
19974
20090
|
});
|
|
19975
|
-
manifestUrl =
|
|
20091
|
+
manifestUrl = Option30.String("--manifest-url", {
|
|
19976
20092
|
description: "Fetch the release manifest from this URL instead of the release channel."
|
|
19977
20093
|
});
|
|
19978
|
-
manifestFile =
|
|
20094
|
+
manifestFile = Option30.String("--manifest-file", {
|
|
19979
20095
|
description: "Read the release manifest from this local file instead of the release channel."
|
|
19980
20096
|
});
|
|
19981
|
-
verify =
|
|
20097
|
+
verify = Option30.Boolean("--verify", false, {
|
|
19982
20098
|
description: "Additionally probe the live gateway (image tag + /api/version) and report stamp-vs-live."
|
|
19983
20099
|
});
|
|
19984
|
-
output =
|
|
20100
|
+
output = Option30.String("--output");
|
|
19985
20101
|
async executeCommand() {
|
|
19986
20102
|
const mode = resolveOutputMode(
|
|
19987
20103
|
this.output,
|
|
@@ -20099,7 +20215,7 @@ var PlatformStatusCommand = class extends M8tCommand {
|
|
|
20099
20215
|
};
|
|
20100
20216
|
|
|
20101
20217
|
// src/commands/platform/update.ts
|
|
20102
|
-
import { Command as
|
|
20218
|
+
import { Command as Command33, Option as Option31 } from "clipanion";
|
|
20103
20219
|
import { confirm as confirm5 } from "@inquirer/prompts";
|
|
20104
20220
|
import { DefaultAzureCredential as DefaultAzureCredential17 } from "@azure/identity";
|
|
20105
20221
|
|
|
@@ -20742,40 +20858,40 @@ function assertCliVersionOk(manifest, runningVersion, onWarn = () => {
|
|
|
20742
20858
|
// src/commands/platform/update.ts
|
|
20743
20859
|
var PlatformUpdateCommand = class extends M8tCommand {
|
|
20744
20860
|
static paths = [["platform", "update"]];
|
|
20745
|
-
static usage =
|
|
20861
|
+
static usage = Command33.Usage({
|
|
20746
20862
|
description: "Converge the whole platform (gateway, hosted agents, personas, infra) to a release manifest.",
|
|
20747
20863
|
details: "Fetches a release manifest (the current channel by default), diffs it against the installed-state stamp, and converges each changed component via its own executor: rolls the gateway/hosted-agent images, re-versions prompt personas (compose-preserving), and records infra state. A deploy/ tree drift is reported but NOT applied unless --force-infra is passed. Use --check to preview, --only to converge a single component, --yes to skip the confirmation prompt."
|
|
20748
20864
|
});
|
|
20749
|
-
subscription =
|
|
20750
|
-
resourceGroup =
|
|
20865
|
+
subscription = Option31.String("--subscription");
|
|
20866
|
+
resourceGroup = Option31.String("--resource-group", {
|
|
20751
20867
|
description: "m8t resource group to disambiguate the gateway (multi-deployment subscriptions)."
|
|
20752
20868
|
});
|
|
20753
|
-
to =
|
|
20869
|
+
to = Option31.String("--to", {
|
|
20754
20870
|
description: "Pin the platform version to converge to (defaults to the current release channel)."
|
|
20755
20871
|
});
|
|
20756
|
-
only =
|
|
20872
|
+
only = Option31.String("--only", {
|
|
20757
20873
|
description: "Converge only one component: infra | gateway | codingAgent | azureExecutor | personas | brainSeeds."
|
|
20758
20874
|
});
|
|
20759
|
-
check =
|
|
20760
|
-
yes =
|
|
20761
|
-
skipInfra =
|
|
20762
|
-
forceInfra =
|
|
20763
|
-
suffix =
|
|
20875
|
+
check = Option31.Boolean("--check", false);
|
|
20876
|
+
yes = Option31.Boolean("--yes", false);
|
|
20877
|
+
skipInfra = Option31.Boolean("--skip-infra", false);
|
|
20878
|
+
forceInfra = Option31.Boolean("--force-infra", false);
|
|
20879
|
+
suffix = Option31.String("--suffix", {
|
|
20764
20880
|
description: "Required with --force-infra \u2014 the existing deployment's resource-name suffix (avoids provisioning duplicates)."
|
|
20765
20881
|
});
|
|
20766
|
-
contentDir =
|
|
20882
|
+
contentDir = Option31.String("--content-dir", {
|
|
20767
20883
|
description: "Path to a local m8t repo checkout (skips the tarball fetch + tree-drift check)."
|
|
20768
20884
|
});
|
|
20769
|
-
manifestUrl =
|
|
20885
|
+
manifestUrl = Option31.String("--manifest-url", {
|
|
20770
20886
|
description: "Fetch the release manifest from this URL instead of the release channel."
|
|
20771
20887
|
});
|
|
20772
|
-
manifestFile =
|
|
20888
|
+
manifestFile = Option31.String("--manifest-file", {
|
|
20773
20889
|
description: "Read the release manifest from this local file instead of the release channel."
|
|
20774
20890
|
});
|
|
20775
|
-
endpoint =
|
|
20891
|
+
endpoint = Option31.String("--endpoint", {
|
|
20776
20892
|
description: "Foundry project endpoint URL. Disambiguates the project in a multi-project subscription."
|
|
20777
20893
|
});
|
|
20778
|
-
output =
|
|
20894
|
+
output = Option31.String("--output");
|
|
20779
20895
|
async executeCommand() {
|
|
20780
20896
|
const mode = resolveOutputMode(
|
|
20781
20897
|
this.output,
|
|
@@ -20903,7 +21019,7 @@ var PlatformUpdateCommand = class extends M8tCommand {
|
|
|
20903
21019
|
};
|
|
20904
21020
|
|
|
20905
21021
|
// src/commands/platform/converge.ts
|
|
20906
|
-
import { Command as
|
|
21022
|
+
import { Command as Command34 } from "clipanion";
|
|
20907
21023
|
|
|
20908
21024
|
// src/lib/platform-converge-mi.ts
|
|
20909
21025
|
import { ManagedIdentityCredential } from "@azure/identity";
|
|
@@ -21178,7 +21294,7 @@ async function failIfStillInFlight(client, now, error) {
|
|
|
21178
21294
|
}
|
|
21179
21295
|
var PlatformConvergeCommand = class extends M8tCommand {
|
|
21180
21296
|
static paths = [["platform", "converge"]];
|
|
21181
|
-
static usage =
|
|
21297
|
+
static usage = Command34.Usage({
|
|
21182
21298
|
category: "Platform",
|
|
21183
21299
|
description: "Headless updater-job driver: claim a pending apply-request and converge the platform to it.",
|
|
21184
21300
|
details: "The Managed-Identity-authenticated entry point run by the updater Container Apps job. One invocation is one tick: it claims the pending apply-request row (if any), refuses a downgrade against the installed stamp, self-fetches and validates the target manifest, self-updates its own engine image when the manifest requires a newer CLI, then drives the converge engine behind the health-gate + auto-rollback. Reads its subscription/RG/endpoint/channel from env (MI_CLIENT_ID, SUBSCRIPTION_ID, RESOURCE_GROUP, FOUNDRY_ENDPOINT, M8T_UPDATE_CHANNEL_URL). Not intended for interactive use \u2014 the founder-facing path is 'm8t platform update'."
|
|
@@ -21394,7 +21510,7 @@ function targetManifestSource(ctx, target) {
|
|
|
21394
21510
|
|
|
21395
21511
|
// src/commands/platform/seed-stamp.ts
|
|
21396
21512
|
import { readFileSync as readFileSync17 } from "fs";
|
|
21397
|
-
import { Command as
|
|
21513
|
+
import { Command as Command35, Option as Option32 } from "clipanion";
|
|
21398
21514
|
import { DefaultAzureCredential as DefaultAzureCredential18, ManagedIdentityCredential as ManagedIdentityCredential2 } from "@azure/identity";
|
|
21399
21515
|
init_errors();
|
|
21400
21516
|
|
|
@@ -21526,15 +21642,15 @@ async function seedStamp2(args) {
|
|
|
21526
21642
|
}
|
|
21527
21643
|
var PlatformSeedStampCommand = class extends M8tCommand {
|
|
21528
21644
|
static paths = [["platform", "seed-stamp"]];
|
|
21529
|
-
static usage =
|
|
21645
|
+
static usage = Command35.Usage({
|
|
21530
21646
|
description: "INTERNAL: write the initial installed-state stamp from a build-time install descriptor.",
|
|
21531
21647
|
details: "Used by the cloud installer at the end of a from-zero install so the platform records which release it is running. Writes the stamp ONLY IF ABSENT \u2014 it never overwrites a stamp written by the converge engine, so a re-run or a container restart is harmless. Not a founder-facing command: to change what is installed, use 'm8t platform update'."
|
|
21532
21648
|
});
|
|
21533
|
-
descriptor =
|
|
21534
|
-
subscription =
|
|
21535
|
-
resourceGroup =
|
|
21536
|
-
miClientId =
|
|
21537
|
-
output =
|
|
21649
|
+
descriptor = Option32.String("--descriptor", { description: "Path to install-descriptor.json (baked into the installer image)." });
|
|
21650
|
+
subscription = Option32.String("--subscription");
|
|
21651
|
+
resourceGroup = Option32.String("--resource-group");
|
|
21652
|
+
miClientId = Option32.String("--mi-client-id", { description: "Authenticate as this user-assigned managed identity instead of the ambient credential." });
|
|
21653
|
+
output = Option32.String("--output");
|
|
21538
21654
|
async executeCommand() {
|
|
21539
21655
|
const mode = resolveOutputMode(this.output, this.context.stdout);
|
|
21540
21656
|
const need = (v, flag) => {
|
|
@@ -21566,7 +21682,7 @@ var PlatformSeedStampCommand = class extends M8tCommand {
|
|
|
21566
21682
|
};
|
|
21567
21683
|
|
|
21568
21684
|
// src/commands/platform/stamp-build.ts
|
|
21569
|
-
import { Command as
|
|
21685
|
+
import { Command as Command36, Option as Option33 } from "clipanion";
|
|
21570
21686
|
import { DefaultAzureCredential as DefaultAzureCredential19, ManagedIdentityCredential as ManagedIdentityCredential3 } from "@azure/identity";
|
|
21571
21687
|
init_errors();
|
|
21572
21688
|
|
|
@@ -21600,17 +21716,17 @@ function buildRunningBuildStamp(input) {
|
|
|
21600
21716
|
// src/commands/platform/stamp-build.ts
|
|
21601
21717
|
var PlatformStampBuildCommand = class extends M8tCommand {
|
|
21602
21718
|
static paths = [["platform", "stamp-build"]];
|
|
21603
|
-
static usage =
|
|
21719
|
+
static usage = Command36.Usage({
|
|
21604
21720
|
description: "Record the currently running build as this install's platform version.",
|
|
21605
21721
|
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."
|
|
21606
21722
|
});
|
|
21607
|
-
version =
|
|
21608
|
-
gatewayTag =
|
|
21609
|
-
gatewayDigest =
|
|
21610
|
-
subscription =
|
|
21611
|
-
resourceGroup =
|
|
21612
|
-
miClientId =
|
|
21613
|
-
output =
|
|
21723
|
+
version = Option33.String("--version", { description: "The running build's own version, bare X.Y.Z." });
|
|
21724
|
+
gatewayTag = Option33.String("--gateway-tag", { description: "The tag of the gateway image this build deployed." });
|
|
21725
|
+
gatewayDigest = Option33.String("--gateway-digest", { description: "The digest of the gateway image this build deployed." });
|
|
21726
|
+
subscription = Option33.String("--subscription");
|
|
21727
|
+
resourceGroup = Option33.String("--resource-group");
|
|
21728
|
+
miClientId = Option33.String("--mi-client-id", { description: "Authenticate as this user-assigned managed identity instead of the ambient credential." });
|
|
21729
|
+
output = Option33.String("--output");
|
|
21614
21730
|
async executeCommand() {
|
|
21615
21731
|
const mode = resolveOutputMode(this.output, this.context.stdout);
|
|
21616
21732
|
const need = (v, flag) => {
|
|
@@ -21662,7 +21778,7 @@ var PlatformStampBuildCommand = class extends M8tCommand {
|
|
|
21662
21778
|
};
|
|
21663
21779
|
|
|
21664
21780
|
// src/commands/platform/policy.ts
|
|
21665
|
-
import { Command as
|
|
21781
|
+
import { Command as Command37, Option as Option34 } from "clipanion";
|
|
21666
21782
|
import { DefaultAzureCredential as DefaultAzureCredential20, ManagedIdentityCredential as ManagedIdentityCredential4 } from "@azure/identity";
|
|
21667
21783
|
init_errors();
|
|
21668
21784
|
|
|
@@ -21718,16 +21834,16 @@ async function readPolicy(opts) {
|
|
|
21718
21834
|
// src/commands/platform/policy.ts
|
|
21719
21835
|
var PlatformPolicyCommand = class extends M8tCommand {
|
|
21720
21836
|
static paths = [["platform", "policy"]];
|
|
21721
|
-
static usage =
|
|
21837
|
+
static usage = Command37.Usage({
|
|
21722
21838
|
description: "Show or set how this install handles available platform updates.",
|
|
21723
21839
|
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.",
|
|
21724
21840
|
examples: [["Show the current mode", "m8t platform policy"], ["Never apply automatically", "m8t platform policy --set notify-only"]]
|
|
21725
21841
|
});
|
|
21726
|
-
set =
|
|
21727
|
-
subscription =
|
|
21728
|
-
resourceGroup =
|
|
21729
|
-
miClientId =
|
|
21730
|
-
output =
|
|
21842
|
+
set = Option34.String("--set", { description: "notify-only | auto-critical | auto-all" });
|
|
21843
|
+
subscription = Option34.String("--subscription");
|
|
21844
|
+
resourceGroup = Option34.String("--resource-group");
|
|
21845
|
+
miClientId = Option34.String("--mi-client-id");
|
|
21846
|
+
output = Option34.String("--output");
|
|
21731
21847
|
async executeCommand() {
|
|
21732
21848
|
const mode = resolveOutputMode(this.output, this.context.stdout);
|
|
21733
21849
|
const need = (v, flag) => {
|
|
@@ -21773,7 +21889,7 @@ var PlatformPolicyCommand = class extends M8tCommand {
|
|
|
21773
21889
|
};
|
|
21774
21890
|
|
|
21775
21891
|
// src/commands/platform/enable-cost-report.ts
|
|
21776
|
-
import { Command as
|
|
21892
|
+
import { Command as Command38, Option as Option35 } from "clipanion";
|
|
21777
21893
|
|
|
21778
21894
|
// src/lib/wire-gateway-acs.ts
|
|
21779
21895
|
init_rbac();
|
|
@@ -21813,18 +21929,18 @@ async function wireGatewayForAcs(args) {
|
|
|
21813
21929
|
init_errors();
|
|
21814
21930
|
var PlatformEnableCostReportCommand = class extends M8tCommand {
|
|
21815
21931
|
static paths = [["platform", "enable-cost-report"]];
|
|
21816
|
-
static usage =
|
|
21932
|
+
static usage = Command38.Usage({
|
|
21817
21933
|
description: "Wire the deployed gateway to send the bi-weekly cost report via ACS Email.",
|
|
21818
21934
|
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')."
|
|
21819
21935
|
});
|
|
21820
|
-
subscription =
|
|
21821
|
-
resourceGroup =
|
|
21936
|
+
subscription = Option35.String("--subscription");
|
|
21937
|
+
resourceGroup = Option35.String("--resource-group", {
|
|
21822
21938
|
description: "m8t resource group to disambiguate the gateway (multi-deployment subscriptions)."
|
|
21823
21939
|
});
|
|
21824
|
-
acsEndpoint =
|
|
21825
|
-
acsSender =
|
|
21826
|
-
acsResourceId =
|
|
21827
|
-
output =
|
|
21940
|
+
acsEndpoint = Option35.String("--acs-endpoint", { required: true, description: "ACS data-plane endpoint, e.g. https://acs-<name>.communication.azure.com/" });
|
|
21941
|
+
acsSender = Option35.String("--acs-sender", { required: true, description: "Managed-domain sender address, e.g. DoNotReply@<guid>.azurecomm.net" });
|
|
21942
|
+
acsResourceId = Option35.String("--acs-resource-id", { required: true, description: "ARM resource id of the acs-<name> Communication Service \u2014 the role-grant scope." });
|
|
21943
|
+
output = Option35.String("--output");
|
|
21828
21944
|
async executeCommand() {
|
|
21829
21945
|
const mode = resolveOutputMode(
|
|
21830
21946
|
this.output,
|
|
@@ -21898,45 +22014,45 @@ var PlatformEnableCostReportCommand = class extends M8tCommand {
|
|
|
21898
22014
|
};
|
|
21899
22015
|
|
|
21900
22016
|
// src/commands/platform/enable-auto-update.ts
|
|
21901
|
-
import { Command as
|
|
22017
|
+
import { Command as Command39, Option as Option36 } from "clipanion";
|
|
21902
22018
|
import { confirm as confirm6 } from "@inquirer/prompts";
|
|
21903
22019
|
import { DefaultAzureCredential as DefaultAzureCredential21 } from "@azure/identity";
|
|
21904
22020
|
init_errors();
|
|
21905
22021
|
var PlatformEnableAutoUpdateCommand = class extends M8tCommand {
|
|
21906
22022
|
static paths = [["platform", "enable-auto-update"]];
|
|
21907
|
-
static usage =
|
|
22023
|
+
static usage = Command39.Usage({
|
|
21908
22024
|
category: "Platform",
|
|
21909
22025
|
description: "Retrofit the auto-updater (MI + cron job + role assignments) onto an existing install.",
|
|
21910
22026
|
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."
|
|
21911
22027
|
});
|
|
21912
|
-
subscription =
|
|
21913
|
-
resourceGroup =
|
|
22028
|
+
subscription = Option36.String("--subscription");
|
|
22029
|
+
resourceGroup = Option36.String("--resource-group", {
|
|
21914
22030
|
description: "m8t resource group to disambiguate the gateway (multi-deployment subscriptions)."
|
|
21915
22031
|
});
|
|
21916
|
-
suffix =
|
|
22032
|
+
suffix = Option36.String("--suffix", {
|
|
21917
22033
|
description: "The existing deployment's resource-name suffix. Required when it cannot be recovered from system/infra-params or the live gateway."
|
|
21918
22034
|
});
|
|
21919
|
-
installerImage =
|
|
22035
|
+
installerImage = Option36.String("--installer-image", {
|
|
21920
22036
|
required: true,
|
|
21921
22037
|
description: "Updater CA-Job image ref (the converge engine at the current release). Required \u2014 an empty image would skip provisioning."
|
|
21922
22038
|
});
|
|
21923
|
-
updateCron =
|
|
22039
|
+
updateCron = Option36.String("--update-cron", {
|
|
21924
22040
|
description: "Cron schedule for the updater job (bicep default applies when omitted)."
|
|
21925
22041
|
});
|
|
21926
|
-
channelUrl =
|
|
22042
|
+
channelUrl = Option36.String("--channel-url", {
|
|
21927
22043
|
description: "Release-channel URL the updater job polls (bicep default applies when omitted)."
|
|
21928
22044
|
});
|
|
21929
|
-
location =
|
|
22045
|
+
location = Option36.String("--location", {
|
|
21930
22046
|
description: "Region for the updater identity + job. Defaults to the resource group's existing resources."
|
|
21931
22047
|
});
|
|
21932
|
-
foundryTracing =
|
|
22048
|
+
foundryTracing = Option36.String("--foundry-tracing", {
|
|
21933
22049
|
description: "project | account | skip. Pass the value the install was deployed with \u2014 omitting it lets the bicep default (project) switch tracing on."
|
|
21934
22050
|
});
|
|
21935
|
-
endpoint =
|
|
22051
|
+
endpoint = Option36.String("--endpoint", {
|
|
21936
22052
|
description: "Foundry project endpoint URL. Disambiguates the project in a multi-project subscription."
|
|
21937
22053
|
});
|
|
21938
|
-
yes =
|
|
21939
|
-
output =
|
|
22054
|
+
yes = Option36.Boolean("--yes", false);
|
|
22055
|
+
output = Option36.String("--output");
|
|
21940
22056
|
async executeCommand() {
|
|
21941
22057
|
const mode = resolveOutputMode(
|
|
21942
22058
|
this.output,
|
|
@@ -22073,7 +22189,7 @@ var PlatformEnableAutoUpdateCommand = class extends M8tCommand {
|
|
|
22073
22189
|
};
|
|
22074
22190
|
|
|
22075
22191
|
// src/commands/deploy.ts
|
|
22076
|
-
import { Command as
|
|
22192
|
+
import { Command as Command40, Option as Option37 } from "clipanion";
|
|
22077
22193
|
|
|
22078
22194
|
// src/lib/app-reg.ts
|
|
22079
22195
|
init_errors();
|
|
@@ -22321,6 +22437,17 @@ async function ensureGatewayRedirectUri(gatewayClientId, fqdn) {
|
|
|
22321
22437
|
}
|
|
22322
22438
|
await patchRedirectUris(appObjectId, fqdn);
|
|
22323
22439
|
}
|
|
22440
|
+
async function resolveAppObjectIdForWrite(opts) {
|
|
22441
|
+
if (opts.appObjectId) return opts.appObjectId;
|
|
22442
|
+
if (!opts.clientId) return null;
|
|
22443
|
+
try {
|
|
22444
|
+
return await azJson(
|
|
22445
|
+
["ad", "app", "show", "--id", opts.clientId, "--query", "id", "--output", "json"]
|
|
22446
|
+
) ?? null;
|
|
22447
|
+
} catch {
|
|
22448
|
+
return null;
|
|
22449
|
+
}
|
|
22450
|
+
}
|
|
22324
22451
|
async function patchRedirectUris(appObjectId, fqdn) {
|
|
22325
22452
|
const targetUri = `https://${fqdn}`;
|
|
22326
22453
|
const existing = await azJson(
|
|
@@ -22553,52 +22680,52 @@ function classifyWhatIf(changes) {
|
|
|
22553
22680
|
var DEFAULT_IMAGE_REF = "ghcr.io/m8t-labs/m8t:latest";
|
|
22554
22681
|
var DeployCommand = class extends M8tCommand {
|
|
22555
22682
|
static paths = [["deploy"]];
|
|
22556
|
-
static usage =
|
|
22683
|
+
static usage = Command40.Usage({
|
|
22557
22684
|
description: "Deploy (or update) the m8t gateway/webapp stack via Bicep.",
|
|
22558
22685
|
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."
|
|
22559
22686
|
});
|
|
22560
|
-
subscription =
|
|
22561
|
-
resourceGroup =
|
|
22562
|
-
location =
|
|
22563
|
-
suffix =
|
|
22564
|
-
imageRef =
|
|
22565
|
-
acrPullIdentity =
|
|
22566
|
-
acrResourceId =
|
|
22567
|
-
foundryEndpoint =
|
|
22568
|
-
foundryResourceId =
|
|
22569
|
-
foundryTracing =
|
|
22687
|
+
subscription = Option37.String("--subscription");
|
|
22688
|
+
resourceGroup = Option37.String("--resource-group", "rg-m8t-stack");
|
|
22689
|
+
location = Option37.String("--location", "eastus");
|
|
22690
|
+
suffix = Option37.String("--suffix", "");
|
|
22691
|
+
imageRef = Option37.String("--image-ref", DEFAULT_IMAGE_REF);
|
|
22692
|
+
acrPullIdentity = Option37.String("--acrpull-identity");
|
|
22693
|
+
acrResourceId = Option37.String("--acr-resource-id");
|
|
22694
|
+
foundryEndpoint = Option37.String("--foundry-endpoint");
|
|
22695
|
+
foundryResourceId = Option37.String("--foundry-resource-id");
|
|
22696
|
+
foundryTracing = Option37.String("--foundry-tracing");
|
|
22570
22697
|
// project | account | skip (bicep default: project)
|
|
22571
|
-
clientId =
|
|
22572
|
-
whatIf =
|
|
22698
|
+
clientId = Option37.String("--client-id");
|
|
22699
|
+
whatIf = Option37.Boolean("--what-if", false);
|
|
22573
22700
|
// Only meaningful with --what-if. Routes the comparison through the
|
|
22574
22701
|
// value-free renderers (see ./lib/whatif-redact.js) instead of the default
|
|
22575
22702
|
// before/after renderer. Defaults false so a local, interactive run keeps
|
|
22576
22703
|
// showing values — that is the whole diagnostic point of --what-if.
|
|
22577
22704
|
// Automation that forwards this output anywhere non-private (a CI log, an
|
|
22578
22705
|
// issue) MUST pass --redact.
|
|
22579
|
-
redact =
|
|
22580
|
-
output =
|
|
22706
|
+
redact = Option37.Boolean("--redact", false);
|
|
22707
|
+
output = Option37.String("--output");
|
|
22581
22708
|
// Subscription-scoped role assignments. Omitted ⇒ the template default (true).
|
|
22582
22709
|
// Pass false when deploying as a principal scoped to the resource group only:
|
|
22583
22710
|
// it cannot deploy at subscription scope, and those assignments persist
|
|
22584
22711
|
// idempotently from the initial deployment anyway.
|
|
22585
|
-
assignSubscriptionRoles =
|
|
22712
|
+
assignSubscriptionRoles = Option37.String("--assign-subscription-roles");
|
|
22586
22713
|
// Referee — all optional, undefined by default ⇒ the bicep defaults
|
|
22587
22714
|
// apply (dormant: gatewayCpu=0.25, gatewayMemory=0.5Gi, every referee/exam var
|
|
22588
22715
|
// empty). Only pass these when explicitly enabling the referee exam stack.
|
|
22589
|
-
gatewayCpu =
|
|
22590
|
-
gatewayMemory =
|
|
22591
|
-
refereeEnabled =
|
|
22592
|
-
refereeBrainRepos =
|
|
22593
|
-
refereeFeedRepo =
|
|
22594
|
-
refereeInstallationId =
|
|
22595
|
-
refereeWebhookHmacKvUri =
|
|
22596
|
-
examKvUri =
|
|
22597
|
-
examLaWorkspaceId =
|
|
22598
|
-
brainEvalDeployment =
|
|
22599
|
-
brainAppLogin =
|
|
22600
|
-
refereeCheckpointDir =
|
|
22601
|
-
examApiBase =
|
|
22716
|
+
gatewayCpu = Option37.String("--gateway-cpu");
|
|
22717
|
+
gatewayMemory = Option37.String("--gateway-memory");
|
|
22718
|
+
refereeEnabled = Option37.String("--referee-enabled");
|
|
22719
|
+
refereeBrainRepos = Option37.String("--referee-brain-repos");
|
|
22720
|
+
refereeFeedRepo = Option37.String("--referee-feed-repo");
|
|
22721
|
+
refereeInstallationId = Option37.String("--referee-installation-id");
|
|
22722
|
+
refereeWebhookHmacKvUri = Option37.String("--referee-webhook-hmac-kv-uri");
|
|
22723
|
+
examKvUri = Option37.String("--exam-kv-uri");
|
|
22724
|
+
examLaWorkspaceId = Option37.String("--exam-la-workspace-id");
|
|
22725
|
+
brainEvalDeployment = Option37.String("--brain-eval-deployment");
|
|
22726
|
+
brainAppLogin = Option37.String("--brain-app-login");
|
|
22727
|
+
refereeCheckpointDir = Option37.String("--referee-checkpoint-dir");
|
|
22728
|
+
examApiBase = Option37.String("--exam-api-base");
|
|
22602
22729
|
async executeCommand() {
|
|
22603
22730
|
const mode = resolveOutputMode(
|
|
22604
22731
|
this.output,
|
|
@@ -22684,9 +22811,6 @@ var DeployCommand = class extends M8tCommand {
|
|
|
22684
22811
|
}
|
|
22685
22812
|
log(this.clientId ? `using existing app reg ${this.clientId}` : "ensuring Entra app reg\u2026");
|
|
22686
22813
|
const app = await ensureAppReg({ tenantId: account.tenantId, clientId: this.clientId });
|
|
22687
|
-
if (app.appObjectId === null && this.clientId) {
|
|
22688
|
-
log(colors.dim(" (BYO app reg \u2014 skipping Graph writes; ensure it has http://localhost:3000 + the deployed FQDN as SPA redirect URIs and Expose-an-API)"));
|
|
22689
|
-
}
|
|
22690
22814
|
await writeFoundryConfig({ tenantId: app.tenantId, clientId: app.clientId, projectEndpoint: foundryEndpoint });
|
|
22691
22815
|
log(`ensuring resource group ${this.resourceGroup}\u2026`);
|
|
22692
22816
|
await ensureResourceGroup(this.resourceGroup, this.location);
|
|
@@ -22732,8 +22856,16 @@ var DeployCommand = class extends M8tCommand {
|
|
|
22732
22856
|
params,
|
|
22733
22857
|
deploymentName: `m8t-deploy-${account.subscriptionId.slice(0, 8)}`
|
|
22734
22858
|
});
|
|
22735
|
-
|
|
22736
|
-
|
|
22859
|
+
const writableAppObjectId = await resolveAppObjectIdForWrite({
|
|
22860
|
+
appObjectId: app.appObjectId,
|
|
22861
|
+
clientId: this.clientId
|
|
22862
|
+
});
|
|
22863
|
+
if (writableAppObjectId) {
|
|
22864
|
+
await patchRedirectUris(writableAppObjectId, outputs.containerAppFqdn);
|
|
22865
|
+
} else {
|
|
22866
|
+
log(colors.dim(
|
|
22867
|
+
` (could not register the sign-in redirect URI automatically \u2014 add https://${outputs.containerAppFqdn} as an SPA redirect URI on app registration ${app.clientId}, or sign-in will fail with AADSTS50011)`
|
|
22868
|
+
));
|
|
22737
22869
|
}
|
|
22738
22870
|
const webappUrl = `https://${outputs.containerAppFqdn}`;
|
|
22739
22871
|
if (mode === "json") {
|
|
@@ -22758,7 +22890,7 @@ var DeployCommand = class extends M8tCommand {
|
|
|
22758
22890
|
|
|
22759
22891
|
// src/commands/eval/skill.ts
|
|
22760
22892
|
import { spawnSync as spawnSync4 } from "child_process";
|
|
22761
|
-
import { Command as
|
|
22893
|
+
import { Command as Command41, Option as Option38 } from "clipanion";
|
|
22762
22894
|
init_errors();
|
|
22763
22895
|
var DECISIONS = /* @__PURE__ */ new Set(["promote", "reject", "needs_review"]);
|
|
22764
22896
|
var JUDGE_STATUSES = /* @__PURE__ */ new Set(["ok", "skipped", "unavailable"]);
|
|
@@ -22783,14 +22915,14 @@ function parseVerdict(stdout) {
|
|
|
22783
22915
|
}
|
|
22784
22916
|
var EvalSkillCommand = class extends M8tCommand {
|
|
22785
22917
|
static paths = [["eval", "skill"]];
|
|
22786
|
-
static usage =
|
|
22918
|
+
static usage = Command41.Usage({
|
|
22787
22919
|
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)."
|
|
22788
22920
|
});
|
|
22789
|
-
candidate =
|
|
22790
|
-
skillsDir =
|
|
22791
|
-
noJudge =
|
|
22792
|
-
deployment =
|
|
22793
|
-
output =
|
|
22921
|
+
candidate = Option38.String();
|
|
22922
|
+
skillsDir = Option38.String("--skills-dir");
|
|
22923
|
+
noJudge = Option38.Boolean("--no-judge", false);
|
|
22924
|
+
deployment = Option38.String("--deployment");
|
|
22925
|
+
output = Option38.String("--output");
|
|
22794
22926
|
executeCommand() {
|
|
22795
22927
|
return Promise.resolve(this._runCommand());
|
|
22796
22928
|
}
|
|
@@ -22849,7 +22981,7 @@ var EvalSkillCommand = class extends M8tCommand {
|
|
|
22849
22981
|
import { spawnSync as spawnSync5 } from "child_process";
|
|
22850
22982
|
import { writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, readFileSync as readFileSync18, existsSync as existsSync15, readdirSync as readdirSync2 } from "fs";
|
|
22851
22983
|
import { join as join27 } from "path";
|
|
22852
|
-
import { Command as
|
|
22984
|
+
import { Command as Command42, Option as Option39 } from "clipanion";
|
|
22853
22985
|
init_errors();
|
|
22854
22986
|
init_esm();
|
|
22855
22987
|
function parseArmToken(tok, opts) {
|
|
@@ -23079,24 +23211,24 @@ function buildPlan(args) {
|
|
|
23079
23211
|
}
|
|
23080
23212
|
var EvalExamCommand = class extends M8tCommand {
|
|
23081
23213
|
static paths = [["eval", "exam"]];
|
|
23082
|
-
static usage =
|
|
23214
|
+
static usage = Command42.Usage({
|
|
23083
23215
|
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."
|
|
23084
23216
|
});
|
|
23085
|
-
worker =
|
|
23086
|
-
arms =
|
|
23087
|
-
taskSet =
|
|
23088
|
-
examType =
|
|
23089
|
-
skill =
|
|
23090
|
-
reps =
|
|
23091
|
-
probes =
|
|
23092
|
-
pool =
|
|
23093
|
-
out =
|
|
23094
|
-
dryRun =
|
|
23095
|
-
keepArms =
|
|
23096
|
-
allowStub =
|
|
23097
|
-
deployment =
|
|
23098
|
-
output =
|
|
23099
|
-
observeWaitS =
|
|
23217
|
+
worker = Option39.String();
|
|
23218
|
+
arms = Option39.String("--arms");
|
|
23219
|
+
taskSet = Option39.String("--task-set");
|
|
23220
|
+
examType = Option39.String("--exam-type");
|
|
23221
|
+
skill = Option39.String("--skill");
|
|
23222
|
+
reps = Option39.String("-n,--reps");
|
|
23223
|
+
probes = Option39.String("--probes");
|
|
23224
|
+
pool = Option39.String("--pool");
|
|
23225
|
+
out = Option39.String("--out");
|
|
23226
|
+
dryRun = Option39.Boolean("--dry-run", false);
|
|
23227
|
+
keepArms = Option39.Boolean("--keep-arms", false);
|
|
23228
|
+
allowStub = Option39.Boolean("--allow-stub", false);
|
|
23229
|
+
deployment = Option39.String("--deployment");
|
|
23230
|
+
output = Option39.String("--output");
|
|
23231
|
+
observeWaitS = Option39.String("--observe-wait-s");
|
|
23100
23232
|
async executeCommand() {
|
|
23101
23233
|
await Promise.resolve();
|
|
23102
23234
|
const worker = typeof this.worker === "string" ? this.worker : void 0;
|
|
@@ -23211,10 +23343,10 @@ var EvalExamCommand = class extends M8tCommand {
|
|
|
23211
23343
|
};
|
|
23212
23344
|
|
|
23213
23345
|
// src/commands/version.ts
|
|
23214
|
-
import { Command as
|
|
23346
|
+
import { Command as Command43, Option as Option40 } from "clipanion";
|
|
23215
23347
|
var VersionCommand = class extends M8tCommand {
|
|
23216
23348
|
static paths = [["version"], ["--version"], ["-v"]];
|
|
23217
|
-
static usage =
|
|
23349
|
+
static usage = Command43.Usage({
|
|
23218
23350
|
description: "Print the CLI version.",
|
|
23219
23351
|
details: "Prints the m8t CLI version. With --verbose, also prints Node version and platform.",
|
|
23220
23352
|
examples: [
|
|
@@ -23222,8 +23354,8 @@ var VersionCommand = class extends M8tCommand {
|
|
|
23222
23354
|
["Print as JSON", "$0 version --output json"]
|
|
23223
23355
|
]
|
|
23224
23356
|
});
|
|
23225
|
-
output =
|
|
23226
|
-
verbose =
|
|
23357
|
+
output = Option40.String("--output", { description: "pretty | json | auto (default)" });
|
|
23358
|
+
verbose = Option40.Boolean("--verbose", false);
|
|
23227
23359
|
executeCommand() {
|
|
23228
23360
|
const mode = resolveOutputMode(
|
|
23229
23361
|
this.output ?? "auto",
|
|
@@ -23254,18 +23386,18 @@ var VersionCommand = class extends M8tCommand {
|
|
|
23254
23386
|
};
|
|
23255
23387
|
|
|
23256
23388
|
// src/commands/whoami.ts
|
|
23257
|
-
import { Command as
|
|
23389
|
+
import { Command as Command44, Option as Option41 } from "clipanion";
|
|
23258
23390
|
var WhoamiCommand = class extends M8tCommand {
|
|
23259
23391
|
static paths = [["whoami"]];
|
|
23260
|
-
static usage =
|
|
23392
|
+
static usage = Command44.Usage({
|
|
23261
23393
|
description: "Show your identity + the gateway you'll talk to. Probes the backend."
|
|
23262
23394
|
});
|
|
23263
|
-
output =
|
|
23264
|
-
verbose =
|
|
23265
|
-
subscription =
|
|
23395
|
+
output = Option41.String("--output");
|
|
23396
|
+
verbose = Option41.Boolean("--verbose", false);
|
|
23397
|
+
subscription = Option41.String("--subscription", {
|
|
23266
23398
|
description: "Azure subscription ID to discover gateway in (defaults to active az subscription)."
|
|
23267
23399
|
});
|
|
23268
|
-
resourceGroup =
|
|
23400
|
+
resourceGroup = Option41.String("--resource-group", {
|
|
23269
23401
|
description: "m8t resource group to disambiguate the gateway (multi-deployment subscriptions)."
|
|
23270
23402
|
});
|
|
23271
23403
|
async executeCommand() {
|
|
@@ -23330,7 +23462,7 @@ var WhoamiCommand = class extends M8tCommand {
|
|
|
23330
23462
|
};
|
|
23331
23463
|
|
|
23332
23464
|
// src/commands/status.ts
|
|
23333
|
-
import { Command as
|
|
23465
|
+
import { Command as Command45, Option as Option42 } from "clipanion";
|
|
23334
23466
|
|
|
23335
23467
|
// src/lib/azd.ts
|
|
23336
23468
|
init_errors();
|
|
@@ -23395,10 +23527,10 @@ async function resolveLocalContext() {
|
|
|
23395
23527
|
// src/commands/status.ts
|
|
23396
23528
|
var StatusCommand = class extends M8tCommand {
|
|
23397
23529
|
static paths = [["status"]];
|
|
23398
|
-
static usage =
|
|
23530
|
+
static usage = Command45.Usage({
|
|
23399
23531
|
description: "Show the local m8t context: identity, config.yaml, gateway cache, azd mode."
|
|
23400
23532
|
});
|
|
23401
|
-
output =
|
|
23533
|
+
output = Option42.String("--output");
|
|
23402
23534
|
async executeCommand() {
|
|
23403
23535
|
const mode = resolveOutputMode(
|
|
23404
23536
|
this.output,
|
|
@@ -23436,7 +23568,7 @@ var StatusCommand = class extends M8tCommand {
|
|
|
23436
23568
|
};
|
|
23437
23569
|
|
|
23438
23570
|
// src/commands/doctor.ts
|
|
23439
|
-
import { Command as
|
|
23571
|
+
import { Command as Command46, Option as Option43 } from "clipanion";
|
|
23440
23572
|
import { DefaultAzureCredential as DefaultAzureCredential22 } from "@azure/identity";
|
|
23441
23573
|
import * as fs26 from "fs";
|
|
23442
23574
|
import * as os11 from "os";
|
|
@@ -23712,12 +23844,12 @@ function probeLegacyStateDir() {
|
|
|
23712
23844
|
}
|
|
23713
23845
|
var DoctorCommand = class extends M8tCommand {
|
|
23714
23846
|
static paths = [["doctor"]];
|
|
23715
|
-
static usage =
|
|
23847
|
+
static usage = Command46.Usage({
|
|
23716
23848
|
description: "Diagnose the local m8t setup: az login, config.yaml, gateway, Foundry data-plane."
|
|
23717
23849
|
});
|
|
23718
|
-
output =
|
|
23719
|
-
agent =
|
|
23720
|
-
resourceGroup =
|
|
23850
|
+
output = Option43.String("--output");
|
|
23851
|
+
agent = Option43.String("--agent");
|
|
23852
|
+
resourceGroup = Option43.String("--resource-group", {
|
|
23721
23853
|
description: "m8t resource group to disambiguate the gateway (multi-deployment subscriptions)."
|
|
23722
23854
|
});
|
|
23723
23855
|
async executeCommand() {
|
|
@@ -23834,7 +23966,7 @@ var DoctorCommand = class extends M8tCommand {
|
|
|
23834
23966
|
};
|
|
23835
23967
|
|
|
23836
23968
|
// src/commands/switch.ts
|
|
23837
|
-
import { Command as
|
|
23969
|
+
import { Command as Command47, Option as Option44 } from "clipanion";
|
|
23838
23970
|
|
|
23839
23971
|
// src/lib/profiles.ts
|
|
23840
23972
|
import * as fs27 from "fs/promises";
|
|
@@ -23974,14 +24106,14 @@ async function profileSwitch(name, asName) {
|
|
|
23974
24106
|
init_errors();
|
|
23975
24107
|
var SwitchCommand = class extends M8tCommand {
|
|
23976
24108
|
static paths = [["switch"]];
|
|
23977
|
-
static usage =
|
|
24109
|
+
static usage = Command47.Usage({
|
|
23978
24110
|
description: "Re-point local config at another deployment: --subscription <id|name> (discovery) or <profile>."
|
|
23979
24111
|
});
|
|
23980
|
-
profile =
|
|
23981
|
-
subscription =
|
|
23982
|
-
list =
|
|
23983
|
-
as =
|
|
23984
|
-
output =
|
|
24112
|
+
profile = Option44.String({ required: false });
|
|
24113
|
+
subscription = Option44.String("--subscription");
|
|
24114
|
+
list = Option44.Boolean("--list", false);
|
|
24115
|
+
as = Option44.String("--as");
|
|
24116
|
+
output = Option44.String("--output");
|
|
23985
24117
|
async executeCommand() {
|
|
23986
24118
|
const mode = resolveOutputMode(
|
|
23987
24119
|
this.output,
|
|
@@ -24038,7 +24170,7 @@ var SwitchCommand = class extends M8tCommand {
|
|
|
24038
24170
|
|
|
24039
24171
|
// src/commands/open.ts
|
|
24040
24172
|
import { spawn as spawn5 } from "child_process";
|
|
24041
|
-
import { Command as
|
|
24173
|
+
import { Command as Command48, Option as Option45 } from "clipanion";
|
|
24042
24174
|
|
|
24043
24175
|
// src/lib/open-targets.ts
|
|
24044
24176
|
init_errors();
|
|
@@ -24084,14 +24216,14 @@ function openUrl(url) {
|
|
|
24084
24216
|
}
|
|
24085
24217
|
var OpenCommand = class extends M8tCommand {
|
|
24086
24218
|
static paths = [["open"]];
|
|
24087
|
-
static usage =
|
|
24219
|
+
static usage = Command48.Usage({
|
|
24088
24220
|
description: "Open the deployed webapp (default), the Foundry portal, or the resource group.",
|
|
24089
24221
|
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)."
|
|
24090
24222
|
});
|
|
24091
|
-
target =
|
|
24092
|
-
print =
|
|
24093
|
-
output =
|
|
24094
|
-
resourceGroup =
|
|
24223
|
+
target = Option45.String({ required: false });
|
|
24224
|
+
print = Option45.Boolean("--print", false);
|
|
24225
|
+
output = Option45.String("--output");
|
|
24226
|
+
resourceGroup = Option45.String("--resource-group", {
|
|
24095
24227
|
description: "m8t resource group to disambiguate the gateway (multi-deployment subscriptions)."
|
|
24096
24228
|
});
|
|
24097
24229
|
async executeCommand() {
|
|
@@ -24135,7 +24267,7 @@ var OpenCommand = class extends M8tCommand {
|
|
|
24135
24267
|
};
|
|
24136
24268
|
|
|
24137
24269
|
// src/commands/dream/run.ts
|
|
24138
|
-
import { Command as
|
|
24270
|
+
import { Command as Command49, Option as Option46 } from "clipanion";
|
|
24139
24271
|
import { AzureCliCredential } from "@azure/identity";
|
|
24140
24272
|
import { TableClient as TableClient7 } from "@azure/data-tables";
|
|
24141
24273
|
import { AIProjectClient as AIProjectClient3 } from "@azure/ai-projects";
|
|
@@ -26362,20 +26494,20 @@ function redactTranscripts(input) {
|
|
|
26362
26494
|
}
|
|
26363
26495
|
var DreamRunCommand = class extends M8tCommand {
|
|
26364
26496
|
static paths = [["dream", "run"]];
|
|
26365
|
-
static usage =
|
|
26497
|
+
static usage = Command49.Usage({
|
|
26366
26498
|
description: "Dry-run the brain consumption pipeline for one worker (no model call, no writes).",
|
|
26367
26499
|
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."
|
|
26368
26500
|
});
|
|
26369
|
-
worker =
|
|
26370
|
-
dryRun =
|
|
26371
|
-
since =
|
|
26372
|
-
reset =
|
|
26373
|
-
showTranscripts =
|
|
26501
|
+
worker = Option46.String("--worker", { description: "Worker (canonical name) to harvest. Required." });
|
|
26502
|
+
dryRun = Option46.Boolean("--dry-run", false, { description: "Read-only harvest; no model call, no writes." });
|
|
26503
|
+
since = Option46.String("--since", { description: "ISO-8601 start override (rejected if malformed or future)." });
|
|
26504
|
+
reset = Option46.Boolean("--reset", false, { description: "Ignore the stored cursor; read from the beginning." });
|
|
26505
|
+
showTranscripts = Option46.Boolean("--show-transcripts", false, {
|
|
26374
26506
|
description: "Print transcript bodies (default: metadata only)."
|
|
26375
26507
|
});
|
|
26376
|
-
subscription =
|
|
26377
|
-
endpoint =
|
|
26378
|
-
output =
|
|
26508
|
+
subscription = Option46.String("--subscription");
|
|
26509
|
+
endpoint = Option46.String("--endpoint");
|
|
26510
|
+
output = Option46.String("--output");
|
|
26379
26511
|
// Resolution seam — overridden by tests; built lazily at runtime otherwise.
|
|
26380
26512
|
deps;
|
|
26381
26513
|
async executeCommand() {
|
|
@@ -26723,7 +26855,7 @@ function defaultDeps(overrides) {
|
|
|
26723
26855
|
}
|
|
26724
26856
|
|
|
26725
26857
|
// src/commands/foundry/create.ts
|
|
26726
|
-
import { Command as
|
|
26858
|
+
import { Command as Command50, Option as Option47 } from "clipanion";
|
|
26727
26859
|
|
|
26728
26860
|
// src/lib/foundry-create.ts
|
|
26729
26861
|
init_errors();
|
|
@@ -26961,7 +27093,7 @@ async function createFoundryProject(args) {
|
|
|
26961
27093
|
init_errors();
|
|
26962
27094
|
var FoundryCreateCommand = class extends M8tCommand {
|
|
26963
27095
|
static paths = [["foundry", "create"]];
|
|
26964
|
-
static usage =
|
|
27096
|
+
static usage = Command50.Usage({
|
|
26965
27097
|
description: "Create an AI Foundry (AIServices) account + project + model deployment from scratch.",
|
|
26966
27098
|
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).",
|
|
26967
27099
|
examples: [
|
|
@@ -26970,16 +27102,16 @@ var FoundryCreateCommand = class extends M8tCommand {
|
|
|
26970
27102
|
["Higher capacity for a reasoning model", "$0 foundry create --resource-group rg-m8t-stack --location eastus2 --model gpt-5-mini --capacity 250"]
|
|
26971
27103
|
]
|
|
26972
27104
|
});
|
|
26973
|
-
resourceGroup =
|
|
26974
|
-
location =
|
|
26975
|
-
account =
|
|
26976
|
-
project =
|
|
26977
|
-
model =
|
|
26978
|
-
modelVersion =
|
|
26979
|
-
capacity =
|
|
26980
|
-
subscription =
|
|
26981
|
-
skipQuotaCheck =
|
|
26982
|
-
output =
|
|
27105
|
+
resourceGroup = Option47.String("--resource-group");
|
|
27106
|
+
location = Option47.String("--location");
|
|
27107
|
+
account = Option47.String("--account");
|
|
27108
|
+
project = Option47.String("--project", "m8t");
|
|
27109
|
+
model = Option47.String("--model", "gpt-4.1-mini");
|
|
27110
|
+
modelVersion = Option47.String("--model-version", "2025-04-14");
|
|
27111
|
+
capacity = Option47.String("--capacity", "50");
|
|
27112
|
+
subscription = Option47.String("--subscription");
|
|
27113
|
+
skipQuotaCheck = Option47.Boolean("--skip-quota-check", false);
|
|
27114
|
+
output = Option47.String("--output");
|
|
26983
27115
|
async executeCommand() {
|
|
26984
27116
|
const mode = resolveOutputMode(
|
|
26985
27117
|
this.output,
|
|
@@ -27051,22 +27183,22 @@ var FoundryCreateCommand = class extends M8tCommand {
|
|
|
27051
27183
|
};
|
|
27052
27184
|
|
|
27053
27185
|
// src/commands/foundry/await-ready.ts
|
|
27054
|
-
import { Command as
|
|
27186
|
+
import { Command as Command51, Option as Option48 } from "clipanion";
|
|
27055
27187
|
import { AzureCliCredential as AzureCliCredential2 } from "@azure/identity";
|
|
27056
27188
|
init_errors();
|
|
27057
27189
|
var FoundryAwaitReadyCommand = class extends M8tCommand {
|
|
27058
27190
|
static paths = [["foundry", "await-ready"]];
|
|
27059
|
-
static usage =
|
|
27191
|
+
static usage = Command51.Usage({
|
|
27060
27192
|
description: "Wait until a freshly-created Foundry project's data plane reliably serves it.",
|
|
27061
27193
|
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.",
|
|
27062
27194
|
examples: [["Wait for a project to be ready", "$0 foundry await-ready --endpoint https://acc.services.ai.azure.com/api/projects/m8t"]]
|
|
27063
27195
|
});
|
|
27064
|
-
endpoint =
|
|
27065
|
-
consecutive =
|
|
27066
|
-
attempts =
|
|
27067
|
-
interval =
|
|
27068
|
-
subscription =
|
|
27069
|
-
output =
|
|
27196
|
+
endpoint = Option48.String("--endpoint");
|
|
27197
|
+
consecutive = Option48.String("--consecutive", "3");
|
|
27198
|
+
attempts = Option48.String("--attempts", "60");
|
|
27199
|
+
interval = Option48.String("--interval", "5");
|
|
27200
|
+
subscription = Option48.String("--subscription");
|
|
27201
|
+
output = Option48.String("--output");
|
|
27070
27202
|
async executeCommand() {
|
|
27071
27203
|
const mode = resolveOutputMode(this.output, this.context.stdout);
|
|
27072
27204
|
const endpoint = typeof this.endpoint === "string" ? this.endpoint : void 0;
|
|
@@ -27100,7 +27232,7 @@ var FoundryAwaitReadyCommand = class extends M8tCommand {
|
|
|
27100
27232
|
};
|
|
27101
27233
|
|
|
27102
27234
|
// src/commands/bootstrap/preflight.ts
|
|
27103
|
-
import { Command as
|
|
27235
|
+
import { Command as Command52, Option as Option49 } from "clipanion";
|
|
27104
27236
|
|
|
27105
27237
|
// ../../packages/telemetry-contract/artifact/tier-map.ts
|
|
27106
27238
|
var EVENT_TIERS = {
|
|
@@ -27116,8 +27248,12 @@ var EVENT_TIERS = {
|
|
|
27116
27248
|
};
|
|
27117
27249
|
var EVENT_ENUM = Object.keys(EVENT_TIERS);
|
|
27118
27250
|
|
|
27251
|
+
// ../../packages/telemetry-contract/artifact/cadence.ts
|
|
27252
|
+
var HEARTBEAT_CADENCE_MS = 3 * 60 * 60 * 1e3;
|
|
27253
|
+
var HEARTBEAT_CADENCE_HOURS = HEARTBEAT_CADENCE_MS / (60 * 60 * 1e3);
|
|
27254
|
+
|
|
27119
27255
|
// ../../packages/telemetry-contract/src/disclosure.ts
|
|
27120
|
-
var DISCLOSURE_TIER1 = "Operational data. To support your installation, m8t receives limited operational data linked to it \u2014 installation and update events, installed versions, and service health signals. Your installation is identified only by a random installation ID we generate at setup \u2014 an opaque value with no information encoded in it. No name, email, company, or subscription information is sent in the enrollment record unless you explicitly choose to share contact details for support. At enrollment, we also verify a cloud identity token to confirm the request comes from a real cloud account; that token names the account making the request, and is otherwise discarded immediately and never stored. This is service data used only to operate and support the platform; it contains none of your content. Details: TELEMETRY.md.";
|
|
27256
|
+
var DISCLOSURE_TIER1 = "Operational data. To support your installation, m8t receives limited operational data linked to it \u2014 installation and update events, installed versions, and service health signals. Your installation is identified only by a random installation ID we generate at setup \u2014 an opaque value with no information encoded in it. No name, email, company, or subscription information is sent in the enrollment record unless you explicitly choose to share contact details for support. At enrollment, we also verify a cloud identity token to confirm the request comes from a real cloud account; that token names the account making the request, and is otherwise discarded immediately and never stored. This is service data used only to operate and support the platform; it contains none of your content. After setup, you can turn this off in the web app's Settings, under Privacy; update checks keep working. Details: TELEMETRY.md.";
|
|
27121
27257
|
|
|
27122
27258
|
// ../../packages/telemetry-contract/src/endpoints.ts
|
|
27123
27259
|
var INGEST_BASE_URL = (process.env.M8T_INGEST_BASE_URL ?? "").trim() || "https://m8t-admin.wonderfuldesert-721e332f.eastus2.azurecontainerapps.io";
|
|
@@ -27211,7 +27347,7 @@ function buildPreflightBanner(who) {
|
|
|
27211
27347
|
// src/commands/bootstrap/preflight.ts
|
|
27212
27348
|
var BootstrapPreflightCommand = class extends M8tCommand {
|
|
27213
27349
|
static paths = [["bootstrap", "preflight"]];
|
|
27214
|
-
static usage =
|
|
27350
|
+
static usage = Command52.Usage({
|
|
27215
27351
|
description: "Loudly verify you can install m8t (Owner/UAA + directory admin) and hard-stop if not.",
|
|
27216
27352
|
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.",
|
|
27217
27353
|
examples: [
|
|
@@ -27219,8 +27355,8 @@ var BootstrapPreflightCommand = class extends M8tCommand {
|
|
|
27219
27355
|
["BYO app registration (directory guests)", "$0 bootstrap preflight --client-id <appId>"]
|
|
27220
27356
|
]
|
|
27221
27357
|
});
|
|
27222
|
-
clientId =
|
|
27223
|
-
subscription =
|
|
27358
|
+
clientId = Option49.String("--client-id");
|
|
27359
|
+
subscription = Option49.String("--subscription");
|
|
27224
27360
|
async executeCommand() {
|
|
27225
27361
|
const clientId = typeof this.clientId === "string" ? this.clientId : void 0;
|
|
27226
27362
|
const account = await getAzAccount();
|
|
@@ -27283,7 +27419,7 @@ ${colors.error(" " + why)}
|
|
|
27283
27419
|
import * as fs30 from "fs";
|
|
27284
27420
|
import * as os14 from "os";
|
|
27285
27421
|
import * as path32 from "path";
|
|
27286
|
-
import { Command as
|
|
27422
|
+
import { Command as Command53, Option as Option50 } from "clipanion";
|
|
27287
27423
|
init_errors();
|
|
27288
27424
|
|
|
27289
27425
|
// src/lib/bootstrap-mi.ts
|
|
@@ -27387,6 +27523,7 @@ function buildAciCreateArgs(s) {
|
|
|
27387
27523
|
];
|
|
27388
27524
|
if (s.gatewayImageRef) env.push(`GATEWAY_IMAGE_REF=${s.gatewayImageRef}`);
|
|
27389
27525
|
if (s.foundryTracing) env.push(`FOUNDRY_TRACING=${s.foundryTracing}`);
|
|
27526
|
+
if (s.skipBrains) env.push("SKIP_BRAINS=true");
|
|
27390
27527
|
if (s.updateChannelUrl) env.push(`M8T_UPDATE_CHANNEL_URL=${s.updateChannelUrl}`);
|
|
27391
27528
|
if (s.enrollContactEmail) env.push(`M8T_ENROLL_CONTACT_EMAIL=${s.enrollContactEmail}`);
|
|
27392
27529
|
if (s.enrollCompany) env.push(`M8T_ENROLL_COMPANY=${s.enrollCompany}`);
|
|
@@ -27622,15 +27759,36 @@ function buildOccupiedRefusal(args) {
|
|
|
27622
27759
|
].join("\n");
|
|
27623
27760
|
}
|
|
27624
27761
|
|
|
27762
|
+
// src/lib/bootstrap-launch-guards.ts
|
|
27763
|
+
function buildMissingCredsRefusal(credsPath) {
|
|
27764
|
+
return `
|
|
27765
|
+
${colors.error("\u2717")} No GitHub App credentials found at ${colors.field(credsPath)}.
|
|
27766
|
+
Your workers' brains are private repositories created through that App, so the install
|
|
27767
|
+
needs it before it starts.
|
|
27768
|
+
|
|
27769
|
+
${colors.hint("fix:")} m8t brain app-create --org <org>
|
|
27770
|
+
|
|
27771
|
+
`;
|
|
27772
|
+
}
|
|
27773
|
+
function buildOrgMismatchRefusal(args) {
|
|
27774
|
+
return `
|
|
27775
|
+
${colors.error("\u2717")} The GitHub App on disk is installed on ${colors.field(args.recorded)}, but this launch asked for ${colors.field(args.requested)}.
|
|
27776
|
+
Brains would land in ${args.recorded}, not ${args.requested}.
|
|
27777
|
+
|
|
27778
|
+
${colors.hint("fix:")} m8t brain app-create --org ${args.requested}
|
|
27779
|
+
|
|
27780
|
+
`;
|
|
27781
|
+
}
|
|
27782
|
+
|
|
27625
27783
|
// src/commands/bootstrap/launch.ts
|
|
27626
27784
|
var DEFAULT_RG = "rg-m8t-stack";
|
|
27627
27785
|
var DEFAULT_INSTALLER = "ghcr.io/m8t-labs/m8t-installer";
|
|
27628
|
-
var DEFAULT_INSTALLER_TAG = "v0.1.
|
|
27786
|
+
var DEFAULT_INSTALLER_TAG = "v0.1.44";
|
|
27629
27787
|
var ACI_NAME = "m8t-installer";
|
|
27630
27788
|
var MI_NAME = "m8t-installer-mi";
|
|
27631
27789
|
var BootstrapLaunchCommand = class extends M8tCommand {
|
|
27632
27790
|
static paths = [["bootstrap", "launch"]];
|
|
27633
|
-
static usage =
|
|
27791
|
+
static usage = Command53.Usage({
|
|
27634
27792
|
description: "Create + authorize the installer managed identity, then kick the cloud installer.",
|
|
27635
27793
|
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`.",
|
|
27636
27794
|
examples: [
|
|
@@ -27641,24 +27799,26 @@ var BootstrapLaunchCommand = class extends M8tCommand {
|
|
|
27641
27799
|
["Share a support contact", "$0 bootstrap launch --location eastus2 --contact-email you@example.com --company 'Acme'"]
|
|
27642
27800
|
]
|
|
27643
27801
|
});
|
|
27644
|
-
location =
|
|
27645
|
-
resourceGroup =
|
|
27646
|
-
clientId =
|
|
27647
|
-
subscription =
|
|
27648
|
-
installerTag =
|
|
27802
|
+
location = Option50.String("--location");
|
|
27803
|
+
resourceGroup = Option50.String("--resource-group");
|
|
27804
|
+
clientId = Option50.String("--client-id");
|
|
27805
|
+
subscription = Option50.String("--subscription");
|
|
27806
|
+
installerTag = Option50.String("--installer-tag");
|
|
27649
27807
|
// Full image ref override (registry + repo + tag) — an escape hatch when the
|
|
27650
27808
|
// default org/tag is wrong for the current CLI (e.g. a stale published build).
|
|
27651
27809
|
// Wins over --installer-tag / the pinned default.
|
|
27652
|
-
installerImage =
|
|
27653
|
-
gatewayImageRef =
|
|
27654
|
-
githubAppCreds =
|
|
27655
|
-
contactEmail =
|
|
27656
|
-
company =
|
|
27810
|
+
installerImage = Option50.String("--installer-image");
|
|
27811
|
+
gatewayImageRef = Option50.String("--gateway-image-ref");
|
|
27812
|
+
githubAppCreds = Option50.String("--github-app-creds");
|
|
27813
|
+
contactEmail = Option50.String("--contact-email", { description: "Share a contact email with m8t support. Not sent unless you pass it." });
|
|
27814
|
+
company = Option50.String("--company", { description: "Share your company name with m8t support. Not sent unless you pass it." });
|
|
27657
27815
|
// Value-carrying on purpose: a bare --force would be cargo-culted into
|
|
27658
27816
|
// runbooks and harness prompts and erode the protection, whereas a faithful
|
|
27659
27817
|
// paste can never accidentally carry the victim group's name. It AUTHORIZES
|
|
27660
27818
|
// the target; --resource-group is what CHOOSES it.
|
|
27661
|
-
reinstallInto =
|
|
27819
|
+
reinstallInto = Option50.String("--reinstall-into", { description: "Consent to installing into --resource-group even though it already holds resources. Must match the target group's name." });
|
|
27820
|
+
org = Option50.String("--org", { description: "Assert the GitHub App on disk is installed on this org; refuses on a mismatch." });
|
|
27821
|
+
noBrains = Option50.Boolean("--no-brains", false, { description: "Install without brain-backed workers. For test and CI rigs; the supported install creates brains." });
|
|
27662
27822
|
async executeCommand() {
|
|
27663
27823
|
const location = typeof this.location === "string" ? this.location : void 0;
|
|
27664
27824
|
if (!location) {
|
|
@@ -27698,8 +27858,19 @@ var BootstrapLaunchCommand = class extends M8tCommand {
|
|
|
27698
27858
|
return 0;
|
|
27699
27859
|
}
|
|
27700
27860
|
const credsPath = typeof this.githubAppCreds === "string" ? this.githubAppCreds : path32.join(os14.homedir(), ".m8t", "github-app.json");
|
|
27861
|
+
const skipBrains = this.noBrains === true;
|
|
27862
|
+
const requestedOrg = typeof this.org === "string" ? this.org : void 0;
|
|
27701
27863
|
let githubApp;
|
|
27702
|
-
if (
|
|
27864
|
+
if (skipBrains) {
|
|
27865
|
+
out("installing without brain-backed workers; no GitHub App credentials will be used");
|
|
27866
|
+
} else if (!fs30.existsSync(credsPath)) {
|
|
27867
|
+
this.context.stderr.write(buildMissingCredsRefusal(credsPath));
|
|
27868
|
+
throw new LocalCliError({
|
|
27869
|
+
code: "GITHUB_APP_CREDS_MISSING",
|
|
27870
|
+
message: `No GitHub App credentials at ${credsPath}.`,
|
|
27871
|
+
hint: "Run `m8t brain app-create --org <org>` first."
|
|
27872
|
+
});
|
|
27873
|
+
} else {
|
|
27703
27874
|
let parsed;
|
|
27704
27875
|
try {
|
|
27705
27876
|
parsed = JSON.parse(fs30.readFileSync(credsPath, "utf8"));
|
|
@@ -27710,6 +27881,14 @@ var BootstrapLaunchCommand = class extends M8tCommand {
|
|
|
27710
27881
|
hint: "Run `m8t brain app-create --org <org>` to regenerate."
|
|
27711
27882
|
});
|
|
27712
27883
|
}
|
|
27884
|
+
if (requestedOrg !== void 0 && requestedOrg.toLowerCase() !== parsed.org.toLowerCase()) {
|
|
27885
|
+
this.context.stderr.write(buildOrgMismatchRefusal({ requested: requestedOrg, recorded: parsed.org }));
|
|
27886
|
+
throw new LocalCliError({
|
|
27887
|
+
code: "GITHUB_APP_ORG_MISMATCH",
|
|
27888
|
+
message: `GitHub App creds are for '${parsed.org}', but --org named '${requestedOrg}'.`,
|
|
27889
|
+
hint: `Run \`m8t brain app-create --org ${requestedOrg}\` first.`
|
|
27890
|
+
});
|
|
27891
|
+
}
|
|
27713
27892
|
let pem;
|
|
27714
27893
|
try {
|
|
27715
27894
|
pem = fs30.readFileSync(parsed.pemPath, "utf8");
|
|
@@ -27727,9 +27906,11 @@ var BootstrapLaunchCommand = class extends M8tCommand {
|
|
|
27727
27906
|
installationId: parsed.installationId,
|
|
27728
27907
|
pemB64: Buffer.from(pem).toString("base64")
|
|
27729
27908
|
};
|
|
27909
|
+
const stillInstalled = await findValidBrainApp(credsPath, parsed.org);
|
|
27910
|
+
if (stillInstalled === null) {
|
|
27911
|
+
out(`warning: could not confirm the GitHub App is still installed on ${parsed.org} - continuing`);
|
|
27912
|
+
}
|
|
27730
27913
|
out(`threading GitHub App creds for org ${parsed.org} (app ${parsed.appId})\u2026`);
|
|
27731
|
-
} else {
|
|
27732
|
-
out(`no GitHub App creds found at ${credsPath} \u2014 skipping (brain workers will not be deployed; run \`m8t brain app-create --org <org>\` first if you want them)`);
|
|
27733
27914
|
}
|
|
27734
27915
|
out("registering Microsoft.ContainerInstance\u2026");
|
|
27735
27916
|
await registerContainerInstance(subscriptionId);
|
|
@@ -27773,6 +27954,7 @@ var BootstrapLaunchCommand = class extends M8tCommand {
|
|
|
27773
27954
|
gatewayImageRef,
|
|
27774
27955
|
foundryTracing: "skip",
|
|
27775
27956
|
githubApp,
|
|
27957
|
+
...skipBrains ? { skipBrains: true } : {},
|
|
27776
27958
|
// Opt-in only. The signed-in UPN was previously seeded here automatically;
|
|
27777
27959
|
// an installation is identified by its random instance id, and contact
|
|
27778
27960
|
// details are sent only when the operator asks for them.
|
|
@@ -27790,7 +27972,7 @@ var BootstrapLaunchCommand = class extends M8tCommand {
|
|
|
27790
27972
|
};
|
|
27791
27973
|
|
|
27792
27974
|
// src/commands/bootstrap/status.ts
|
|
27793
|
-
import { Command as
|
|
27975
|
+
import { Command as Command54, Option as Option51 } from "clipanion";
|
|
27794
27976
|
init_errors();
|
|
27795
27977
|
|
|
27796
27978
|
// src/lib/bootstrap-aci-state.ts
|
|
@@ -27818,13 +28000,13 @@ async function getAciState(opts) {
|
|
|
27818
28000
|
// src/commands/bootstrap/status.ts
|
|
27819
28001
|
var BootstrapStatusCommand = class extends M8tCommand {
|
|
27820
28002
|
static paths = [["bootstrap", "status"]];
|
|
27821
|
-
static usage =
|
|
28003
|
+
static usage = Command54.Usage({
|
|
27822
28004
|
description: "Show the cloud installer's live status (phase, progress, result).",
|
|
27823
28005
|
details: "Reads the durable status blob written by the installer. --watch polls until the install reaches done or failed.",
|
|
27824
28006
|
examples: [["One read", "$0 bootstrap status"], ["Watch to completion", "$0 bootstrap status --watch"]]
|
|
27825
28007
|
});
|
|
27826
|
-
watch =
|
|
27827
|
-
output =
|
|
28008
|
+
watch = Option51.Boolean("--watch", false);
|
|
28009
|
+
output = Option51.String("--output");
|
|
27828
28010
|
async executeCommand() {
|
|
27829
28011
|
const state = await readBootstrapState();
|
|
27830
28012
|
if (!state) {
|
|
@@ -27846,6 +28028,20 @@ var BootstrapStatusCommand = class extends M8tCommand {
|
|
|
27846
28028
|
doc = await readStatusBlob({ saName: state.statusSaName, resourceGroup: state.resourceGroup, subscriptionId: state.subscriptionId });
|
|
27847
28029
|
} catch (e) {
|
|
27848
28030
|
if (watch && e instanceof LocalCliError && e.code === "BOOTSTRAP_STATUS_UNREADABLE") {
|
|
28031
|
+
const early = await getAciState({
|
|
28032
|
+
aciName: state.aciName,
|
|
28033
|
+
resourceGroup: state.resourceGroup,
|
|
28034
|
+
subscriptionId: state.subscriptionId
|
|
28035
|
+
}).catch(() => null);
|
|
28036
|
+
if (early?.terminated) {
|
|
28037
|
+
this.context.stderr.write(
|
|
28038
|
+
` ${colors.error("\u2717")} the installer container has terminated (exit ${String(early.exitCode ?? "?")}) and never reported a status.
|
|
28039
|
+
${colors.hint("inspect:")} az container logs -n ${state.aciName} -g ${state.resourceGroup}
|
|
28040
|
+
${colors.hint("reap:")} m8t bootstrap reap --force
|
|
28041
|
+
`
|
|
28042
|
+
);
|
|
28043
|
+
return 1;
|
|
28044
|
+
}
|
|
27849
28045
|
if (mode === "pretty") this.context.stderr.write(` ${colors.dim("waiting for the installer to start\u2026")}
|
|
27850
28046
|
`);
|
|
27851
28047
|
await sleep5(1e4);
|
|
@@ -27895,7 +28091,7 @@ function formatStatus(d) {
|
|
|
27895
28091
|
}
|
|
27896
28092
|
|
|
27897
28093
|
// src/commands/bootstrap/reap.ts
|
|
27898
|
-
import { Command as
|
|
28094
|
+
import { Command as Command55, Option as Option52 } from "clipanion";
|
|
27899
28095
|
init_errors();
|
|
27900
28096
|
|
|
27901
28097
|
// src/lib/bootstrap-reap.ts
|
|
@@ -27989,14 +28185,14 @@ async function reapInstaller(opts) {
|
|
|
27989
28185
|
// src/commands/bootstrap/reap.ts
|
|
27990
28186
|
var BootstrapReapCommand = class extends M8tCommand {
|
|
27991
28187
|
static paths = [["bootstrap", "reap"]];
|
|
27992
|
-
static usage =
|
|
28188
|
+
static usage = Command55.Usage({
|
|
27993
28189
|
description: "Tear down the installer scaffolding (ACI \u2192 MI \u2192 its role assignments) after a successful install.",
|
|
27994
28190
|
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.",
|
|
27995
28191
|
examples: [["Reap after done", "$0 bootstrap reap"]]
|
|
27996
28192
|
});
|
|
27997
|
-
force =
|
|
27998
|
-
sweepOrphans =
|
|
27999
|
-
yes =
|
|
28193
|
+
force = Option52.Boolean("--force", false);
|
|
28194
|
+
sweepOrphans = Option52.Boolean("--sweep-orphans", false);
|
|
28195
|
+
yes = Option52.Boolean("--yes", false);
|
|
28000
28196
|
async executeCommand() {
|
|
28001
28197
|
if (this.sweepOrphans === true) {
|
|
28002
28198
|
const { subscriptionId: sub } = await getAzAccount();
|
|
@@ -28093,7 +28289,7 @@ Found ${String(total)} orphaned assignment(s) (${breakdown}) (dry-run). ${colors
|
|
|
28093
28289
|
import * as fs31 from "fs/promises";
|
|
28094
28290
|
import * as os16 from "os";
|
|
28095
28291
|
import * as path34 from "path";
|
|
28096
|
-
import { Command as
|
|
28292
|
+
import { Command as Command56, Option as Option53 } from "clipanion";
|
|
28097
28293
|
init_errors();
|
|
28098
28294
|
|
|
28099
28295
|
// src/lib/company-profile-seed.ts
|
|
@@ -29058,14 +29254,14 @@ function renderInstallSummary(args) {
|
|
|
29058
29254
|
// src/commands/bootstrap/finish.ts
|
|
29059
29255
|
var BootstrapFinishCommand = class extends M8tCommand {
|
|
29060
29256
|
static paths = [["bootstrap", "finish"]];
|
|
29061
|
-
static usage =
|
|
29257
|
+
static usage = Command56.Usage({
|
|
29062
29258
|
description: "Point your local tools at the now-live platform (repo-root marker, discovery cache, next steps).",
|
|
29063
29259
|
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 intake \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.",
|
|
29064
29260
|
examples: [["Finish local", "$0 bootstrap finish --repo-root /path/to/m8t"]]
|
|
29065
29261
|
});
|
|
29066
|
-
repoRoot =
|
|
29067
|
-
subscription =
|
|
29068
|
-
resourceGroup =
|
|
29262
|
+
repoRoot = Option53.String("--repo-root");
|
|
29263
|
+
subscription = Option53.String("--subscription");
|
|
29264
|
+
resourceGroup = Option53.String("--resource-group");
|
|
29069
29265
|
async executeCommand() {
|
|
29070
29266
|
const state = await readBootstrapState();
|
|
29071
29267
|
if (!state) {
|
|
@@ -29168,7 +29364,7 @@ ${colors.field("Then open a brand new chat/session")} \u2014 new skills + MCP se
|
|
|
29168
29364
|
import * as fs33 from "fs";
|
|
29169
29365
|
import * as os18 from "os";
|
|
29170
29366
|
import * as path36 from "path";
|
|
29171
|
-
import { Command as
|
|
29367
|
+
import { Command as Command57, Option as Option54 } from "clipanion";
|
|
29172
29368
|
import { DefaultAzureCredential as DefaultAzureCredential23 } from "@azure/identity";
|
|
29173
29369
|
init_errors();
|
|
29174
29370
|
|
|
@@ -29976,7 +30172,7 @@ function renderDeployFailure(error) {
|
|
|
29976
30172
|
}
|
|
29977
30173
|
var BootstrapUiCommand = class extends M8tCommand {
|
|
29978
30174
|
static paths = [["bootstrap", "ui"]];
|
|
29979
|
-
static usage =
|
|
30175
|
+
static usage = Command57.Usage({
|
|
29980
30176
|
description: "Deploy Azzy + start the local onboarding chat UI in the background (returns immediately).",
|
|
29981
30177
|
details: [
|
|
29982
30178
|
"Run after `m8t bootstrap launch`, in parallel with `status --watch`. Waits for the cloud",
|
|
@@ -29997,16 +30193,16 @@ var BootstrapUiCommand = class extends M8tCommand {
|
|
|
29997
30193
|
["Experimental: start the voice relay (no effect on the text-only intake)", "$0 bootstrap ui --repo-root /path/to/m8t --voice"]
|
|
29998
30194
|
]
|
|
29999
30195
|
});
|
|
30000
|
-
repoRoot =
|
|
30001
|
-
port =
|
|
30002
|
-
endpoint =
|
|
30196
|
+
repoRoot = Option54.String("--repo-root");
|
|
30197
|
+
port = Option54.String("--port", "3000");
|
|
30198
|
+
endpoint = Option54.String("--endpoint", {
|
|
30003
30199
|
description: "Foundry project endpoint to target \u2014 disambiguates when the subscription has multiple projects."
|
|
30004
30200
|
});
|
|
30005
|
-
prepOnly =
|
|
30006
|
-
skipInstall =
|
|
30007
|
-
stop =
|
|
30008
|
-
foreground =
|
|
30009
|
-
voice =
|
|
30201
|
+
prepOnly = Option54.Boolean("--prep-only", false);
|
|
30202
|
+
skipInstall = Option54.Boolean("--skip-install", false);
|
|
30203
|
+
stop = Option54.Boolean("--stop", false);
|
|
30204
|
+
foreground = Option54.Boolean("--foreground", false);
|
|
30205
|
+
voice = Option54.Boolean("--voice", false, {
|
|
30010
30206
|
description: "Experimental: when serving, starts the voice relay and writes the intake voice env var. The onboarding intake is text-only and is unaffected by this flag \u2014 no voice worker is registered for it."
|
|
30011
30207
|
});
|
|
30012
30208
|
async executeCommand() {
|
|
@@ -30168,10 +30364,10 @@ var BootstrapUiCommand = class extends M8tCommand {
|
|
|
30168
30364
|
};
|
|
30169
30365
|
|
|
30170
30366
|
// src/commands/bootstrap/seed-profile.ts
|
|
30171
|
-
import { Command as
|
|
30367
|
+
import { Command as Command58, Option as Option55 } from "clipanion";
|
|
30172
30368
|
var BootstrapSeedProfileCommand = class extends M8tCommand {
|
|
30173
30369
|
static paths = [["bootstrap", "seed-profile"]];
|
|
30174
|
-
static usage =
|
|
30370
|
+
static usage = Command58.Usage({
|
|
30175
30371
|
description: "Seed your advisors' brains with the founder + company profile from the onboarding intake.",
|
|
30176
30372
|
details: "Reads the latest onboarding 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 finishes the intake.",
|
|
30177
30373
|
examples: [
|
|
@@ -30179,11 +30375,11 @@ var BootstrapSeedProfileCommand = class extends M8tCommand {
|
|
|
30179
30375
|
["Wait for the founder to finish", "$0 bootstrap seed-profile --watch"]
|
|
30180
30376
|
]
|
|
30181
30377
|
});
|
|
30182
|
-
endpoint =
|
|
30183
|
-
brain =
|
|
30184
|
-
watch =
|
|
30185
|
-
timeout =
|
|
30186
|
-
githubAppCreds =
|
|
30378
|
+
endpoint = Option55.String("--endpoint", { description: "Override the Foundry endpoint (else read from the install status)." });
|
|
30379
|
+
brain = Option55.String("--brain", { description: "Seed only this one brain repo, instead of both <org>/stacey-brain and <org>/azzy-brain." });
|
|
30380
|
+
watch = Option55.Boolean("--watch", false, { description: "Poll until the intake completes (or --timeout)." });
|
|
30381
|
+
timeout = Option55.String("--timeout", { description: "Watch timeout in minutes (default 20)." });
|
|
30382
|
+
githubAppCreds = Option55.String("--github-app-creds");
|
|
30187
30383
|
async executeCommand() {
|
|
30188
30384
|
const ctx = await resolveSeedContext({
|
|
30189
30385
|
endpointOverride: typeof this.endpoint === "string" ? this.endpoint : void 0,
|
|
@@ -30246,7 +30442,7 @@ var BootstrapSeedProfileCommand = class extends M8tCommand {
|
|
|
30246
30442
|
import * as fs34 from "fs";
|
|
30247
30443
|
import * as os19 from "os";
|
|
30248
30444
|
import * as path37 from "path";
|
|
30249
|
-
import { Command as
|
|
30445
|
+
import { Command as Command59, Option as Option56 } from "clipanion";
|
|
30250
30446
|
init_errors();
|
|
30251
30447
|
|
|
30252
30448
|
// src/lib/telemetry-enroll.ts
|
|
@@ -30328,7 +30524,7 @@ async function resolveKeyVaultName(containerAppResourceId) {
|
|
|
30328
30524
|
}
|
|
30329
30525
|
var TelemetryEnrollCommand = class extends M8tCommand {
|
|
30330
30526
|
static paths = [["telemetry", "enroll"]];
|
|
30331
|
-
static usage =
|
|
30527
|
+
static usage = Command59.Usage({
|
|
30332
30528
|
description: "Enroll this installation for operational telemetry (pre-existing installs).",
|
|
30333
30529
|
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.",
|
|
30334
30530
|
examples: [
|
|
@@ -30336,11 +30532,11 @@ var TelemetryEnrollCommand = class extends M8tCommand {
|
|
|
30336
30532
|
["Enroll and share a support contact", "$0 telemetry enroll --contact-email you@example.com --company 'Acme'"]
|
|
30337
30533
|
]
|
|
30338
30534
|
});
|
|
30339
|
-
company =
|
|
30340
|
-
contactEmail =
|
|
30341
|
-
subscription =
|
|
30342
|
-
resourceGroup =
|
|
30343
|
-
force =
|
|
30535
|
+
company = Option56.String("--company", { description: "Share your company name with m8t support. Not sent unless you pass it." });
|
|
30536
|
+
contactEmail = Option56.String("--contact-email", { description: "Share a contact email with m8t support. Not sent unless you pass it." });
|
|
30537
|
+
subscription = Option56.String("--subscription", { description: "Azure subscription id used to find your deployment. Never sent to m8t." });
|
|
30538
|
+
resourceGroup = Option56.String("--resource-group", { description: "Resource group to disambiguate discovery, if you have more than one m8t deployment." });
|
|
30539
|
+
force = Option56.Boolean("--force", false, { description: "Enroll even when a key is already stored. Use only when m8t support asks you to." });
|
|
30344
30540
|
async executeCommand() {
|
|
30345
30541
|
const account = await getAzAccount();
|
|
30346
30542
|
const subscriptionId = (typeof this.subscription === "string" ? this.subscription : void 0) ?? account.subscriptionId;
|
|
@@ -30421,6 +30617,7 @@ cli.register(BrainCheckAppCommand);
|
|
|
30421
30617
|
cli.register(BrainCreateCommand);
|
|
30422
30618
|
cli.register(BrainLinkCommand);
|
|
30423
30619
|
cli.register(BrainListCommand);
|
|
30620
|
+
cli.register(BrainOrgsCommand);
|
|
30424
30621
|
cli.register(BrainShowCommand);
|
|
30425
30622
|
cli.register(BrainUnlinkCommand);
|
|
30426
30623
|
cli.register(ArchitectCheckCommand);
|