@m8t-stack/cli 0.2.25 → 0.2.27

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 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.25";
1250
+ var CLI_VERSION = "0.2.27";
1251
1251
 
1252
1252
  // src/lib/render-error.ts
1253
1253
  init_errors();
@@ -16465,6 +16465,67 @@ function readVersionFrontmatter(file) {
16465
16465
  function sha256File(filePath) {
16466
16466
  return createHash2("sha256").update(fs17.readFileSync(filePath)).digest("hex");
16467
16467
  }
16468
+ var SIDECAR_FILENAME = "m8t-architect.m8t-skill.json";
16469
+ var LEGACY_SIDECAR_FILENAME = ".m8t-skill.json";
16470
+ function vsCodeUserDataDir() {
16471
+ if (process.platform === "darwin") {
16472
+ return path15.join(os7.homedir(), "Library", "Application Support", "Code", "User");
16473
+ }
16474
+ if (process.platform === "win32") {
16475
+ const appData = process.env.APPDATA ?? path15.join(os7.homedir(), "AppData", "Roaming");
16476
+ return path15.join(appData, "Code", "User");
16477
+ }
16478
+ return null;
16479
+ }
16480
+ function vsCodePromptsDir() {
16481
+ const userData = vsCodeUserDataDir();
16482
+ if (!userData) return null;
16483
+ const prompts = path15.join(userData, "prompts");
16484
+ if (fs17.existsSync(prompts)) return prompts;
16485
+ const promptFiles = path15.join(userData, "prompt-files");
16486
+ if (fs17.existsSync(promptFiles)) return promptFiles;
16487
+ return prompts;
16488
+ }
16489
+ var COPILOT_CLI_SKILLS_ROOTS = [
16490
+ [".copilot", "skills"],
16491
+ [".config", "github-copilot", "skills"],
16492
+ [".github", "copilot", "skills"]
16493
+ ];
16494
+ function sidecarLocations() {
16495
+ const home = os7.homedir();
16496
+ const locations = [
16497
+ { host: "Claude Code", dir: path15.join(home, ".claude", "skills", "m8t-architect") }
16498
+ ];
16499
+ const vsCodeDir = vsCodePromptsDir();
16500
+ if (vsCodeDir) {
16501
+ locations.push({ host: "VS Code Copilot Chat", dir: vsCodeDir });
16502
+ }
16503
+ for (const segments of COPILOT_CLI_SKILLS_ROOTS) {
16504
+ locations.push({
16505
+ host: "GitHub Copilot CLI",
16506
+ dir: path15.join(home, ...segments, "m8t-architect")
16507
+ });
16508
+ }
16509
+ return locations;
16510
+ }
16511
+ function resolveSidecar() {
16512
+ let best = null;
16513
+ for (const loc of sidecarLocations()) {
16514
+ for (const filename of [SIDECAR_FILENAME, LEGACY_SIDECAR_FILENAME]) {
16515
+ const candidate2 = path15.join(loc.dir, filename);
16516
+ let mtimeMs;
16517
+ try {
16518
+ mtimeMs = fs17.statSync(candidate2).mtimeMs;
16519
+ } catch {
16520
+ continue;
16521
+ }
16522
+ if (!best || mtimeMs > best.mtimeMs) {
16523
+ best = { path: candidate2, host: loc.host, mtimeMs };
16524
+ }
16525
+ }
16526
+ }
16527
+ return best;
16528
+ }
16468
16529
  function checkArchitectDrift() {
16469
16530
  const sourcePath = path15.join(
16470
16531
  resolveRepoRoot(),
@@ -16472,13 +16533,6 @@ function checkArchitectDrift() {
16472
16533
  "m8t-architect",
16473
16534
  "persona.md"
16474
16535
  );
16475
- const sidecarPath = path15.join(
16476
- os7.homedir(),
16477
- ".claude",
16478
- "skills",
16479
- "m8t-architect",
16480
- ".m8t-skill.json"
16481
- );
16482
16536
  if (!fs17.existsSync(sourcePath)) {
16483
16537
  return {
16484
16538
  match: false,
@@ -16488,10 +16542,11 @@ function checkArchitectDrift() {
16488
16542
  };
16489
16543
  }
16490
16544
  const sourceVersion = readVersionFrontmatter(sourcePath);
16545
+ const resolved = resolveSidecar();
16491
16546
  let sidecar = null;
16492
- if (fs17.existsSync(sidecarPath)) {
16547
+ if (resolved) {
16493
16548
  try {
16494
- const raw = JSON.parse(fs17.readFileSync(sidecarPath, "utf8"));
16549
+ const raw = JSON.parse(fs17.readFileSync(resolved.path, "utf8"));
16495
16550
  if (raw !== null && typeof raw === "object") {
16496
16551
  const r = raw;
16497
16552
  sidecar = {
@@ -16504,11 +16559,12 @@ function checkArchitectDrift() {
16504
16559
  }
16505
16560
  }
16506
16561
  if (!sidecar || typeof sidecar.sourceSha256 !== "string") {
16562
+ const checked = sidecarLocations().map((l) => `${l.host} (${l.dir})`).join("; ");
16507
16563
  return {
16508
16564
  match: false,
16509
16565
  sourceVersion,
16510
16566
  installedVersion: "",
16511
- advice: "Architect skill not installed (or installed before sidecar support). Run `bash guides/install/m8t.md` to render it."
16567
+ advice: `Architect skill not installed (or installed before sidecar support). Checked: ${checked}. Re-run the install guide for your host from guides/install/m8t.md to render it.`
16512
16568
  };
16513
16569
  }
16514
16570
  const installedVersion = typeof sidecar.version === "string" ? sidecar.version : "";
@@ -16521,7 +16577,7 @@ function checkArchitectDrift() {
16521
16577
  match: false,
16522
16578
  sourceVersion,
16523
16579
  installedVersion,
16524
- advice: sameVersion ? `m8t-architect content drift (v${sourceVersion} unchanged, body edited since render). Re-render via \`bash guides/install/m8t.md\`.` : `Installed m8t-architect${installedVersion ? ` (v${installedVersion})` : ""} is out of date with source${sourceVersion ? ` (v${sourceVersion})` : ""}. Run \`bash guides/install/m8t.md\` to re-render.`
16580
+ advice: sameVersion ? `m8t-architect content drift (v${sourceVersion} unchanged, body edited since render). Re-render via the install guide for your host (guides/install/m8t.md).` : `Installed m8t-architect${installedVersion ? ` (v${installedVersion})` : ""} is out of date with source${sourceVersion ? ` (v${sourceVersion})` : ""}. Re-render via the install guide for your host (guides/install/m8t.md).`
16525
16581
  };
16526
16582
  }
16527
16583
 
@@ -16530,7 +16586,7 @@ var ArchitectCheckCommand = class extends M8tCommand {
16530
16586
  static paths = [["architect-check"]];
16531
16587
  static usage = Command27.Usage({
16532
16588
  description: "Verify the installed m8t-architect persona matches the repo source.",
16533
- details: "Compares a render-time content hash (stored in ~/.claude/skills/m8t-architect/.m8t-skill.json) 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.",
16589
+ 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.",
16534
16590
  examples: [
16535
16591
  ["Run the architect drift check", "$0 architect-check"]
16536
16592
  ]
@@ -20660,6 +20716,19 @@ async function ensureAppReg(opts) {
20660
20716
  await ensureExposeAnApi(created.appId, created.id);
20661
20717
  return { tenantId: opts.tenantId, clientId: created.appId, appObjectId: created.id };
20662
20718
  }
20719
+ async function ensureGatewayRedirectUri(gatewayClientId, fqdn) {
20720
+ const appObjectId = await azJson(
20721
+ ["ad", "app", "show", "--id", gatewayClientId, "--query", "id", "--output", "json"]
20722
+ );
20723
+ if (!appObjectId) {
20724
+ throw new LocalCliError({
20725
+ code: "APP_REG_OBJECT_ID_MISSING",
20726
+ message: `Could not resolve the object ID for app registration ${gatewayClientId}.`,
20727
+ hint: "You need directory read access to the app registration the gateway signs in against."
20728
+ });
20729
+ }
20730
+ await patchRedirectUris(appObjectId, fqdn);
20731
+ }
20663
20732
  async function patchRedirectUris(appObjectId, fqdn) {
20664
20733
  const targetUri = `https://${fqdn}`;
20665
20734
  const existing = await azJson(
@@ -26473,6 +26542,20 @@ var BootstrapFinishCommand = class extends M8tCommand {
26473
26542
 
26474
26543
  `
26475
26544
  );
26545
+ try {
26546
+ await ensureGatewayRedirectUri(d.gatewayClientId, new URL(d.gatewayUrl).host);
26547
+ } catch (e) {
26548
+ const err = e;
26549
+ this.context.stderr.write(
26550
+ ` ${colors.error("\u26A0 could not authorize sign-in for your webapp:")} ${err.message}
26551
+ ${colors.hint(`Until this is fixed, opening ${d.gatewayUrl} will fail with AADSTS50011 (redirect URI mismatch).`)}
26552
+ ${colors.hint("Ask a directory admin to run:")}
26553
+ ${colors.hint(` m8t bootstrap finish --repo-root ${repoRoot} # (as an admin), or by hand:`)}
26554
+ ${colors.hint(` az ad app update --id ${d.gatewayClientId} --set spa.redirectUris="['${d.gatewayUrl}']" # (merge, do not overwrite)`)}
26555
+
26556
+ `
26557
+ );
26558
+ }
26476
26559
  } catch (e) {
26477
26560
  const err = e;
26478
26561
  this.context.stdout.write(`${colors.success("\u2705 The platform is live.")}
@@ -26493,8 +26576,10 @@ var BootstrapFinishCommand = class extends M8tCommand {
26493
26576
  }
26494
26577
  this.context.stdout.write(renderInstallSummary({ webappUrl, brainOrg }) + "\n");
26495
26578
  this.context.stdout.write(
26496
- `${colors.field("Finish wiring your coding agent:")}
26497
- \u2022 Render the m8t personas + MCP into your host \u2014 follow guides/install/m8t.md (step 4) and, optionally, guides/install/m8t-stack.md (step 5).
26579
+ `${colors.field("Optional local tooling for your coding agent:")}
26580
+ \u2022 Talk to your deployed workers from agent sessions (e.g. /stacey) \u2014 install the m8t-stack plugin: guides/install/m8t-stack.md.
26581
+ \u2022 Azure-capable MCP servers (microsoft/azure-skills, Microsoft Learn) \u2014 see the optional steps in guides/install.md.
26582
+ \u2022 Deploy workers conversationally with the opt-in persona skills \u2014 see guides/workers.md.
26498
26583
  \u2022 Make sure your m8t CLI is current: npm i -g @m8t-stack/cli@latest
26499
26584
 
26500
26585
  ${colors.field("Then open a brand new chat/session")} \u2014 new skills + MCP servers load only on a fresh start.