@m8t-stack/cli 0.2.34 → 0.2.35
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 +64 -49
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1247,7 +1247,7 @@ var init_enable_hosted_brain = __esm({
|
|
|
1247
1247
|
import { Builtins, Cli } from "clipanion";
|
|
1248
1248
|
|
|
1249
1249
|
// src/lib/package-version.ts
|
|
1250
|
-
var CLI_VERSION = "0.2.
|
|
1250
|
+
var CLI_VERSION = "0.2.35";
|
|
1251
1251
|
|
|
1252
1252
|
// src/lib/render-error.ts
|
|
1253
1253
|
init_errors();
|
|
@@ -1444,6 +1444,7 @@ var BACKEND_RULES = [
|
|
|
1444
1444
|
var LOCAL_RULES = {
|
|
1445
1445
|
AGENT_CREATE_VERSION_FAILED: "Re-run with `--verbose` for the full response body.",
|
|
1446
1446
|
AGENT_CREATE_VERSION_NO_VERSION: "Foundry returned 2xx but no version \u2014 likely an API regression. Re-try; if it persists, file an issue.",
|
|
1447
|
+
AGENT_ENDPOINT_AUTH_PATCH_FAILED: "Re-run with `--verbose` for the full response body.",
|
|
1447
1448
|
AGENT_GET_FAILED: "Re-run with `--verbose` for the full response body.",
|
|
1448
1449
|
AGENT_NOT_FOUND: "Use `m8t brain create <name>` to create the worker first, OR run `m8t deploy <name>` to register an existing agent.",
|
|
1449
1450
|
AGENT_REDEPLOY_FAILED: "Re-run with `--verbose` for the full response body.",
|
|
@@ -13917,8 +13918,27 @@ ${text.slice(0, 500)}` });
|
|
|
13917
13918
|
}
|
|
13918
13919
|
const data = await res.json();
|
|
13919
13920
|
if (!data.version) throw new LocalCliError({ code: "AGENT_CREATE_VERSION_NO_VERSION", message: "createVersion returned no version" });
|
|
13921
|
+
await ensureAgentEndpointEntraIsolation(
|
|
13922
|
+
{ credential: args.credential, projectEndpoint: args.projectEndpoint, agentName: args.agentName, extraHeaders: args.extraHeaders },
|
|
13923
|
+
fetchImpl
|
|
13924
|
+
);
|
|
13920
13925
|
return data.version;
|
|
13921
13926
|
}
|
|
13927
|
+
async function ensureAgentEndpointEntraIsolation(args, fetchImpl = fetch) {
|
|
13928
|
+
const token = await args.credential.getToken(FOUNDRY_DATA_SCOPE);
|
|
13929
|
+
if (!token?.token) throw new LocalCliError({ code: "FOUNDRY_AUTH", message: "Could not acquire Foundry data-plane token" });
|
|
13930
|
+
const url = `${args.projectEndpoint}/agents/${args.agentName}?api-version=v1`;
|
|
13931
|
+
const res = await fetchImpl(url, {
|
|
13932
|
+
method: "PATCH",
|
|
13933
|
+
headers: { Authorization: `Bearer ${token.token}`, "Content-Type": "application/json", ...args.extraHeaders ?? {} },
|
|
13934
|
+
body: JSON.stringify({ agent_endpoint: { authorization_schemes: [{ type: "Entra", isolation_key_source: { kind: "Entra" } }] } })
|
|
13935
|
+
});
|
|
13936
|
+
if (!res.ok) {
|
|
13937
|
+
const text = await res.text();
|
|
13938
|
+
throw new LocalCliError({ code: "AGENT_ENDPOINT_AUTH_PATCH_FAILED", message: `PATCH ${url}: HTTP ${res.status.toString()}
|
|
13939
|
+
${text.slice(0, 500)}` });
|
|
13940
|
+
}
|
|
13941
|
+
}
|
|
13922
13942
|
|
|
13923
13943
|
// src/lib/brain-link.ts
|
|
13924
13944
|
init_brain_yaml_mirror();
|
|
@@ -15223,7 +15243,6 @@ import * as os5 from "os";
|
|
|
15223
15243
|
import * as path11 from "path";
|
|
15224
15244
|
init_foundry_agent_get();
|
|
15225
15245
|
var FOUNDRY_ARM_API2 = "2025-04-01-preview";
|
|
15226
|
-
var FOUNDRY_DATA_SCOPE2 = "https://ai.azure.com/.default";
|
|
15227
15246
|
var ARM_SCOPE5 = "https://management.azure.com/.default";
|
|
15228
15247
|
var GITHUB_APP_API = "https://api.github.com";
|
|
15229
15248
|
async function unlinkBrain(args) {
|
|
@@ -15309,10 +15328,6 @@ function parseBrainMeta(raw) {
|
|
|
15309
15328
|
}
|
|
15310
15329
|
}
|
|
15311
15330
|
async function createBrainStrippedVersion(args) {
|
|
15312
|
-
const fndToken = await args.credential.getToken(FOUNDRY_DATA_SCOPE2);
|
|
15313
|
-
if (!fndToken?.token) {
|
|
15314
|
-
throw new LocalCliError({ code: "FOUNDRY_AUTH", message: "Could not acquire Foundry data-plane token" });
|
|
15315
|
-
}
|
|
15316
15331
|
const otherTools = (args.currentDefinition.tools ?? []).filter(
|
|
15317
15332
|
(t) => !(t.type === "mcp" && t.server_label === "brain")
|
|
15318
15333
|
);
|
|
@@ -15325,28 +15340,13 @@ async function createBrainStrippedVersion(args) {
|
|
|
15325
15340
|
...args.currentMetadata,
|
|
15326
15341
|
brain: ""
|
|
15327
15342
|
};
|
|
15328
|
-
|
|
15329
|
-
|
|
15330
|
-
|
|
15331
|
-
|
|
15332
|
-
|
|
15343
|
+
return createAgentVersion({
|
|
15344
|
+
credential: args.credential,
|
|
15345
|
+
projectEndpoint: args.projectEndpoint,
|
|
15346
|
+
agentName: args.agentName,
|
|
15347
|
+
definition,
|
|
15348
|
+
metadata
|
|
15333
15349
|
});
|
|
15334
|
-
if (!res.ok) {
|
|
15335
|
-
const text = await res.text();
|
|
15336
|
-
throw new LocalCliError({
|
|
15337
|
-
code: "AGENT_CREATE_VERSION_FAILED",
|
|
15338
|
-
message: `POST ${url}: HTTP ${res.status.toString()}
|
|
15339
|
-
${text.slice(0, 500)}`
|
|
15340
|
-
});
|
|
15341
|
-
}
|
|
15342
|
-
const data = await res.json();
|
|
15343
|
-
if (!data.version) {
|
|
15344
|
-
throw new LocalCliError({
|
|
15345
|
-
code: "AGENT_REDEPLOY_NO_VERSION",
|
|
15346
|
-
message: "createVersion returned no version"
|
|
15347
|
-
});
|
|
15348
|
-
}
|
|
15349
|
-
return data.version;
|
|
15350
15350
|
}
|
|
15351
15351
|
async function deleteConnection(args) {
|
|
15352
15352
|
const armToken = await args.credential.getToken(ARM_SCOPE5);
|
|
@@ -25668,7 +25668,7 @@ var EVENT_TIERS = {
|
|
|
25668
25668
|
var EVENT_ENUM = Object.keys(EVENT_TIERS);
|
|
25669
25669
|
|
|
25670
25670
|
// ../../packages/telemetry-contract/src/disclosure.ts
|
|
25671
|
-
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
|
|
25671
|
+
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.";
|
|
25672
25672
|
|
|
25673
25673
|
// ../../packages/telemetry-contract/src/endpoints.ts
|
|
25674
25674
|
var INGEST_BASE_URL = (process.env.M8T_INGEST_BASE_URL ?? "").trim() || "https://m8t-admin.wonderfuldesert-721e332f.eastus2.azurecontainerapps.io";
|
|
@@ -25928,6 +25928,7 @@ function buildAciCreateArgs(s) {
|
|
|
25928
25928
|
if (s.foundryTracing) env.push(`FOUNDRY_TRACING=${s.foundryTracing}`);
|
|
25929
25929
|
if (s.updateChannelUrl) env.push(`M8T_UPDATE_CHANNEL_URL=${s.updateChannelUrl}`);
|
|
25930
25930
|
if (s.enrollContactEmail) env.push(`M8T_ENROLL_CONTACT_EMAIL=${s.enrollContactEmail}`);
|
|
25931
|
+
if (s.enrollCompany) env.push(`M8T_ENROLL_COMPANY=${s.enrollCompany}`);
|
|
25931
25932
|
if (s.githubApp) {
|
|
25932
25933
|
const g = s.githubApp;
|
|
25933
25934
|
env.push(
|
|
@@ -26078,7 +26079,7 @@ async function writeBootstrapState(state, home = os13.homedir()) {
|
|
|
26078
26079
|
// src/commands/bootstrap/launch.ts
|
|
26079
26080
|
var DEFAULT_RG = "rg-m8t-stack";
|
|
26080
26081
|
var DEFAULT_INSTALLER = "ghcr.io/m8t-labs/m8t-installer";
|
|
26081
|
-
var DEFAULT_INSTALLER_TAG = "v0.1.
|
|
26082
|
+
var DEFAULT_INSTALLER_TAG = "v0.1.41";
|
|
26082
26083
|
var ACI_NAME = "m8t-installer";
|
|
26083
26084
|
var MI_NAME = "m8t-installer-mi";
|
|
26084
26085
|
var BootstrapLaunchCommand = class extends M8tCommand {
|
|
@@ -26090,7 +26091,8 @@ var BootstrapLaunchCommand = class extends M8tCommand {
|
|
|
26090
26091
|
["Launch in eastus2", "$0 bootstrap launch --location eastus2"],
|
|
26091
26092
|
["BYO app registration", "$0 bootstrap launch --location eastus2 --client-id <appId>"],
|
|
26092
26093
|
["Pin a specific installer tag", "$0 bootstrap launch --location eastus2 --installer-tag v0.1.33"],
|
|
26093
|
-
["Override the full installer image ref", "$0 bootstrap launch --location eastus2 --installer-image ghcr.io/m8t-labs/m8t-installer:v0.1.33"]
|
|
26094
|
+
["Override the full installer image ref", "$0 bootstrap launch --location eastus2 --installer-image ghcr.io/m8t-labs/m8t-installer:v0.1.33"],
|
|
26095
|
+
["Share a support contact", "$0 bootstrap launch --location eastus2 --contact-email you@example.com --company 'Acme'"]
|
|
26094
26096
|
]
|
|
26095
26097
|
});
|
|
26096
26098
|
location = Option47.String("--location");
|
|
@@ -26104,6 +26106,8 @@ var BootstrapLaunchCommand = class extends M8tCommand {
|
|
|
26104
26106
|
installerImage = Option47.String("--installer-image");
|
|
26105
26107
|
gatewayImageRef = Option47.String("--gateway-image-ref");
|
|
26106
26108
|
githubAppCreds = Option47.String("--github-app-creds");
|
|
26109
|
+
contactEmail = Option47.String("--contact-email", { description: "Share a contact email with m8t support. Not sent unless you pass it." });
|
|
26110
|
+
company = Option47.String("--company", { description: "Share your company name with m8t support. Not sent unless you pass it." });
|
|
26107
26111
|
async executeCommand() {
|
|
26108
26112
|
const location = typeof this.location === "string" ? this.location : void 0;
|
|
26109
26113
|
if (!location) {
|
|
@@ -26195,7 +26199,11 @@ var BootstrapLaunchCommand = class extends M8tCommand {
|
|
|
26195
26199
|
gatewayImageRef,
|
|
26196
26200
|
foundryTracing: "skip",
|
|
26197
26201
|
githubApp,
|
|
26198
|
-
|
|
26202
|
+
// Opt-in only. The signed-in UPN was previously seeded here automatically;
|
|
26203
|
+
// an installation is identified by its random instance id, and contact
|
|
26204
|
+
// details are sent only when the operator asks for them.
|
|
26205
|
+
...typeof this.contactEmail === "string" ? { enrollContactEmail: this.contactEmail } : {},
|
|
26206
|
+
...typeof this.company === "string" ? { enrollCompany: this.company } : {},
|
|
26199
26207
|
...process.env.M8T_UPDATE_CHANNEL_URL ? { updateChannelUrl: process.env.M8T_UPDATE_CHANNEL_URL } : {}
|
|
26200
26208
|
});
|
|
26201
26209
|
this.context.stdout.write(
|
|
@@ -28040,13 +28048,13 @@ async function enroll(args) {
|
|
|
28040
28048
|
const url = args.baseUrl ? `${args.baseUrl.replace(/\/+$/, "")}/api/ingest/enroll` : ingestUrl("/api/ingest/enroll");
|
|
28041
28049
|
const retryDelayMs = args.retryDelayMs ?? 1e3;
|
|
28042
28050
|
const token = await (args.tokenImpl ?? defaultToken)().catch(() => null);
|
|
28043
|
-
const
|
|
28044
|
-
|
|
28045
|
-
|
|
28046
|
-
|
|
28047
|
-
|
|
28048
|
-
|
|
28049
|
-
|
|
28051
|
+
const payload = { schemaVersion: 1 };
|
|
28052
|
+
const company = args.company?.trim();
|
|
28053
|
+
if (company) payload.company = company;
|
|
28054
|
+
const contactEmail = args.contactEmail?.trim();
|
|
28055
|
+
if (contactEmail) payload.contactEmail = contactEmail;
|
|
28056
|
+
payload.proof = token ? { type: "entra-jwt", token } : null;
|
|
28057
|
+
const body = JSON.stringify(payload);
|
|
28050
28058
|
let res;
|
|
28051
28059
|
for (let attempt = 1; attempt <= 3; attempt++) {
|
|
28052
28060
|
try {
|
|
@@ -28099,19 +28107,22 @@ var TelemetryEnrollCommand = class extends M8tCommand {
|
|
|
28099
28107
|
static paths = [["telemetry", "enroll"]];
|
|
28100
28108
|
static usage = Command56.Usage({
|
|
28101
28109
|
description: "Enroll this installation for operational telemetry (pre-existing installs).",
|
|
28102
|
-
details: "
|
|
28103
|
-
examples: [
|
|
28110
|
+
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.",
|
|
28111
|
+
examples: [
|
|
28112
|
+
["Enroll", "$0 telemetry enroll"],
|
|
28113
|
+
["Enroll and share a support contact", "$0 telemetry enroll --contact-email you@example.com --company 'Acme'"]
|
|
28114
|
+
]
|
|
28104
28115
|
});
|
|
28105
|
-
company = Option53.String("--company", { description: "
|
|
28106
|
-
contactEmail = Option53.String("--contact-email", { description: "
|
|
28107
|
-
subscription = Option53.String("--subscription", { description: "Azure subscription id
|
|
28116
|
+
company = Option53.String("--company", { description: "Share your company name with m8t support. Not sent unless you pass it." });
|
|
28117
|
+
contactEmail = Option53.String("--contact-email", { description: "Share a contact email with m8t support. Not sent unless you pass it." });
|
|
28118
|
+
subscription = Option53.String("--subscription", { description: "Azure subscription id used to find your deployment. Never sent to m8t." });
|
|
28108
28119
|
resourceGroup = Option53.String("--resource-group", { description: "Resource group to disambiguate discovery, if you have more than one m8t deployment." });
|
|
28109
|
-
force = Option53.Boolean("--force", false, { description: "
|
|
28120
|
+
force = Option53.Boolean("--force", false, { description: "Enroll even when a key is already stored. Use only when m8t support asks you to." });
|
|
28110
28121
|
async executeCommand() {
|
|
28111
28122
|
const account = await getAzAccount();
|
|
28112
28123
|
const subscriptionId = (typeof this.subscription === "string" ? this.subscription : void 0) ?? account.subscriptionId;
|
|
28113
|
-
const contactEmail =
|
|
28114
|
-
const company =
|
|
28124
|
+
const contactEmail = typeof this.contactEmail === "string" ? this.contactEmail : void 0;
|
|
28125
|
+
const company = typeof this.company === "string" ? this.company : void 0;
|
|
28115
28126
|
const d = await discoverGateway({
|
|
28116
28127
|
subscriptionId,
|
|
28117
28128
|
interactive: false,
|
|
@@ -28127,14 +28138,18 @@ var TelemetryEnrollCommand = class extends M8tCommand {
|
|
|
28127
28138
|
existing = "";
|
|
28128
28139
|
}
|
|
28129
28140
|
if (existing.trim()) {
|
|
28141
|
+
const wantedContact = contactEmail !== void 0 || company !== void 0;
|
|
28130
28142
|
throw new LocalCliError({
|
|
28131
28143
|
code: "TELEMETRY_ALREADY_ENROLLED",
|
|
28132
|
-
message: "This installation is already enrolled.",
|
|
28133
|
-
hint: "
|
|
28144
|
+
message: wantedContact ? "This installation is already enrolled, so contact details can't be attached from here." : "This installation is already enrolled.",
|
|
28145
|
+
hint: "To add or change the contact details on your record, reach out through the channels in SUPPORT.md and we'll update it for you."
|
|
28134
28146
|
});
|
|
28135
28147
|
}
|
|
28136
28148
|
}
|
|
28137
|
-
const { instanceId, ingestKey } = await enroll({
|
|
28149
|
+
const { instanceId, ingestKey } = await enroll({
|
|
28150
|
+
...company ? { company } : {},
|
|
28151
|
+
...contactEmail ? { contactEmail } : {}
|
|
28152
|
+
});
|
|
28138
28153
|
const keyDir = fs34.mkdtempSync(path37.join(os19.tmpdir(), "m8t-ingest-key-"));
|
|
28139
28154
|
const keyFile = path37.join(keyDir, "key");
|
|
28140
28155
|
try {
|