@m8t-stack/cli 0.2.79 → 0.2.81
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 +453 -114
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -229,9 +229,19 @@ var init_agent_roster = __esm({
|
|
|
229
229
|
});
|
|
230
230
|
|
|
231
231
|
// ../../packages/api-contract/dist/esm/ui-directive.js
|
|
232
|
+
var DECISION_REFUSAL_REASONS, decisionRefusalReasons;
|
|
232
233
|
var init_ui_directive = __esm({
|
|
233
234
|
"../../packages/api-contract/dist/esm/ui-directive.js"() {
|
|
234
235
|
"use strict";
|
|
236
|
+
DECISION_REFUSAL_REASONS = {
|
|
237
|
+
/** 409 — no live call with that `callId`. Answered twice, or talked past and dismissed. */
|
|
238
|
+
notPending: "decision_not_pending",
|
|
239
|
+
/** 400 — decisions are a prompt-worker surface; a hosted worker raises none. */
|
|
240
|
+
invalidAgent: "invalid_decision_agent",
|
|
241
|
+
/** 400 — the `data-ui-result` payload is malformed or its option is out of range. */
|
|
242
|
+
invalidResult: "invalid_decision_result"
|
|
243
|
+
};
|
|
244
|
+
decisionRefusalReasons = Object.values(DECISION_REFUSAL_REASONS);
|
|
235
245
|
}
|
|
236
246
|
});
|
|
237
247
|
|
|
@@ -1390,7 +1400,7 @@ var init_enable_hosted_brain = __esm({
|
|
|
1390
1400
|
import { Builtins, Cli } from "clipanion";
|
|
1391
1401
|
|
|
1392
1402
|
// src/lib/package-version.ts
|
|
1393
|
-
var CLI_VERSION = "0.2.
|
|
1403
|
+
var CLI_VERSION = "0.2.81";
|
|
1394
1404
|
|
|
1395
1405
|
// src/lib/render-error.ts
|
|
1396
1406
|
init_errors();
|
|
@@ -15005,14 +15015,14 @@ function tryResolveRepoRoot() {
|
|
|
15005
15015
|
const root = fs5.readFileSync(marker, "utf8").trim();
|
|
15006
15016
|
return root.length > 0 ? root : null;
|
|
15007
15017
|
}
|
|
15008
|
-
function assertPlatformCheckout(repoRoot, operation, needs = ["personas"]) {
|
|
15018
|
+
function assertPlatformCheckout(repoRoot, operation, needs = ["personas"], overrides = {}) {
|
|
15009
15019
|
const missing = needs.filter((d) => !fs5.existsSync(path6.join(repoRoot, d)));
|
|
15010
15020
|
if (missing.length === 0) return;
|
|
15011
15021
|
const isAgentRepo = fs5.existsSync(path6.join(repoRoot, "agent", "persona.md"));
|
|
15012
15022
|
throw new LocalCliError({
|
|
15013
15023
|
code: "PLATFORM_CHECKOUT_REQUIRED",
|
|
15014
|
-
message: `${operation} needs a platform checkout, but ~/.m8t/repo-root points at '${repoRoot}', which has no ${missing.join("/ or ")}/.` + (isAgentRepo ? " That path is the agent repository \u2014 it carries the install runbook, not the platform." : ""),
|
|
15015
|
-
hint: "This operation reads platform content that is not published today, so it is maintainer-side for now. Your installation still updates itself: the auto-update rail applies published releases without needing any checkout."
|
|
15024
|
+
message: `${operation} needs a platform checkout, but ${overrides.source ?? "~/.m8t/repo-root"} points at '${repoRoot}', which has no ${missing.join("/ or ")}/.` + (isAgentRepo ? " That path is the agent repository \u2014 it carries the install runbook, not the platform." : ""),
|
|
15025
|
+
hint: overrides.hint ?? "This operation reads platform content that is not published today, so it is maintainer-side for now. Your installation still updates itself: the auto-update rail applies published releases without needing any checkout."
|
|
15016
15026
|
});
|
|
15017
15027
|
}
|
|
15018
15028
|
function resolvePlatformRepoRoot(operation, needs) {
|
|
@@ -26621,13 +26631,66 @@ import { TableClient as TableClient7 } from "@azure/data-tables";
|
|
|
26621
26631
|
import { AIProjectClient as AIProjectClient3 } from "@azure/ai-projects";
|
|
26622
26632
|
import { LogsQueryClient as LogsQueryClient3, LogsQueryResultStatus as LogsQueryResultStatus3 } from "@azure/monitor-query";
|
|
26623
26633
|
|
|
26634
|
+
// ../../packages/agent-ledger/dist/esm/pii.js
|
|
26635
|
+
import { createHmac } from "crypto";
|
|
26636
|
+
var EMAIL_PLACEHOLDER = "[email]";
|
|
26637
|
+
var PHONE_PLACEHOLDER = "[phone]";
|
|
26638
|
+
var SECRET_PLACEHOLDER = "[secret]";
|
|
26639
|
+
var PEM_BLOCK_RE = /-----BEGIN [A-Z0-9 ]{0,32}PRIVATE KEY-----[\s\S]*?-----END [A-Z0-9 ]{0,32}PRIVATE KEY-----/g;
|
|
26640
|
+
var JWT_RE = /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{6,}(?:\.[A-Za-z0-9_-]{10,})?/g;
|
|
26641
|
+
var HTTP_CREDENTIAL_RE = /\b(Bearer|Basic)[ \t]+(?=[A-Za-z0-9._~+/=-]{0,80}[0-9+/=])[A-Za-z0-9._~+/=-]{16,}/gi;
|
|
26642
|
+
var KNOWN_PREFIX_RE = /(?<![A-Za-z0-9_-])(?:sk-[A-Za-z0-9_-]{16,}|rk-[A-Za-z0-9_-]{16,}|xox[a-z]-[A-Za-z0-9-]{10,}|gh[pousr]_[A-Za-z0-9]{16,}|github_pat_[A-Za-z0-9_]{20,}|glpat-[A-Za-z0-9_-]{20,}|npm_[A-Za-z0-9]{28,}|AKIA[0-9A-Z]{16}|ASIA[0-9A-Z]{16}|AIza[0-9A-Za-z_-]{35}|ya29\.[A-Za-z0-9_-]{20,}|dckr_pat_[A-Za-z0-9_-]{20,}|shp(?:at|ca|pa|ss)_[a-fA-F0-9]{32,})(?![A-Za-z0-9_-])/g;
|
|
26643
|
+
var KEYED_VALUE = `("[^"\\n]{8,}"|'[^'\\n]{8,}'|(?=[A-Za-z0-9+/=_.~%-]{0,64}[0-9+/=])[A-Za-z0-9+/=_.~%-]{8,})`;
|
|
26644
|
+
var KEYED_STRONG_SECRET_RE = new RegExp(`(?<![A-Za-z0-9])(shared[_-]?access[_-]?key|account[_-]?key|access[_-]?key|storage[_-]?key|api[_-]?key|apikey|x[_-]?api[_-]?key|client[_-]?secret|sas[_-]?token|access[_-]?token|refresh[_-]?token|auth[_-]?token|id[_-]?token|bot[_-]?token|private[_-]?key|password|passwd|pwd)(["']?\\s*[:=]\\s*)("[^"\\n]{8,}"|'[^'\\n]{8,}'|[A-Za-z0-9+/=_.~%-]{8,})`, "gi");
|
|
26645
|
+
var KEYED_WEAK_SECRET_RE = new RegExp(`(?<![A-Za-z0-9])(authorization|secret|token|sig)(["']?\\s*[:=]\\s*)` + KEYED_VALUE, "gi");
|
|
26646
|
+
var TELEGRAM_BOT_TOKEN_RE = /(?<!\d)\d{8,10}:AA[A-Za-z0-9_-]{32,34}(?![A-Za-z0-9_-])/g;
|
|
26647
|
+
var SPOKEN_SECRET_RE = /\b((?:password|passcode|passphrase|api[ _-]?key|access code|pin(?: code)?)\s+is[ \t:]+)(?=\S{0,32}[0-9])\S{4,64}/gi;
|
|
26648
|
+
var SPOKEN_PASSWORD_RE = /\b((?:password|passcode|passphrase)\s+is[ \t:]+)(?!\[)(?!(?:wrong|incorrect|invalid|expired|required|missing|reset|unchanged|correct|secure|weak|strong|blank|empty|not|now|still|too|the|already|also|only|just|being|getting)\b)("[^"\n]{4,64}"|'[^'\n]{4,64}'|\S{4,64})/gi;
|
|
26649
|
+
var B64ISH_RE = /(?<![A-Za-z0-9+=_-])(?=[A-Za-z0-9+=_-]{0,64}[A-Z])(?=[A-Za-z0-9+=_-]{0,64}[a-z])(?=[A-Za-z0-9+=_-]{0,64}[0-9])[A-Za-z0-9+=_-]{40,}(?![A-Za-z0-9+=_-])/g;
|
|
26650
|
+
var EMAIL_RE = new RegExp("[\\p{L}\\p{N}._%+-]+@[\\p{L}\\p{N}](?:[\\p{L}\\p{N}.-]*[\\p{L}\\p{N}])?\\.\\p{L}{2,}(?![\\p{L}\\p{N}-])", "gu");
|
|
26651
|
+
var PHONE_INTL_RE = /(?<![\d/.-])\+\d{1,3}(?:[ .-]?\(\d{1,4}\))?(?:[ .-]?\d){6,12}(?!\d)/g;
|
|
26652
|
+
var PHONE_SEP_RE = /(?<![\d.-])(?:\d[ .-])?(?:\(\d{3}\)[ .-]?\d{3}[ .-]?\d{4}|\d{3}[ .-]\d{3}[ .-]\d{4}|0\d{1,2}[ .-]\d{7})(?![\d-])/g;
|
|
26653
|
+
var PHONE_CONTEXT_RE = /\b((?:call|text|dial|whatsapp)(?:\s+(?:me|us|him|her|them|back))?(?:\s+(?:at|on))?\s*[:-]?\s*|(?:phone|mobile|cell|tel)(?:\s*(?:number|no\.?))?\s*(?:is|:)?\s*)(?<![\d.(-])\d{7,15}(?![\d.])/gi;
|
|
26654
|
+
var PEM_OPEN_RE = /-----BEGIN [A-Z0-9 ]{0,32}PRIVATE KEY-----/;
|
|
26655
|
+
var UNCLOSED_QUOTED_SECRET_RE = /(?<![A-Za-z0-9])(?:shared[_-]?access[_-]?key|account[_-]?key|access[_-]?key|storage[_-]?key|api[_-]?key|apikey|x[_-]?api[_-]?key|client[_-]?secret|sas[_-]?token|access[_-]?token|refresh[_-]?token|auth[_-]?token|id[_-]?token|bot[_-]?token|private[_-]?key|password|passwd|pwd|authorization|secret|token|sig)["']?\s*[:=]\s*["'][^"'\n]*$/i;
|
|
26656
|
+
function failClosedOnCutConstructs(text) {
|
|
26657
|
+
const pem = PEM_OPEN_RE.exec(text);
|
|
26658
|
+
if (pem && !/-----END [A-Z0-9 ]{0,32}PRIVATE KEY-----/.test(text.slice(pem.index))) {
|
|
26659
|
+
return text.slice(0, pem.index) + SECRET_PLACEHOLDER;
|
|
26660
|
+
}
|
|
26661
|
+
const quoted = UNCLOSED_QUOTED_SECRET_RE.exec(text);
|
|
26662
|
+
if (quoted)
|
|
26663
|
+
return text.slice(0, quoted.index) + SECRET_PLACEHOLDER;
|
|
26664
|
+
return text;
|
|
26665
|
+
}
|
|
26666
|
+
function maskSecrets(text) {
|
|
26667
|
+
const masked = text.replace(PEM_BLOCK_RE, SECRET_PLACEHOLDER).replace(JWT_RE, SECRET_PLACEHOLDER).replace(HTTP_CREDENTIAL_RE, (_, scheme) => `${scheme} ${SECRET_PLACEHOLDER}`).replace(KNOWN_PREFIX_RE, SECRET_PLACEHOLDER).replace(TELEGRAM_BOT_TOKEN_RE, SECRET_PLACEHOLDER).replace(KEYED_STRONG_SECRET_RE, (_, key2, sep4) => `${key2}${sep4}${SECRET_PLACEHOLDER}`).replace(KEYED_WEAK_SECRET_RE, (_, key2, sep4) => `${key2}${sep4}${SECRET_PLACEHOLDER}`).replace(SPOKEN_SECRET_RE, (_, lead) => `${lead}${SECRET_PLACEHOLDER}`).replace(SPOKEN_PASSWORD_RE, (_, lead) => `${lead}${SECRET_PLACEHOLDER}`).replace(B64ISH_RE, SECRET_PLACEHOLDER);
|
|
26668
|
+
return failClosedOnCutConstructs(masked);
|
|
26669
|
+
}
|
|
26670
|
+
function maskContact(text) {
|
|
26671
|
+
return text.replace(EMAIL_RE, EMAIL_PLACEHOLDER).replace(PHONE_INTL_RE, PHONE_PLACEHOLDER).replace(PHONE_SEP_RE, PHONE_PLACEHOLDER).replace(PHONE_CONTEXT_RE, (_, lead) => `${lead}${PHONE_PLACEHOLDER}`);
|
|
26672
|
+
}
|
|
26673
|
+
var BARE_PHONE_RUN_RE = /(?<![\w.,-])\d{7,15}(?!\.?\d)(?![\w,-])/g;
|
|
26674
|
+
function maskContactStrict(text) {
|
|
26675
|
+
return maskContact(text).replace(BARE_PHONE_RUN_RE, PHONE_PLACEHOLDER);
|
|
26676
|
+
}
|
|
26677
|
+
var USERREF_DIGEST_VERSION = "1";
|
|
26678
|
+
function userRefHashKey() {
|
|
26679
|
+
return process.env.M8T_LEDGER_USERREF_KEY ?? (process.env.STORAGE_ACCOUNT_NAME ? `m8t-ledger-userref:${process.env.STORAGE_ACCOUNT_NAME}` : "m8t-agent-ledger-userref-dev");
|
|
26680
|
+
}
|
|
26681
|
+
function maskUserRef(ref) {
|
|
26682
|
+
if (ref == null)
|
|
26683
|
+
return void 0;
|
|
26684
|
+
return ref.replace(EMAIL_RE, (m) => `email#${USERREF_DIGEST_VERSION}:${createHmac("sha256", userRefHashKey()).update(m.toLowerCase()).digest("hex").slice(0, 32)}`);
|
|
26685
|
+
}
|
|
26686
|
+
|
|
26624
26687
|
// ../../packages/agent-ledger/dist/esm/read/ledger-identity.js
|
|
26625
26688
|
var CHANNEL_SOURCES = /* @__PURE__ */ new Set(["telegram", "slack"]);
|
|
26626
26689
|
function resolveIdentity(source, userRef, members = []) {
|
|
26627
26690
|
if (!userRef)
|
|
26628
26691
|
return { source, ref: "unknown" };
|
|
26629
26692
|
if (CHANNEL_SOURCES.has(source)) {
|
|
26630
|
-
const m = members.find((x) => x.source === source && x.handle.toLowerCase() === userRef.toLowerCase());
|
|
26693
|
+
const m = members.find((x) => x.source === source && (x.handle.toLowerCase() === userRef.toLowerCase() || maskUserRef(x.handle.toLowerCase()) === userRef.toLowerCase()));
|
|
26631
26694
|
if (m)
|
|
26632
26695
|
return { source, ref: userRef, display: m.displayName };
|
|
26633
26696
|
}
|
|
@@ -26937,6 +27000,10 @@ function makeRowKey(timestampIso, eventId) {
|
|
|
26937
27000
|
return `${String(reverse).padStart(19, "0")}_${eventId}`;
|
|
26938
27001
|
}
|
|
26939
27002
|
|
|
27003
|
+
// ../../packages/agent-ledger/dist/esm/entity.js
|
|
27004
|
+
var SNIPPET_MAX_LEN = 256;
|
|
27005
|
+
var PII_SCAN_WINDOW = SNIPPET_MAX_LEN * 16;
|
|
27006
|
+
|
|
26940
27007
|
// ../../packages/brain/engine/dist/esm/cursor.js
|
|
26941
27008
|
var CURSOR_PARTITION_KEY = "dreamcursor";
|
|
26942
27009
|
function isAbsentCursorError(e) {
|
|
@@ -27165,7 +27232,7 @@ function mapItems(raw) {
|
|
|
27165
27232
|
continue;
|
|
27166
27233
|
if (item.role !== "user" && item.role !== "assistant")
|
|
27167
27234
|
continue;
|
|
27168
|
-
const text = Array.isArray(item.content) ? stripVoiceEnvelope(item.content.map((c) => typeof c.text === "string" && c.text.length > 0 ? c.text : typeof c.transcript === "string" && c.transcript.length > 0 ? c.transcript : "").filter(Boolean).join("\n\n")) : "";
|
|
27235
|
+
const text = Array.isArray(item.content) ? maskSecrets(stripVoiceEnvelope(item.content.map((c) => typeof c.text === "string" && c.text.length > 0 ? c.text : typeof c.transcript === "string" && c.transcript.length > 0 ? c.transcript : "").filter(Boolean).join("\n\n"))) : "";
|
|
27169
27236
|
const at = typeof item.created_at === "number" ? new Date(item.created_at * 1e3).toISOString() : void 0;
|
|
27170
27237
|
acc.push(at ? { role: item.role, text, at } : { role: item.role, text });
|
|
27171
27238
|
}
|
|
@@ -27450,7 +27517,9 @@ async function runPipeline(args) {
|
|
|
27450
27517
|
const grpRows = rowsByGroupKey.get(groupKeyOf(g)) ?? [];
|
|
27451
27518
|
(consumedRowsByPk[pk] ??= []).push(...grpRows);
|
|
27452
27519
|
const provRows = grpRows.map((r) => ({ rowKey: rowStorageKey(r), eventTimestamp: r.eventTimestamp }));
|
|
27453
|
-
const
|
|
27520
|
+
const trustedOwner = g.source !== "a2a" && g.user.ref !== "unknown" && !g.user.ref.startsWith("svc:");
|
|
27521
|
+
const dreamItems = trustedOwner ? items : items.map((i) => ({ ...i, text: maskContactStrict(i.text) }));
|
|
27522
|
+
const conv = normalize(ng, dreamItems, enrichment);
|
|
27454
27523
|
conv.provenance = { pk, rows: provRows };
|
|
27455
27524
|
conversations.push(conv);
|
|
27456
27525
|
if (outcome === "consumed")
|
|
@@ -29207,14 +29276,278 @@ function defaultDeps(overrides) {
|
|
|
29207
29276
|
return deps;
|
|
29208
29277
|
}
|
|
29209
29278
|
|
|
29210
|
-
// src/commands/
|
|
29279
|
+
// src/commands/conversations/sweep.ts
|
|
29280
|
+
import { createHash as createHash4 } from "crypto";
|
|
29211
29281
|
import { Command as Command53, Option as Option50 } from "clipanion";
|
|
29282
|
+
import { AzureCliCredential as AzureCliCredential2 } from "@azure/identity";
|
|
29283
|
+
import { TableClient as TableClient8 } from "@azure/data-tables";
|
|
29284
|
+
import { AIProjectClient as AIProjectClient4 } from "@azure/ai-projects";
|
|
29285
|
+
init_errors();
|
|
29286
|
+
var LEDGER_TABLE_NAME2 = "AgentLedger";
|
|
29287
|
+
var KEY_LIFETIME_DAYS = 30;
|
|
29288
|
+
var DAY_MS = 24 * 60 * 60 * 1e3;
|
|
29289
|
+
function ownerDigest(nativeUserKey) {
|
|
29290
|
+
return createHash4("sha256").update(nativeUserKey).digest("base64url");
|
|
29291
|
+
}
|
|
29292
|
+
function svcPrincipal(svcRef) {
|
|
29293
|
+
return svcRef.split(":")[1] ?? "";
|
|
29294
|
+
}
|
|
29295
|
+
function svcConversationFacts(rows) {
|
|
29296
|
+
const facts = /* @__PURE__ */ new Map();
|
|
29297
|
+
for (const r of rows) {
|
|
29298
|
+
if (!r.foundryConversationId) continue;
|
|
29299
|
+
if (!r.userRef?.startsWith("svc:")) continue;
|
|
29300
|
+
const prev = facts.get(r.foundryConversationId);
|
|
29301
|
+
if (!prev || r.eventTimestamp > prev.lastSeen) {
|
|
29302
|
+
facts.set(r.foundryConversationId, {
|
|
29303
|
+
conversationId: r.foundryConversationId,
|
|
29304
|
+
svcRef: r.userRef,
|
|
29305
|
+
principal: svcPrincipal(r.userRef),
|
|
29306
|
+
agent: r.agentName,
|
|
29307
|
+
lastSeen: r.eventTimestamp
|
|
29308
|
+
});
|
|
29309
|
+
}
|
|
29310
|
+
}
|
|
29311
|
+
return facts;
|
|
29312
|
+
}
|
|
29313
|
+
function selectStaleCandidates(facts, cutoffIso) {
|
|
29314
|
+
return [...facts.values()].filter((f) => f.lastSeen < cutoffIso).sort((a, b) => a.lastSeen < b.lastSeen ? -1 : 1);
|
|
29315
|
+
}
|
|
29316
|
+
function confirmCandidate(fact, meta, newestItemAt, cutoffIso) {
|
|
29317
|
+
if (meta.app !== "m8t-webapp") return { ok: false, reason: `unexpected app tag '${meta.app ?? ""}'` };
|
|
29318
|
+
const expectedOwner = `web:${ownerDigest(fact.svcRef)}`;
|
|
29319
|
+
if (meta.ownerKey !== expectedOwner) return { ok: false, reason: "owner mismatch" };
|
|
29320
|
+
if (newestItemAt === null) return { ok: false, reason: "no items to prove inactivity" };
|
|
29321
|
+
if (newestItemAt >= cutoffIso) return { ok: false, reason: "recent activity" };
|
|
29322
|
+
return { ok: true };
|
|
29323
|
+
}
|
|
29324
|
+
function statusOf2(e) {
|
|
29325
|
+
const err = e;
|
|
29326
|
+
return err?.statusCode ?? err?.status;
|
|
29327
|
+
}
|
|
29328
|
+
function defaultDeps2() {
|
|
29329
|
+
const credential2 = new AzureCliCredential2();
|
|
29330
|
+
const openaiFor = (ctx) => new AIProjectClient4(ctx.projectEndpoint, credential2).getOpenAIClient();
|
|
29331
|
+
return {
|
|
29332
|
+
async resolveContext(opts) {
|
|
29333
|
+
const account = await getAzAccount();
|
|
29334
|
+
const subscriptionId = opts.subscription ?? account.subscriptionId;
|
|
29335
|
+
const project = await resolveFoundryProject({
|
|
29336
|
+
credential: credential2,
|
|
29337
|
+
subscriptionId,
|
|
29338
|
+
interactive: false,
|
|
29339
|
+
endpoint: opts.endpoint
|
|
29340
|
+
});
|
|
29341
|
+
const m = /\/resourceGroups\/([^/]+)/i.exec(project.accountScope);
|
|
29342
|
+
if (!m) throw new LocalCliError({ code: "sweep_context", message: `Could not parse resource group from '${project.accountScope}'.` });
|
|
29343
|
+
const { ledgerTableEndpoint } = await discoverLedgerResources({
|
|
29344
|
+
credential: credential2,
|
|
29345
|
+
subscriptionId,
|
|
29346
|
+
resourceGroup: m[1]
|
|
29347
|
+
});
|
|
29348
|
+
return { projectEndpoint: project.endpoint, ledgerTableEndpoint };
|
|
29349
|
+
},
|
|
29350
|
+
async fetchRows(ctx, fromIso, toIso) {
|
|
29351
|
+
const client = new TableClient8(ctx.ledgerTableEndpoint, LEDGER_TABLE_NAME2, credential2);
|
|
29352
|
+
return fetchLedgerRows({ workers: [], source: "all", from: fromIso, to: toIso }, client);
|
|
29353
|
+
},
|
|
29354
|
+
async retrieveMetadata(ctx, conversationId) {
|
|
29355
|
+
try {
|
|
29356
|
+
const conv = await openaiFor(ctx).conversations.retrieve(conversationId);
|
|
29357
|
+
const md = conv.metadata;
|
|
29358
|
+
const s = (v) => typeof v === "string" ? v : void 0;
|
|
29359
|
+
if (!md || typeof md !== "object") return {};
|
|
29360
|
+
return { app: s(md.app), ownerKey: s(md.ownerKey), platform: s(md.platform) };
|
|
29361
|
+
} catch (e) {
|
|
29362
|
+
if (statusOf2(e) === 404) return "gone";
|
|
29363
|
+
throw e;
|
|
29364
|
+
}
|
|
29365
|
+
},
|
|
29366
|
+
async newestItemAt(ctx, conversationId) {
|
|
29367
|
+
try {
|
|
29368
|
+
for await (const item of openaiFor(ctx).conversations.items.list(conversationId)) {
|
|
29369
|
+
const created = item.created_at;
|
|
29370
|
+
if (typeof created !== "number") return { at: null };
|
|
29371
|
+
return { at: new Date(created * 1e3).toISOString() };
|
|
29372
|
+
}
|
|
29373
|
+
return { at: null };
|
|
29374
|
+
} catch (e) {
|
|
29375
|
+
if (statusOf2(e) === 404) return "gone";
|
|
29376
|
+
throw e;
|
|
29377
|
+
}
|
|
29378
|
+
},
|
|
29379
|
+
async deleteConversation(ctx, conversationId) {
|
|
29380
|
+
try {
|
|
29381
|
+
await openaiFor(ctx).conversations.delete(conversationId);
|
|
29382
|
+
return "deleted";
|
|
29383
|
+
} catch (e) {
|
|
29384
|
+
if (statusOf2(e) === 404) return "already-gone";
|
|
29385
|
+
throw e;
|
|
29386
|
+
}
|
|
29387
|
+
}
|
|
29388
|
+
};
|
|
29389
|
+
}
|
|
29390
|
+
var ConversationsSweepCommand = class extends M8tCommand {
|
|
29391
|
+
static paths = [["conversations", "sweep"]];
|
|
29392
|
+
static usage = Command53.Usage({
|
|
29393
|
+
category: "Conversations",
|
|
29394
|
+
description: "Delete expired public-visitor conversations (dry run by default)",
|
|
29395
|
+
details: `
|
|
29396
|
+
Finds conversations owned by delegated end users (public visitors) whose
|
|
29397
|
+
last activity predates the retention window (${String(KEY_LIFETIME_DAYS)}-day key life + grace),
|
|
29398
|
+
confirms each against its own metadata and newest item, and \u2014 only with
|
|
29399
|
+
--delete \u2014 permanently removes them. Team, channel, and delegated-work
|
|
29400
|
+
conversations are structurally out of scope. The masked ledger telemetry
|
|
29401
|
+
of swept conversations is kept.
|
|
29402
|
+
`,
|
|
29403
|
+
examples: [
|
|
29404
|
+
["Report what would be deleted (nothing is)", "m8t conversations sweep"],
|
|
29405
|
+
["Delete, capped at 50", "m8t conversations sweep --delete --max 50"]
|
|
29406
|
+
]
|
|
29407
|
+
});
|
|
29408
|
+
doDelete = Option50.Boolean("--delete", false, {
|
|
29409
|
+
description: "Perform deletions (without this flag the command only reports)"
|
|
29410
|
+
});
|
|
29411
|
+
principal = Option50.String("--principal", {
|
|
29412
|
+
description: "Service-principal oid whose end-user keys are known-ephemeral (required with --delete; a dry run without it reports candidates grouped by principal)"
|
|
29413
|
+
});
|
|
29414
|
+
max = Option50.String("--max", "200", { description: "Maximum deletions per run" });
|
|
29415
|
+
graceDays = Option50.String("--grace-days", "14", {
|
|
29416
|
+
description: "Days past the 30-day key life before a conversation is eligible"
|
|
29417
|
+
});
|
|
29418
|
+
lookbackDays = Option50.String("--lookback-days", "180", {
|
|
29419
|
+
description: "How far back to scan ledger activity for candidates"
|
|
29420
|
+
});
|
|
29421
|
+
subscription = Option50.String("--subscription", { description: "Azure subscription id override" });
|
|
29422
|
+
endpoint = Option50.String("--endpoint", { description: "Foundry project endpoint override" });
|
|
29423
|
+
deps = defaultDeps2();
|
|
29424
|
+
async executeCommand() {
|
|
29425
|
+
const out = this.context.stdout;
|
|
29426
|
+
const max = Number.parseInt(this.max, 10);
|
|
29427
|
+
const grace = Number.parseInt(this.graceDays, 10);
|
|
29428
|
+
const lookback = Number.parseInt(this.lookbackDays, 10);
|
|
29429
|
+
if (!Number.isFinite(max) || max < 1) throw new LocalCliError({ code: "sweep_args", message: "--max must be a positive integer." });
|
|
29430
|
+
if (!Number.isFinite(grace) || grace < 0) throw new LocalCliError({ code: "sweep_args", message: "--grace-days must be a non-negative integer." });
|
|
29431
|
+
const retentionDays = KEY_LIFETIME_DAYS + grace;
|
|
29432
|
+
if (!Number.isFinite(lookback) || lookback <= retentionDays) {
|
|
29433
|
+
throw new LocalCliError({ code: "sweep_args", message: `--lookback-days must exceed the retention window (${String(retentionDays)} days).` });
|
|
29434
|
+
}
|
|
29435
|
+
const now = Date.now();
|
|
29436
|
+
const cutoffIso = new Date(now - retentionDays * DAY_MS).toISOString();
|
|
29437
|
+
const fromIso = new Date(now - lookback * DAY_MS).toISOString();
|
|
29438
|
+
const toIso = new Date(now).toISOString();
|
|
29439
|
+
const ctx = await this.deps.resolveContext({ subscription: this.subscription, endpoint: this.endpoint });
|
|
29440
|
+
out.write(`Scanning ledger activity ${fromIso} \u2192 ${toIso}; retention cutoff ${cutoffIso}.
|
|
29441
|
+
`);
|
|
29442
|
+
const rows = await this.deps.fetchRows(ctx, fromIso, toIso);
|
|
29443
|
+
const facts = svcConversationFacts(rows);
|
|
29444
|
+
const stale = selectStaleCandidates(facts, cutoffIso);
|
|
29445
|
+
if (this.doDelete && !this.principal) {
|
|
29446
|
+
throw new LocalCliError({
|
|
29447
|
+
code: "sweep_principal_required",
|
|
29448
|
+
message: "--delete requires --principal <service-principal oid>.",
|
|
29449
|
+
hint: "Run without --delete first: the dry run lists candidates grouped by principal so you can identify the visitor-minting one."
|
|
29450
|
+
});
|
|
29451
|
+
}
|
|
29452
|
+
const inScope = this.principal ? stale.filter((f) => f.principal === this.principal) : stale;
|
|
29453
|
+
const outOfScope = stale.length - inScope.length;
|
|
29454
|
+
out.write(
|
|
29455
|
+
`${String(facts.size)} delegated conversation(s) seen in window; ${String(stale.length)} past cutoff` + (this.principal ? ` (${String(inScope.length)} for principal ${this.principal}, ${String(outOfScope)} other-principal ignored)` : "") + ".\n"
|
|
29456
|
+
);
|
|
29457
|
+
if (!this.principal && stale.length > 0) {
|
|
29458
|
+
const byPrincipal = /* @__PURE__ */ new Map();
|
|
29459
|
+
for (const f of stale) byPrincipal.set(f.principal, (byPrincipal.get(f.principal) ?? 0) + 1);
|
|
29460
|
+
out.write("Stale candidates by principal (pass --principal to scope deletion):\n");
|
|
29461
|
+
for (const [pr, n] of [...byPrincipal.entries()].sort((a, b) => b[1] - a[1])) {
|
|
29462
|
+
out.write(` ${pr || "(malformed)"} ${String(n)}
|
|
29463
|
+
`);
|
|
29464
|
+
}
|
|
29465
|
+
}
|
|
29466
|
+
out.write("\n");
|
|
29467
|
+
let attempts = 0;
|
|
29468
|
+
let deleted = 0;
|
|
29469
|
+
let alreadyGone = 0;
|
|
29470
|
+
let skipped = 0;
|
|
29471
|
+
let failures = 0;
|
|
29472
|
+
let remaining = 0;
|
|
29473
|
+
for (const fact of inScope) {
|
|
29474
|
+
if (attempts >= max) {
|
|
29475
|
+
remaining += 1;
|
|
29476
|
+
continue;
|
|
29477
|
+
}
|
|
29478
|
+
const ageDays = Math.floor((now - Date.parse(fact.lastSeen)) / DAY_MS);
|
|
29479
|
+
const label = `${fact.conversationId} agent=${fact.agent} last-active=${fact.lastSeen} (${String(ageDays)}d)`;
|
|
29480
|
+
let meta;
|
|
29481
|
+
let newest;
|
|
29482
|
+
try {
|
|
29483
|
+
meta = await this.deps.retrieveMetadata(ctx, fact.conversationId);
|
|
29484
|
+
newest = meta === "gone" ? "gone" : await this.deps.newestItemAt(ctx, fact.conversationId);
|
|
29485
|
+
} catch (e) {
|
|
29486
|
+
failures += 1;
|
|
29487
|
+
out.write(`${colors.error("failed")} ${label} \u2014 ${e.message}
|
|
29488
|
+
`);
|
|
29489
|
+
continue;
|
|
29490
|
+
}
|
|
29491
|
+
if (meta === "gone" || newest === "gone") {
|
|
29492
|
+
alreadyGone += 1;
|
|
29493
|
+
out.write(`${colors.dim("already gone")} ${label}
|
|
29494
|
+
`);
|
|
29495
|
+
continue;
|
|
29496
|
+
}
|
|
29497
|
+
const verdict = confirmCandidate(fact, meta, newest.at, cutoffIso);
|
|
29498
|
+
if (!verdict.ok) {
|
|
29499
|
+
skipped += 1;
|
|
29500
|
+
out.write(`${colors.warn("skip")} ${label} \u2014 ${verdict.reason}
|
|
29501
|
+
`);
|
|
29502
|
+
continue;
|
|
29503
|
+
}
|
|
29504
|
+
attempts += 1;
|
|
29505
|
+
if (!this.doDelete) {
|
|
29506
|
+
out.write(`${colors.field("would delete")} ${label}
|
|
29507
|
+
`);
|
|
29508
|
+
continue;
|
|
29509
|
+
}
|
|
29510
|
+
try {
|
|
29511
|
+
const result2 = await this.deps.deleteConversation(ctx, fact.conversationId);
|
|
29512
|
+
if (result2 === "deleted") {
|
|
29513
|
+
deleted += 1;
|
|
29514
|
+
out.write(`${colors.error("deleted")} ${label}
|
|
29515
|
+
`);
|
|
29516
|
+
} else {
|
|
29517
|
+
alreadyGone += 1;
|
|
29518
|
+
out.write(`${colors.dim("already gone")} ${label}
|
|
29519
|
+
`);
|
|
29520
|
+
}
|
|
29521
|
+
} catch (e) {
|
|
29522
|
+
failures += 1;
|
|
29523
|
+
out.write(`${colors.error("failed")} ${label} \u2014 ${e.message}
|
|
29524
|
+
`);
|
|
29525
|
+
}
|
|
29526
|
+
}
|
|
29527
|
+
out.write("\n");
|
|
29528
|
+
const tail = `already gone ${String(alreadyGone)}, skipped ${String(skipped)} (fail-closed), failed ${String(failures)}` + (remaining > 0 ? `, ${String(remaining)} past the cap \u2014 re-run to continue` : "") + ".\n";
|
|
29529
|
+
if (this.doDelete) {
|
|
29530
|
+
out.write(`Deleted ${String(deleted)}, ${tail}`);
|
|
29531
|
+
} else {
|
|
29532
|
+
out.write(`DRY RUN \u2014 nothing deleted. ${String(attempts)} conversation(s) would be deleted, ${tail}`);
|
|
29533
|
+
}
|
|
29534
|
+
if (failures > 0) {
|
|
29535
|
+
out.write(`${colors.error("Run incomplete:")} ${String(failures)} verification/deletion failure(s) \u2014 fix access and re-run.
|
|
29536
|
+
`);
|
|
29537
|
+
return 1;
|
|
29538
|
+
}
|
|
29539
|
+
return 0;
|
|
29540
|
+
}
|
|
29541
|
+
};
|
|
29542
|
+
|
|
29543
|
+
// src/commands/foundry/create.ts
|
|
29544
|
+
import { Command as Command54, Option as Option51 } from "clipanion";
|
|
29212
29545
|
|
|
29213
29546
|
// src/lib/foundry-create.ts
|
|
29214
29547
|
init_errors();
|
|
29215
|
-
import { createHash as
|
|
29548
|
+
import { createHash as createHash5 } from "crypto";
|
|
29216
29549
|
function deriveAccountName(subscriptionId) {
|
|
29217
|
-
const h =
|
|
29550
|
+
const h = createHash5("sha256").update(subscriptionId).digest("hex").slice(0, 12);
|
|
29218
29551
|
return `m8t${h}`;
|
|
29219
29552
|
}
|
|
29220
29553
|
function assertHostedRegion(location) {
|
|
@@ -29446,7 +29779,7 @@ async function createFoundryProject(args) {
|
|
|
29446
29779
|
init_errors();
|
|
29447
29780
|
var FoundryCreateCommand = class extends M8tCommand {
|
|
29448
29781
|
static paths = [["foundry", "create"]];
|
|
29449
|
-
static usage =
|
|
29782
|
+
static usage = Command54.Usage({
|
|
29450
29783
|
description: "Create an AI Foundry (AIServices) account + project + model deployment from scratch.",
|
|
29451
29784
|
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).",
|
|
29452
29785
|
examples: [
|
|
@@ -29455,16 +29788,16 @@ var FoundryCreateCommand = class extends M8tCommand {
|
|
|
29455
29788
|
["Higher capacity for a reasoning model", "$0 foundry create --resource-group rg-m8t-stack --location eastus2 --model gpt-5-mini --capacity 250"]
|
|
29456
29789
|
]
|
|
29457
29790
|
});
|
|
29458
|
-
resourceGroup =
|
|
29459
|
-
location =
|
|
29460
|
-
account =
|
|
29461
|
-
project =
|
|
29462
|
-
model =
|
|
29463
|
-
modelVersion =
|
|
29464
|
-
capacity =
|
|
29465
|
-
subscription =
|
|
29466
|
-
skipQuotaCheck =
|
|
29467
|
-
output =
|
|
29791
|
+
resourceGroup = Option51.String("--resource-group");
|
|
29792
|
+
location = Option51.String("--location");
|
|
29793
|
+
account = Option51.String("--account");
|
|
29794
|
+
project = Option51.String("--project", "m8t");
|
|
29795
|
+
model = Option51.String("--model", "gpt-4.1-mini");
|
|
29796
|
+
modelVersion = Option51.String("--model-version", "2025-04-14");
|
|
29797
|
+
capacity = Option51.String("--capacity", "50");
|
|
29798
|
+
subscription = Option51.String("--subscription");
|
|
29799
|
+
skipQuotaCheck = Option51.Boolean("--skip-quota-check", false);
|
|
29800
|
+
output = Option51.String("--output");
|
|
29468
29801
|
async executeCommand() {
|
|
29469
29802
|
const mode = resolveOutputMode(
|
|
29470
29803
|
this.output,
|
|
@@ -29536,22 +29869,22 @@ var FoundryCreateCommand = class extends M8tCommand {
|
|
|
29536
29869
|
};
|
|
29537
29870
|
|
|
29538
29871
|
// src/commands/foundry/await-ready.ts
|
|
29539
|
-
import { Command as
|
|
29540
|
-
import { AzureCliCredential as
|
|
29872
|
+
import { Command as Command55, Option as Option52 } from "clipanion";
|
|
29873
|
+
import { AzureCliCredential as AzureCliCredential3 } from "@azure/identity";
|
|
29541
29874
|
init_errors();
|
|
29542
29875
|
var FoundryAwaitReadyCommand = class extends M8tCommand {
|
|
29543
29876
|
static paths = [["foundry", "await-ready"]];
|
|
29544
|
-
static usage =
|
|
29877
|
+
static usage = Command55.Usage({
|
|
29545
29878
|
description: "Wait until a freshly-created Foundry project's data plane reliably serves it.",
|
|
29546
29879
|
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.",
|
|
29547
29880
|
examples: [["Wait for a project to be ready", "$0 foundry await-ready --endpoint https://acc.services.ai.azure.com/api/projects/m8t"]]
|
|
29548
29881
|
});
|
|
29549
|
-
endpoint =
|
|
29550
|
-
consecutive =
|
|
29551
|
-
attempts =
|
|
29552
|
-
interval =
|
|
29553
|
-
subscription =
|
|
29554
|
-
output =
|
|
29882
|
+
endpoint = Option52.String("--endpoint");
|
|
29883
|
+
consecutive = Option52.String("--consecutive", "3");
|
|
29884
|
+
attempts = Option52.String("--attempts", "60");
|
|
29885
|
+
interval = Option52.String("--interval", "5");
|
|
29886
|
+
subscription = Option52.String("--subscription");
|
|
29887
|
+
output = Option52.String("--output");
|
|
29555
29888
|
async executeCommand() {
|
|
29556
29889
|
const mode = resolveOutputMode(this.output, this.context.stdout);
|
|
29557
29890
|
const endpoint = typeof this.endpoint === "string" ? this.endpoint : void 0;
|
|
@@ -29562,7 +29895,7 @@ var FoundryAwaitReadyCommand = class extends M8tCommand {
|
|
|
29562
29895
|
const attempts = typeof this.attempts === "string" ? Number(this.attempts) : 60;
|
|
29563
29896
|
const intervalMs = (typeof this.interval === "string" ? Number(this.interval) : 5) * 1e3;
|
|
29564
29897
|
await getAzAccount();
|
|
29565
|
-
const credential2 = new
|
|
29898
|
+
const credential2 = new AzureCliCredential3();
|
|
29566
29899
|
const probe = makeAgentsProbe(credential2, endpoint);
|
|
29567
29900
|
const onProgress = mode === "pretty" ? (m) => this.context.stderr.write(` ${colors.dim(m)}
|
|
29568
29901
|
`) : void 0;
|
|
@@ -29585,7 +29918,7 @@ var FoundryAwaitReadyCommand = class extends M8tCommand {
|
|
|
29585
29918
|
};
|
|
29586
29919
|
|
|
29587
29920
|
// src/commands/bootstrap/preflight.ts
|
|
29588
|
-
import { Command as
|
|
29921
|
+
import { Command as Command56, Option as Option53 } from "clipanion";
|
|
29589
29922
|
|
|
29590
29923
|
// ../../packages/telemetry-contract/artifact/tier-map.ts
|
|
29591
29924
|
var EVENT_TIERS = {
|
|
@@ -29637,7 +29970,7 @@ function preflightRenderable(results) {
|
|
|
29637
29970
|
}
|
|
29638
29971
|
var BootstrapPreflightCommand = class extends M8tCommand {
|
|
29639
29972
|
static paths = [["bootstrap", "preflight"]];
|
|
29640
|
-
static usage =
|
|
29973
|
+
static usage = Command56.Usage({
|
|
29641
29974
|
description: "Loudly verify you can install m8t (Owner/UAA + directory admin) and hard-stop if not.",
|
|
29642
29975
|
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), every Azure resource provider the install uses (registering any that are missing), soft-deleted Cognitive Services accounts (they keep their model quota until purged, so quota can read free and the model deployment still fail), and \u2014 with --location \u2014 model quota in the target region. Exits non-zero with the exact failing check + remedy. `m8t prereqs` runs the same substrate checks on their own.",
|
|
29643
29976
|
examples: [
|
|
@@ -29646,9 +29979,9 @@ var BootstrapPreflightCommand = class extends M8tCommand {
|
|
|
29646
29979
|
["BYO app registration (directory guests)", "$0 bootstrap preflight --client-id <appId>"]
|
|
29647
29980
|
]
|
|
29648
29981
|
});
|
|
29649
|
-
clientId =
|
|
29650
|
-
subscription =
|
|
29651
|
-
location =
|
|
29982
|
+
clientId = Option53.String("--client-id");
|
|
29983
|
+
subscription = Option53.String("--subscription");
|
|
29984
|
+
location = Option53.String("--location", {
|
|
29652
29985
|
description: "Target region. Enables the model-quota check \u2014 without it, quota is not verified."
|
|
29653
29986
|
});
|
|
29654
29987
|
async executeCommand() {
|
|
@@ -29748,7 +30081,7 @@ ${colors.error(" " + why)}
|
|
|
29748
30081
|
import * as fs35 from "fs";
|
|
29749
30082
|
import * as os15 from "os";
|
|
29750
30083
|
import * as path38 from "path";
|
|
29751
|
-
import { Command as
|
|
30084
|
+
import { Command as Command57, Option as Option54 } from "clipanion";
|
|
29752
30085
|
init_errors();
|
|
29753
30086
|
|
|
29754
30087
|
// src/lib/bootstrap-mi.ts
|
|
@@ -29903,7 +30236,7 @@ async function kickInstaller(s) {
|
|
|
29903
30236
|
}
|
|
29904
30237
|
|
|
29905
30238
|
// src/lib/bootstrap-status.ts
|
|
29906
|
-
import { createHash as
|
|
30239
|
+
import { createHash as createHash6, randomUUID as randomUUID2 } from "crypto";
|
|
29907
30240
|
import * as fs33 from "fs/promises";
|
|
29908
30241
|
import * as os13 from "os";
|
|
29909
30242
|
import * as path36 from "path";
|
|
@@ -29911,7 +30244,7 @@ init_errors();
|
|
|
29911
30244
|
var STATUS_CONTAINER = "status";
|
|
29912
30245
|
var STATUS_BLOB = "status.json";
|
|
29913
30246
|
function deriveStatusSaName(resourceGroup, subscriptionId) {
|
|
29914
|
-
const hex =
|
|
30247
|
+
const hex = createHash6("sha256").update(resourceGroup + subscriptionId).digest("hex").slice(0, 12);
|
|
29915
30248
|
return `m8tinst${hex}`;
|
|
29916
30249
|
}
|
|
29917
30250
|
function statusBlobUrl(saName) {
|
|
@@ -30118,7 +30451,7 @@ var ACI_NAME = "m8t-installer";
|
|
|
30118
30451
|
var MI_NAME = "m8t-installer-mi";
|
|
30119
30452
|
var BootstrapLaunchCommand = class extends M8tCommand {
|
|
30120
30453
|
static paths = [["bootstrap", "launch"]];
|
|
30121
|
-
static usage =
|
|
30454
|
+
static usage = Command57.Usage({
|
|
30122
30455
|
description: "Create + authorize the installer managed identity, then kick the cloud installer.",
|
|
30123
30456
|
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` and `reap`, and threads your Azure object id so the installer can grant you the platform's data-plane roles itself.",
|
|
30124
30457
|
examples: [
|
|
@@ -30129,26 +30462,26 @@ var BootstrapLaunchCommand = class extends M8tCommand {
|
|
|
30129
30462
|
["Share a support contact", "$0 bootstrap launch --location eastus2 --contact-email you@example.com --company 'Acme'"]
|
|
30130
30463
|
]
|
|
30131
30464
|
});
|
|
30132
|
-
location =
|
|
30133
|
-
resourceGroup =
|
|
30134
|
-
clientId =
|
|
30135
|
-
subscription =
|
|
30136
|
-
installerTag =
|
|
30465
|
+
location = Option54.String("--location");
|
|
30466
|
+
resourceGroup = Option54.String("--resource-group");
|
|
30467
|
+
clientId = Option54.String("--client-id");
|
|
30468
|
+
subscription = Option54.String("--subscription");
|
|
30469
|
+
installerTag = Option54.String("--installer-tag");
|
|
30137
30470
|
// Full image ref override (registry + repo + tag) — an escape hatch when the
|
|
30138
30471
|
// default org/tag is wrong for the current CLI (e.g. a stale published build).
|
|
30139
30472
|
// Wins over --installer-tag / the pinned default.
|
|
30140
|
-
installerImage =
|
|
30141
|
-
gatewayImageRef =
|
|
30142
|
-
githubAppCreds =
|
|
30143
|
-
contactEmail =
|
|
30144
|
-
company =
|
|
30473
|
+
installerImage = Option54.String("--installer-image");
|
|
30474
|
+
gatewayImageRef = Option54.String("--gateway-image-ref");
|
|
30475
|
+
githubAppCreds = Option54.String("--github-app-creds");
|
|
30476
|
+
contactEmail = Option54.String("--contact-email", { description: "Share a contact email with m8t support. Not sent unless you pass it." });
|
|
30477
|
+
company = Option54.String("--company", { description: "Share your company name with m8t support. Not sent unless you pass it." });
|
|
30145
30478
|
// Value-carrying on purpose: a bare --force would be cargo-culted into
|
|
30146
30479
|
// runbooks and harness prompts and erode the protection, whereas a faithful
|
|
30147
30480
|
// paste can never accidentally carry the victim group's name. It AUTHORIZES
|
|
30148
30481
|
// the target; --resource-group is what CHOOSES it.
|
|
30149
|
-
reinstallInto =
|
|
30150
|
-
org =
|
|
30151
|
-
noBrains =
|
|
30482
|
+
reinstallInto = Option54.String("--reinstall-into", { description: "Consent to installing into --resource-group even though it already holds resources. Must match the target group's name." });
|
|
30483
|
+
org = Option54.String("--org", { description: "Assert the GitHub App on disk is installed on this org; refuses on a mismatch." });
|
|
30484
|
+
noBrains = Option54.Boolean("--no-brains", false, { description: "Install without brain-backed workers. For test and CI rigs; the supported install creates brains." });
|
|
30152
30485
|
async executeCommand() {
|
|
30153
30486
|
const location = typeof this.location === "string" ? this.location : void 0;
|
|
30154
30487
|
if (!location) {
|
|
@@ -30309,7 +30642,7 @@ var BootstrapLaunchCommand = class extends M8tCommand {
|
|
|
30309
30642
|
};
|
|
30310
30643
|
|
|
30311
30644
|
// src/commands/bootstrap/status.ts
|
|
30312
|
-
import { Command as
|
|
30645
|
+
import { Command as Command59, Option as Option56 } from "clipanion";
|
|
30313
30646
|
init_errors();
|
|
30314
30647
|
|
|
30315
30648
|
// src/lib/bootstrap-aci-state.ts
|
|
@@ -31313,7 +31646,7 @@ import { randomUUID as randomUUID3 } from "crypto";
|
|
|
31313
31646
|
import { execFile, spawn as spawn7 } from "child_process";
|
|
31314
31647
|
|
|
31315
31648
|
// src/lib/companion-artifact.ts
|
|
31316
|
-
import { createHash as
|
|
31649
|
+
import { createHash as createHash7 } from "crypto";
|
|
31317
31650
|
import { constants } from "fs";
|
|
31318
31651
|
import * as fs36 from "fs/promises";
|
|
31319
31652
|
import * as path40 from "path";
|
|
@@ -31351,7 +31684,7 @@ function canonicalEntry(entry) {
|
|
|
31351
31684
|
`;
|
|
31352
31685
|
}
|
|
31353
31686
|
function artifactTreeSha256(entries) {
|
|
31354
|
-
const hash =
|
|
31687
|
+
const hash = createHash7("sha256");
|
|
31355
31688
|
const ordered = [...entries].sort(
|
|
31356
31689
|
(left, right) => left.path.localeCompare(right.path)
|
|
31357
31690
|
);
|
|
@@ -31421,7 +31754,7 @@ function parseArtifactManifest(value) {
|
|
|
31421
31754
|
};
|
|
31422
31755
|
}
|
|
31423
31756
|
async function sha256File2(filePath) {
|
|
31424
|
-
return
|
|
31757
|
+
return createHash7("sha256").update(await fs36.readFile(filePath)).digest("hex");
|
|
31425
31758
|
}
|
|
31426
31759
|
async function walk2(root, relative4 = "") {
|
|
31427
31760
|
const directory = path40.join(root, ...relative4.split("/").filter(Boolean));
|
|
@@ -32237,7 +32570,7 @@ async function uninstallCompanion(options) {
|
|
|
32237
32570
|
// src/commands/companion/install.ts
|
|
32238
32571
|
import * as os18 from "os";
|
|
32239
32572
|
import * as path43 from "path";
|
|
32240
|
-
import { Command as
|
|
32573
|
+
import { Command as Command58, Option as Option55 } from "clipanion";
|
|
32241
32574
|
|
|
32242
32575
|
// src/lib/companion-channel.ts
|
|
32243
32576
|
async function readCompanionRelease(source = { url: CHANNEL_LATEST_URL }, deps = {}) {
|
|
@@ -32252,7 +32585,7 @@ async function readCompanionRelease(source = { url: CHANNEL_LATEST_URL }, deps =
|
|
|
32252
32585
|
}
|
|
32253
32586
|
|
|
32254
32587
|
// src/lib/companion-download.ts
|
|
32255
|
-
import { createHash as
|
|
32588
|
+
import { createHash as createHash8 } from "crypto";
|
|
32256
32589
|
import { execFile as execFile2 } from "child_process";
|
|
32257
32590
|
import * as fs38 from "fs/promises";
|
|
32258
32591
|
import * as os17 from "os";
|
|
@@ -32301,7 +32634,7 @@ async function downloadCompanionArtifact(component, deps = {}) {
|
|
|
32301
32634
|
message: `${pinned.asset} is larger than this command will accept.`
|
|
32302
32635
|
});
|
|
32303
32636
|
}
|
|
32304
|
-
const digest =
|
|
32637
|
+
const digest = createHash8("sha256").update(bytes).digest("hex");
|
|
32305
32638
|
if (digest !== pinned.sha256) {
|
|
32306
32639
|
throw new LocalCliError({
|
|
32307
32640
|
code: "COMPANION_ASSET_DIGEST_MISMATCH",
|
|
@@ -32395,7 +32728,7 @@ Version: ${state.version}
|
|
|
32395
32728
|
}
|
|
32396
32729
|
var CompanionInstallCommand = class extends M8tCommand {
|
|
32397
32730
|
static paths = [["companion", "install"]];
|
|
32398
|
-
static usage =
|
|
32731
|
+
static usage = Command58.Usage({
|
|
32399
32732
|
description: "Install the desktop companions for this user from the release channel.",
|
|
32400
32733
|
examples: [
|
|
32401
32734
|
["Install the released build", "$0 companion install"],
|
|
@@ -32405,10 +32738,10 @@ var CompanionInstallCommand = class extends M8tCommand {
|
|
|
32405
32738
|
]
|
|
32406
32739
|
]
|
|
32407
32740
|
});
|
|
32408
|
-
from =
|
|
32741
|
+
from = Option55.String("--from", {
|
|
32409
32742
|
description: "A locally staged build directory instead of the released one."
|
|
32410
32743
|
});
|
|
32411
|
-
resourceGroup =
|
|
32744
|
+
resourceGroup = Option55.String("--resource-group", {
|
|
32412
32745
|
description: "Which deployment to bind to, when the subscription holds more than one."
|
|
32413
32746
|
});
|
|
32414
32747
|
async executeCommand() {
|
|
@@ -32436,7 +32769,7 @@ async function looksLikeCheckout(dir) {
|
|
|
32436
32769
|
return false;
|
|
32437
32770
|
}
|
|
32438
32771
|
}
|
|
32439
|
-
var
|
|
32772
|
+
var defaultDeps3 = {
|
|
32440
32773
|
discoverGateway,
|
|
32441
32774
|
writeConfig,
|
|
32442
32775
|
ensureGatewayRedirectUri,
|
|
@@ -32449,7 +32782,7 @@ var defaultDeps2 = {
|
|
|
32449
32782
|
}),
|
|
32450
32783
|
homedir: () => os19.homedir()
|
|
32451
32784
|
};
|
|
32452
|
-
async function finalizeInstall(args, deps =
|
|
32785
|
+
async function finalizeInstall(args, deps = defaultDeps3) {
|
|
32453
32786
|
const markerDir = path44.join(deps.homedir(), ".m8t");
|
|
32454
32787
|
const markerPath = path44.join(markerDir, "repo-root");
|
|
32455
32788
|
const cwd = process.cwd();
|
|
@@ -32624,7 +32957,7 @@ var BootstrapStatusCommand = class extends M8tCommand {
|
|
|
32624
32957
|
// runbooks and shakedown recipes that a founder may already be part-way
|
|
32625
32958
|
// through — it prints a deprecation notice and does the right thing.
|
|
32626
32959
|
static paths = [["bootstrap", "status"], ["bootstrap", "finish"]];
|
|
32627
|
-
static usage =
|
|
32960
|
+
static usage = Command59.Usage({
|
|
32628
32961
|
description: "Show the cloud installer's live status (phase, progress, result) \u2014 and finish the local setup when it lands.",
|
|
32629
32962
|
details: "Reads the durable status blob written by the installer. --watch polls until the install reaches done or failed.\n\nOn reaching done under --watch this also completes the local half of the install, which nothing else in the bootstrap path can do: it registers the webapp's sign-in redirect URI (the installer runs as a managed identity with no directory role, and at launch time the gateway FQDN did not exist yet), writes ~/.m8t/repo-root and the gateway discovery cache, and seeds your advisors' brains from the onboarding intake. Re-runnable \u2014 `m8t bootstrap finish` is a deprecated alias that does exactly this on an already-done install.",
|
|
32630
32963
|
examples: [
|
|
@@ -32633,12 +32966,12 @@ var BootstrapStatusCommand = class extends M8tCommand {
|
|
|
32633
32966
|
["Redo the local setup on a finished install", "$0 bootstrap status --finalize --repo-root /path/to/m8t"]
|
|
32634
32967
|
]
|
|
32635
32968
|
});
|
|
32636
|
-
watch =
|
|
32637
|
-
output =
|
|
32638
|
-
repoRoot =
|
|
32639
|
-
finalize =
|
|
32640
|
-
subscription =
|
|
32641
|
-
resourceGroup =
|
|
32969
|
+
watch = Option56.Boolean("--watch", false);
|
|
32970
|
+
output = Option56.String("--output");
|
|
32971
|
+
repoRoot = Option56.String("--repo-root", { description: "The m8t clone to point local tools at (default: the current directory)." });
|
|
32972
|
+
finalize = Option56.Boolean("--finalize", false, { description: "Complete the local setup against an already-done install, without watching." });
|
|
32973
|
+
subscription = Option56.String("--subscription");
|
|
32974
|
+
resourceGroup = Option56.String("--resource-group");
|
|
32642
32975
|
async executeCommand() {
|
|
32643
32976
|
const state = await readBootstrapState();
|
|
32644
32977
|
if (!state) {
|
|
@@ -32771,7 +33104,7 @@ function formatStatus(d) {
|
|
|
32771
33104
|
}
|
|
32772
33105
|
|
|
32773
33106
|
// src/commands/bootstrap/reap.ts
|
|
32774
|
-
import { Command as
|
|
33107
|
+
import { Command as Command60, Option as Option57 } from "clipanion";
|
|
32775
33108
|
init_errors();
|
|
32776
33109
|
|
|
32777
33110
|
// src/lib/bootstrap-reap.ts
|
|
@@ -32865,7 +33198,7 @@ async function reapInstaller(opts) {
|
|
|
32865
33198
|
// src/commands/bootstrap/reap.ts
|
|
32866
33199
|
var BootstrapReapCommand = class extends M8tCommand {
|
|
32867
33200
|
static paths = [["bootstrap", "reap"]];
|
|
32868
|
-
static usage =
|
|
33201
|
+
static usage = Command60.Usage({
|
|
32869
33202
|
description: "Tear down the installer scaffolding (ACI \u2192 MI \u2192 its role assignments) after a successful install.",
|
|
32870
33203
|
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.\n\n--sweep-orphans is a DIFFERENT and much broader mode: instead of reaping this install, it scans the WHOLE SUBSCRIPTION for m8t role assignments left behind by installs whose resources are gone \u2014 orphaned installer Owner-at-subscription-scope grants and orphaned gateway subscription-scope roles. It is a dry run that only lists what it found unless you also pass --yes, which deletes them.",
|
|
32871
33204
|
examples: [
|
|
@@ -32875,9 +33208,9 @@ var BootstrapReapCommand = class extends M8tCommand {
|
|
|
32875
33208
|
["\u2026and delete them", "$0 bootstrap reap --sweep-orphans --yes"]
|
|
32876
33209
|
]
|
|
32877
33210
|
});
|
|
32878
|
-
force =
|
|
32879
|
-
sweepOrphans =
|
|
32880
|
-
yes =
|
|
33211
|
+
force = Option57.Boolean("--force", false, { description: "Reap even if the install failed or never reported a status." });
|
|
33212
|
+
sweepOrphans = Option57.Boolean("--sweep-orphans", false, { description: "Subscription-wide: find m8t role assignments orphaned by earlier installs. Lists only, unless --yes." });
|
|
33213
|
+
yes = Option57.Boolean("--yes", false, { description: "With --sweep-orphans, actually delete what the sweep found." });
|
|
32881
33214
|
async executeCommand() {
|
|
32882
33215
|
if (this.sweepOrphans === true) {
|
|
32883
33216
|
const { subscriptionId: sub } = await getAzAccount();
|
|
@@ -32974,7 +33307,7 @@ Found ${String(total)} orphaned assignment(s) (${breakdown}) (dry-run). ${colors
|
|
|
32974
33307
|
import * as fs41 from "fs";
|
|
32975
33308
|
import * as os21 from "os";
|
|
32976
33309
|
import * as path46 from "path";
|
|
32977
|
-
import { Command as
|
|
33310
|
+
import { Command as Command61, Option as Option58 } from "clipanion";
|
|
32978
33311
|
import { DefaultAzureCredential as DefaultAzureCredential24 } from "@azure/identity";
|
|
32979
33312
|
init_errors();
|
|
32980
33313
|
|
|
@@ -33802,7 +34135,7 @@ function renderDeployFailure(error) {
|
|
|
33802
34135
|
}
|
|
33803
34136
|
var BootstrapUiCommand = class extends M8tCommand {
|
|
33804
34137
|
static paths = [["bootstrap", "ui"]];
|
|
33805
|
-
static usage =
|
|
34138
|
+
static usage = Command61.Usage({
|
|
33806
34139
|
description: "Deploy Ezra + start the local onboarding chat UI in the background (returns immediately).",
|
|
33807
34140
|
details: [
|
|
33808
34141
|
"Run after `m8t bootstrap launch`, in parallel with `status --watch`. Waits for the cloud",
|
|
@@ -33823,16 +34156,16 @@ var BootstrapUiCommand = class extends M8tCommand {
|
|
|
33823
34156
|
["Experimental: start the voice relay (no effect on the text-only intake)", "$0 bootstrap ui --repo-root /path/to/m8t --voice"]
|
|
33824
34157
|
]
|
|
33825
34158
|
});
|
|
33826
|
-
repoRoot =
|
|
33827
|
-
port =
|
|
33828
|
-
endpoint =
|
|
34159
|
+
repoRoot = Option58.String("--repo-root");
|
|
34160
|
+
port = Option58.String("--port", "3000");
|
|
34161
|
+
endpoint = Option58.String("--endpoint", {
|
|
33829
34162
|
description: "Foundry project endpoint to target \u2014 overrides discovery when this install's resource group holds more than one Foundry project."
|
|
33830
34163
|
});
|
|
33831
|
-
prepOnly =
|
|
33832
|
-
skipInstall =
|
|
33833
|
-
stop =
|
|
33834
|
-
foreground =
|
|
33835
|
-
voice =
|
|
34164
|
+
prepOnly = Option58.Boolean("--prep-only", false);
|
|
34165
|
+
skipInstall = Option58.Boolean("--skip-install", false);
|
|
34166
|
+
stop = Option58.Boolean("--stop", false);
|
|
34167
|
+
foreground = Option58.Boolean("--foreground", false);
|
|
34168
|
+
voice = Option58.Boolean("--voice", false, {
|
|
33836
34169
|
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."
|
|
33837
34170
|
});
|
|
33838
34171
|
async executeCommand() {
|
|
@@ -33855,7 +34188,12 @@ var BootstrapUiCommand = class extends M8tCommand {
|
|
|
33855
34188
|
hint: "Run 'm8t bootstrap launch --location <region>' first."
|
|
33856
34189
|
});
|
|
33857
34190
|
}
|
|
33858
|
-
const
|
|
34191
|
+
const explicitRoot = typeof this.repoRoot === "string" ? this.repoRoot : void 0;
|
|
34192
|
+
const repoRoot = explicitRoot ?? process.cwd();
|
|
34193
|
+
assertPlatformCheckout(repoRoot, "'m8t bootstrap ui'", ["apps/web"], {
|
|
34194
|
+
source: explicitRoot === void 0 ? "the working directory" : "--repo-root",
|
|
34195
|
+
hint: "The local onboarding chat is part of the platform's web app, which is not published, so this step is unavailable today. Nothing else is blocked: let the install finish, then run 'm8t open' to meet Ezra in your deployed web app."
|
|
34196
|
+
});
|
|
33859
34197
|
if (this.port !== "3000") {
|
|
33860
34198
|
throw new LocalCliError({
|
|
33861
34199
|
code: "BOOTSTRAP_UI_PORT_MSAL_LOCKED",
|
|
@@ -33999,10 +34337,10 @@ var BootstrapUiCommand = class extends M8tCommand {
|
|
|
33999
34337
|
};
|
|
34000
34338
|
|
|
34001
34339
|
// src/commands/bootstrap/seed-profile.ts
|
|
34002
|
-
import { Command as
|
|
34340
|
+
import { Command as Command62, Option as Option59 } from "clipanion";
|
|
34003
34341
|
var BootstrapSeedProfileCommand = class extends M8tCommand {
|
|
34004
34342
|
static paths = [["bootstrap", "seed-profile"]];
|
|
34005
|
-
static usage =
|
|
34343
|
+
static usage = Command62.Usage({
|
|
34006
34344
|
description: "Seed your advisors' brains with the founder + company profile from the onboarding intake.",
|
|
34007
34345
|
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>/ezra-brain via the GitHub App. Idempotent. --watch polls until the founder finishes the intake.",
|
|
34008
34346
|
examples: [
|
|
@@ -34010,11 +34348,11 @@ var BootstrapSeedProfileCommand = class extends M8tCommand {
|
|
|
34010
34348
|
["Wait for the founder to finish", "$0 bootstrap seed-profile --watch"]
|
|
34011
34349
|
]
|
|
34012
34350
|
});
|
|
34013
|
-
endpoint =
|
|
34014
|
-
brain =
|
|
34015
|
-
watch =
|
|
34016
|
-
timeout =
|
|
34017
|
-
githubAppCreds =
|
|
34351
|
+
endpoint = Option59.String("--endpoint", { description: "Override the Foundry endpoint (else read from the install status)." });
|
|
34352
|
+
brain = Option59.String("--brain", { description: "Seed only this one brain repo, instead of both <org>/stacey-brain and <org>/ezra-brain." });
|
|
34353
|
+
watch = Option59.Boolean("--watch", false, { description: "Poll until the intake completes (or --timeout)." });
|
|
34354
|
+
timeout = Option59.String("--timeout", { description: "Watch timeout in minutes (default 20)." });
|
|
34355
|
+
githubAppCreds = Option59.String("--github-app-creds");
|
|
34018
34356
|
async executeCommand() {
|
|
34019
34357
|
const ctx = await resolveSeedContext({
|
|
34020
34358
|
endpointOverride: typeof this.endpoint === "string" ? this.endpoint : void 0,
|
|
@@ -34077,7 +34415,7 @@ var BootstrapSeedProfileCommand = class extends M8tCommand {
|
|
|
34077
34415
|
import * as fs42 from "fs";
|
|
34078
34416
|
import * as os22 from "os";
|
|
34079
34417
|
import * as path47 from "path";
|
|
34080
|
-
import { Command as
|
|
34418
|
+
import { Command as Command63, Option as Option60 } from "clipanion";
|
|
34081
34419
|
init_errors();
|
|
34082
34420
|
|
|
34083
34421
|
// src/lib/telemetry-enroll.ts
|
|
@@ -34159,7 +34497,7 @@ async function resolveKeyVaultName(containerAppResourceId) {
|
|
|
34159
34497
|
}
|
|
34160
34498
|
var TelemetryEnrollCommand = class extends M8tCommand {
|
|
34161
34499
|
static paths = [["telemetry", "enroll"]];
|
|
34162
|
-
static usage =
|
|
34500
|
+
static usage = Command63.Usage({
|
|
34163
34501
|
description: "Enroll this installation for operational telemetry (pre-existing installs).",
|
|
34164
34502
|
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.",
|
|
34165
34503
|
examples: [
|
|
@@ -34167,11 +34505,11 @@ var TelemetryEnrollCommand = class extends M8tCommand {
|
|
|
34167
34505
|
["Enroll and share a support contact", "$0 telemetry enroll --contact-email you@example.com --company 'Acme'"]
|
|
34168
34506
|
]
|
|
34169
34507
|
});
|
|
34170
|
-
company =
|
|
34171
|
-
contactEmail =
|
|
34172
|
-
subscription =
|
|
34173
|
-
resourceGroup =
|
|
34174
|
-
force =
|
|
34508
|
+
company = Option60.String("--company", { description: "Share your company name with m8t support. Not sent unless you pass it." });
|
|
34509
|
+
contactEmail = Option60.String("--contact-email", { description: "Share a contact email with m8t support. Not sent unless you pass it." });
|
|
34510
|
+
subscription = Option60.String("--subscription", { description: "Azure subscription id used to find your deployment. Never sent to m8t." });
|
|
34511
|
+
resourceGroup = Option60.String("--resource-group", { description: "Resource group to disambiguate discovery, if you have more than one m8t deployment." });
|
|
34512
|
+
force = Option60.Boolean("--force", false, { description: "Enroll even when a key is already stored. Use only when m8t support asks you to." });
|
|
34175
34513
|
async executeCommand() {
|
|
34176
34514
|
const account = await getAzAccount();
|
|
34177
34515
|
const subscriptionId = (typeof this.subscription === "string" ? this.subscription : void 0) ?? account.subscriptionId;
|
|
@@ -34221,7 +34559,7 @@ var TelemetryEnrollCommand = class extends M8tCommand {
|
|
|
34221
34559
|
};
|
|
34222
34560
|
|
|
34223
34561
|
// src/commands/companion/bridge.ts
|
|
34224
|
-
import { Command as
|
|
34562
|
+
import { Command as Command64, Option as Option61 } from "clipanion";
|
|
34225
34563
|
|
|
34226
34564
|
// ../../packages/companion-bridge-contract/src/index.ts
|
|
34227
34565
|
var COMPANION_MESSAGE_MAX_CODE_POINTS = 32768;
|
|
@@ -35274,7 +35612,7 @@ async function runCompanionBridgeServe(stdin, stdout, stderr, deps = {}) {
|
|
|
35274
35612
|
}
|
|
35275
35613
|
|
|
35276
35614
|
// src/commands/companion/bridge.ts
|
|
35277
|
-
var
|
|
35615
|
+
var defaultDeps4 = {
|
|
35278
35616
|
roster: rosterCompanions,
|
|
35279
35617
|
send: sendCompanionMessage,
|
|
35280
35618
|
converse: converseCompanionMessage,
|
|
@@ -35309,7 +35647,7 @@ function exitFor(terminal) {
|
|
|
35309
35647
|
}
|
|
35310
35648
|
return 2;
|
|
35311
35649
|
}
|
|
35312
|
-
async function runCompanionBridge(stdin, stdout, stderr, deps =
|
|
35650
|
+
async function runCompanionBridge(stdin, stdout, stderr, deps = defaultDeps4) {
|
|
35313
35651
|
let request;
|
|
35314
35652
|
try {
|
|
35315
35653
|
request = parseRequestLine(await readSingleRequest(stdin));
|
|
@@ -35338,14 +35676,14 @@ async function runCompanionBridge(stdin, stdout, stderr, deps = defaultDeps3) {
|
|
|
35338
35676
|
return 3;
|
|
35339
35677
|
}
|
|
35340
35678
|
}
|
|
35341
|
-
var CompanionBridgeCommand = class extends
|
|
35679
|
+
var CompanionBridgeCommand = class extends Command64 {
|
|
35342
35680
|
static paths = [["companion", "_bridge"]];
|
|
35343
35681
|
/**
|
|
35344
35682
|
* One process serving many requests instead of one per request, so the
|
|
35345
35683
|
* session keeps its authenticated context between them. A CLI predating the
|
|
35346
35684
|
* flag rejects it outright, which is how the app knows to fall back.
|
|
35347
35685
|
*/
|
|
35348
|
-
serve =
|
|
35686
|
+
serve = Option61.Boolean("--serve", false);
|
|
35349
35687
|
async execute() {
|
|
35350
35688
|
if (this.serve) {
|
|
35351
35689
|
return runCompanionBridgeServe(
|
|
@@ -35363,7 +35701,7 @@ var CompanionBridgeCommand = class extends Command63 {
|
|
|
35363
35701
|
};
|
|
35364
35702
|
|
|
35365
35703
|
// src/commands/companion/status.ts
|
|
35366
|
-
import { Command as
|
|
35704
|
+
import { Command as Command65 } from "clipanion";
|
|
35367
35705
|
async function withTimeout(work, ms) {
|
|
35368
35706
|
let timer;
|
|
35369
35707
|
try {
|
|
@@ -35435,7 +35773,7 @@ Run: m8t companion install
|
|
|
35435
35773
|
}
|
|
35436
35774
|
var CompanionStatusCommand = class extends M8tCommand {
|
|
35437
35775
|
static paths = [["companion", "status"]];
|
|
35438
|
-
static usage =
|
|
35776
|
+
static usage = Command65.Usage({
|
|
35439
35777
|
description: "Verify the installed desktop companion without launching it."
|
|
35440
35778
|
});
|
|
35441
35779
|
async executeCommand() {
|
|
@@ -35449,7 +35787,7 @@ var CompanionStatusCommand = class extends M8tCommand {
|
|
|
35449
35787
|
};
|
|
35450
35788
|
|
|
35451
35789
|
// src/commands/companion/repair.ts
|
|
35452
|
-
import { Command as
|
|
35790
|
+
import { Command as Command66, Option as Option62 } from "clipanion";
|
|
35453
35791
|
async function runCompanionRepairCommand(stdout, repair) {
|
|
35454
35792
|
const state = await repair();
|
|
35455
35793
|
if (state.state === "not-released") {
|
|
@@ -35468,10 +35806,10 @@ async function runCompanionRepairCommand(stdout, repair) {
|
|
|
35468
35806
|
}
|
|
35469
35807
|
var CompanionRepairCommand = class extends M8tCommand {
|
|
35470
35808
|
static paths = [["companion", "repair"]];
|
|
35471
|
-
static usage =
|
|
35809
|
+
static usage = Command66.Usage({
|
|
35472
35810
|
description: "Restore the desktop companions and start-at-login state."
|
|
35473
35811
|
});
|
|
35474
|
-
resourceGroup =
|
|
35812
|
+
resourceGroup = Option62.String("--resource-group", {
|
|
35475
35813
|
description: "Which deployment to bind to, when the subscription holds more than one."
|
|
35476
35814
|
});
|
|
35477
35815
|
async executeCommand() {
|
|
@@ -35485,7 +35823,7 @@ var CompanionRepairCommand = class extends M8tCommand {
|
|
|
35485
35823
|
};
|
|
35486
35824
|
|
|
35487
35825
|
// src/commands/companion/uninstall.ts
|
|
35488
|
-
import { Command as
|
|
35826
|
+
import { Command as Command67 } from "clipanion";
|
|
35489
35827
|
async function runCompanionUninstallCommand(stdout, uninstall) {
|
|
35490
35828
|
const state = await uninstall();
|
|
35491
35829
|
if (state.state !== "not-installed") {
|
|
@@ -35497,7 +35835,7 @@ async function runCompanionUninstallCommand(stdout, uninstall) {
|
|
|
35497
35835
|
}
|
|
35498
35836
|
var CompanionUninstallCommand = class extends M8tCommand {
|
|
35499
35837
|
static paths = [["companion", "uninstall"]];
|
|
35500
|
-
static usage =
|
|
35838
|
+
static usage = Command67.Usage({
|
|
35501
35839
|
description: "Remove only this user's desktop companion installation."
|
|
35502
35840
|
});
|
|
35503
35841
|
async executeCommand() {
|
|
@@ -35567,6 +35905,7 @@ cli.register(A2aDisableCommand);
|
|
|
35567
35905
|
cli.register(EvalSkillCommand);
|
|
35568
35906
|
cli.register(EvalExamCommand);
|
|
35569
35907
|
cli.register(DreamRunCommand);
|
|
35908
|
+
cli.register(ConversationsSweepCommand);
|
|
35570
35909
|
cli.register(FoundryCreateCommand);
|
|
35571
35910
|
cli.register(FoundryAwaitReadyCommand);
|
|
35572
35911
|
cli.register(BootstrapPreflightCommand);
|