@m8t-stack/cli 0.2.14 → 0.2.16

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
@@ -197,6 +197,13 @@ var init_brain_eval = __esm({
197
197
  }
198
198
  });
199
199
 
200
+ // ../../packages/api-contract/dist/esm/founder-benchmark.js
201
+ var init_founder_benchmark = __esm({
202
+ "../../packages/api-contract/dist/esm/founder-benchmark.js"() {
203
+ "use strict";
204
+ }
205
+ });
206
+
200
207
  // ../../packages/api-contract/dist/esm/index.js
201
208
  var init_esm = __esm({
202
209
  "../../packages/api-contract/dist/esm/index.js"() {
@@ -212,6 +219,7 @@ var init_esm = __esm({
212
219
  init_brain_link();
213
220
  init_a2a_card();
214
221
  init_brain_eval();
222
+ init_founder_benchmark();
215
223
  }
216
224
  });
217
225
 
@@ -1198,7 +1206,7 @@ var init_enable_hosted_brain = __esm({
1198
1206
  import { Builtins, Cli } from "clipanion";
1199
1207
 
1200
1208
  // src/lib/package-version.ts
1201
- var CLI_VERSION = "0.2.14";
1209
+ var CLI_VERSION = "0.2.16";
1202
1210
 
1203
1211
  // src/lib/render-error.ts
1204
1212
  init_errors();
@@ -13197,6 +13205,18 @@ async function ghAuthLoginDevice(exec = defaultGhExec) {
13197
13205
  });
13198
13206
  }
13199
13207
  }
13208
+ async function getGhToken(exec = defaultGhExec) {
13209
+ const r = await exec("gh", ["auth", "token"]);
13210
+ const tok = r.stdout.trim();
13211
+ if (r.exitCode !== 0 || !tok) {
13212
+ throw new LocalCliError({
13213
+ code: "GH_TOKEN_FAILED",
13214
+ message: `gh auth token failed (exit ${r.exitCode.toString()}): ${(r.stderr || r.stdout).slice(0, 200)}`,
13215
+ hint: "Run `gh auth login` to authenticate the GitHub CLI."
13216
+ });
13217
+ }
13218
+ return tok;
13219
+ }
13200
13220
  async function getRepoId(owner, repo, exec = defaultGhExec) {
13201
13221
  const r = await exec("gh", ["api", `/repos/${owner}/${repo}`, "--jq", ".id"]);
13202
13222
  if (r.exitCode !== 0) {
@@ -13300,6 +13320,34 @@ async function tryOpenUrl(url, exec = defaultGhExec) {
13300
13320
  } catch {
13301
13321
  }
13302
13322
  }
13323
+ function ghRepoProbe(args) {
13324
+ const exec = args.exec ?? defaultGhExec;
13325
+ const slug = `${args.owner}/${args.repo}`;
13326
+ return {
13327
+ repoStatus: async () => {
13328
+ const r = await exec("gh", ["api", "-i", `/repos/${slug}`]);
13329
+ const combined = `${r.stdout}
13330
+ ${r.stderr}`;
13331
+ const header = /^HTTP\/[\d.]+\s+(\d{3})/m.exec(combined);
13332
+ if (header) return Number(header[1]);
13333
+ const ghErr = /\(HTTP (\d{3})\)/.exec(combined);
13334
+ if (ghErr) return Number(ghErr[1]);
13335
+ if (r.exitCode === 0) return 200;
13336
+ throw new LocalCliError({
13337
+ code: "GH_REPO_PROBE_FAILED",
13338
+ message: `gh api /repos/${slug} failed (exit ${r.exitCode.toString()}): ${(r.stderr || r.stdout).slice(0, 200)}`
13339
+ });
13340
+ },
13341
+ getFile: async (path29) => {
13342
+ const r = await exec("gh", ["api", "-H", "Accept: application/vnd.github.raw+json", `/repos/${slug}/contents/${path29}`]);
13343
+ return r.exitCode === 0 ? r.stdout : null;
13344
+ },
13345
+ isEmpty: async () => {
13346
+ const r = await exec("gh", ["api", `/repos/${slug}/contents`]);
13347
+ return r.exitCode !== 0;
13348
+ }
13349
+ };
13350
+ }
13303
13351
 
13304
13352
  // src/commands/brain/app-create.ts
13305
13353
  init_errors();
@@ -13534,6 +13582,7 @@ import { readFileSync as readFileSync6 } from "fs";
13534
13582
  import * as fs10 from "fs";
13535
13583
  import * as os4 from "os";
13536
13584
  import * as path9 from "path";
13585
+ import * as readline2 from "readline/promises";
13537
13586
  import { DefaultAzureCredential as DefaultAzureCredential4 } from "@azure/identity";
13538
13587
  init_errors();
13539
13588
 
@@ -14065,6 +14114,20 @@ function materializeBrainTree(opts) {
14065
14114
  init_errors();
14066
14115
  init_esm2();
14067
14116
  import { spawn as spawn3 } from "child_process";
14117
+ import { parse as parseYaml5 } from "yaml";
14118
+ function isM8tBrainMarker(yamlText) {
14119
+ if (!yamlText.trim()) return false;
14120
+ let parsed;
14121
+ try {
14122
+ parsed = parseYaml5(yamlText);
14123
+ } catch {
14124
+ return false;
14125
+ }
14126
+ if (!parsed || typeof parsed !== "object") return false;
14127
+ const root = parsed;
14128
+ const isObj2 = (v) => typeof v === "object" && v !== null;
14129
+ return isObj2(root.engine) || isObj2(root.processes) || isObj2(root.link);
14130
+ }
14068
14131
  async function createBlankRepo(args) {
14069
14132
  const res = await fetch(`https://api.github.com/orgs/${args.org}/repos`, {
14070
14133
  method: "POST",
@@ -14195,8 +14258,119 @@ async function commitFilesViaApp(args) {
14195
14258
  });
14196
14259
  await api(`/git/refs/heads/${args.branch}`, { method: "PATCH", body: JSON.stringify({ sha: commit.sha }) });
14197
14260
  }
14261
+ async function probeRepoState(probe) {
14262
+ const status = await probe.repoStatus();
14263
+ if (status === 404) return "absent";
14264
+ if (status !== 200) {
14265
+ throw new LocalCliError({
14266
+ code: "GH_REPO_PROBE_FAILED",
14267
+ message: `GET repo returned HTTP ${status.toString()} (expected 200 or 404)`
14268
+ });
14269
+ }
14270
+ const marker = await probe.getFile(".m8t/brain.yaml");
14271
+ if (marker !== null && isM8tBrainMarker(marker)) return "m8t-brain";
14272
+ if (await probe.isEmpty()) return "empty";
14273
+ return "foreign";
14274
+ }
14275
+ function appRepoProbe(args) {
14276
+ const doFetch = args.fetchImpl ?? fetch;
14277
+ const H = ghHeaders(args.token);
14278
+ return {
14279
+ repoStatus: async () => {
14280
+ const res = await doFetch(`${GH_API}/repos/${args.repo}`, { headers: H, signal: AbortSignal.timeout(GH_REQUEST_TIMEOUT_MS) });
14281
+ return res.status;
14282
+ },
14283
+ getFile: (path29) => readRepoFileViaApp({ token: args.token, repo: args.repo, path: path29, fetchImpl: args.fetchImpl }),
14284
+ isEmpty: async () => {
14285
+ const res = await doFetch(`${GH_API}/repos/${args.repo}/contents`, { headers: H, signal: AbortSignal.timeout(GH_REQUEST_TIMEOUT_MS) });
14286
+ return res.status === 404;
14287
+ }
14288
+ };
14289
+ }
14290
+
14291
+ // src/lib/brain-repo-collision.ts
14292
+ init_errors();
14293
+ var DEFAULT_MAX_ATTEMPTS = 20;
14294
+ function actionForState(state) {
14295
+ switch (state) {
14296
+ case "absent":
14297
+ return "create";
14298
+ case "m8t-brain":
14299
+ return "reuse";
14300
+ case "empty":
14301
+ return "adopt";
14302
+ case "foreign":
14303
+ throw new LocalCliError({
14304
+ code: "FOREIGN_REPO_COLLISION",
14305
+ message: `A repo already exists but isn't an m8t brain.`
14306
+ });
14307
+ }
14308
+ }
14309
+ function candidate(base, n) {
14310
+ return n === 1 ? base : `${base}-${n.toString()}`;
14311
+ }
14312
+ async function scan(base, classify, accept, startAt, maxAttempts) {
14313
+ for (let n = startAt; n <= maxAttempts; n++) {
14314
+ const name = candidate(base, n);
14315
+ const state = await classify(name);
14316
+ if (accept(state)) return { repoName: name, state };
14317
+ }
14318
+ throw new LocalCliError({
14319
+ code: "REPO_NAME_SCAN_EXHAUSTED",
14320
+ message: `Could not find a free repo name for "${base}" after ${maxAttempts.toString()} attempts.`
14321
+ });
14322
+ }
14323
+ async function resolveRepoCollision(args) {
14324
+ const max = args.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;
14325
+ const state = await args.classify(args.repoName);
14326
+ if (args.force === "new") {
14327
+ const found = await scan(args.repoName, args.classify, (s) => s === "absent", 1, max);
14328
+ return { repoName: found.repoName, action: "create" };
14329
+ }
14330
+ if (args.force === "reuse") {
14331
+ return { repoName: args.repoName, action: actionForState(state) };
14332
+ }
14333
+ if (state === "absent") return { repoName: args.repoName, action: "create" };
14334
+ if (args.interactive && args.prompt) {
14335
+ const choice = await args.prompt({ repoName: args.repoName, state });
14336
+ if (choice === "abort") {
14337
+ throw new LocalCliError({ code: "BRAIN_CREATE_ABORTED", message: "Aborted by the operator." });
14338
+ }
14339
+ if (choice === "new") {
14340
+ const found = await scan(args.repoName, args.classify, (s) => s !== "foreign", 2, max);
14341
+ return { repoName: found.repoName, action: actionForState(found.state) };
14342
+ }
14343
+ return { repoName: args.repoName, action: actionForState(state) };
14344
+ }
14345
+ if (state === "foreign") {
14346
+ throw new LocalCliError({
14347
+ code: "FOREIGN_REPO_COLLISION",
14348
+ message: `A repo with this name already exists but isn't an m8t brain, so it won't be touched. Rename that repo or install into a different org, then re-run.`
14349
+ });
14350
+ }
14351
+ return { repoName: args.repoName, action: actionForState(state) };
14352
+ }
14198
14353
 
14199
14354
  // src/commands/brain/create.ts
14355
+ async function promptCollision(ctx, info) {
14356
+ const rl = readline2.createInterface({ input: ctx.stdin, output: ctx.stdout });
14357
+ try {
14358
+ if (info.state === "foreign") {
14359
+ const ans2 = (await rl.question(
14360
+ `A repo "${info.repoName}" already exists but isn't an m8t brain. Create a new "${info.repoName}-2" instead? [Y/n] (n aborts) `
14361
+ )).trim().toLowerCase();
14362
+ return ans2 === "" || ans2 === "y" || ans2 === "yes" ? "new" : "abort";
14363
+ }
14364
+ const ans = (await rl.question(
14365
+ `An m8t brain "${info.repoName}" already exists. Reuse it? [Y/n] (n creates "${info.repoName}-2", or "a" aborts) `
14366
+ )).trim().toLowerCase();
14367
+ if (ans === "" || ans === "y" || ans === "yes") return "reuse";
14368
+ if (ans === "a" || ans === "abort") return "abort";
14369
+ return "new";
14370
+ } finally {
14371
+ rl.close();
14372
+ }
14373
+ }
14200
14374
  function stageAsGitRepo(dir) {
14201
14375
  const steps = [
14202
14376
  { args: ["init", "-b", "main"], label: "git init" },
@@ -14239,6 +14413,8 @@ var BrainCreateCommand = class extends M8tCommand {
14239
14413
  appId = Option17.String("--app-id", { description: "GitHub App id (no-gh path); with --app-pem/--installation-id, create the repo via the App instead of gh." });
14240
14414
  appPem = Option17.String("--app-pem", { description: "Path to the App private-key PEM (no-gh path)." });
14241
14415
  installationId = Option17.String("--installation-id", { description: "Org installation id for the App (no-gh path)." });
14416
+ reuse = Option17.Boolean("--reuse", false, { description: "If the brain repo already exists, reuse it (non-interactive). Errors if the repo isn't a valid m8t brain." });
14417
+ newName = Option17.Boolean("--new", false, { description: "If the brain repo name is taken, create a fresh suffixed repo (e.g. <name>-2) instead of reusing." });
14242
14418
  async executeCommand() {
14243
14419
  const owner = typeof this.owner === "string" ? this.owner : void 0;
14244
14420
  const worker = typeof this.worker === "string" ? this.worker : void 0;
@@ -14303,59 +14479,95 @@ var BrainCreateCommand = class extends M8tCommand {
14303
14479
  const tmpDir = fs10.mkdtempSync(path9.join(os4.tmpdir(), `m8t-brain-create-${worker}-`));
14304
14480
  let result;
14305
14481
  let resolvedInstallationId = null;
14482
+ const force = this.reuse === true ? "reuse" : this.newName === true ? "new" : void 0;
14483
+ const interactive = !useAppPath && this.context.stdout.isTTY === true;
14484
+ let token;
14485
+ let classify;
14486
+ if (useAppPath) {
14487
+ token = await mintInstallationTokenFromPem({
14488
+ appId: appIdOpt,
14489
+ privateKeyPem: readFileSync6(appPemOpt, "utf8"),
14490
+ installationId: installationIdOpt
14491
+ });
14492
+ const tok = token;
14493
+ classify = (name) => probeRepoState(appRepoProbe({ token: tok, repo: `${owner}/${name}` }));
14494
+ } else {
14495
+ classify = (name) => probeRepoState(ghRepoProbe({ owner, repo: name }));
14496
+ }
14497
+ const decision = await resolveRepoCollision({
14498
+ repoName,
14499
+ classify,
14500
+ interactive,
14501
+ force,
14502
+ prompt: interactive ? (info) => promptCollision(
14503
+ { stdin: this.context.stdin, stdout: this.context.stdout },
14504
+ info
14505
+ ) : void 0
14506
+ });
14507
+ const finalName = decision.repoName;
14508
+ const needsPush = decision.action === "create" || decision.action === "adopt";
14509
+ if (finalName !== repoName) {
14510
+ this.context.stdout.write(`${colors.hint("note:")} using repo name ${colors.field(finalName)} (${decision.action}).
14511
+ `);
14512
+ }
14306
14513
  try {
14307
- materializeBrainTree({ templateSrc, destDir: tmpDir, seedDir });
14308
- this.context.stdout.write(
14309
- seedName ? `${colors.dim("\u2192")} copied brain-template/ + overlaid seed ${colors.field(seedName)} to ${tmpDir}
14514
+ if (needsPush) {
14515
+ materializeBrainTree({ templateSrc, destDir: tmpDir, seedDir });
14516
+ this.context.stdout.write(
14517
+ seedName ? `${colors.dim("\u2192")} copied brain-template/ + overlaid seed ${colors.field(seedName)} to ${tmpDir}
14310
14518
  ` : `${colors.dim("\u2192")} copied brain-template/ to ${tmpDir}
14311
14519
  `
14312
- );
14520
+ );
14521
+ }
14313
14522
  if (useAppPath) {
14314
- this.context.stdout.write(`${colors.dim("\u2192")} creating ${owner}/${repoName} via the GitHub App (no gh)\u2026
14523
+ const appToken = token ?? "";
14524
+ if (decision.action === "create") {
14525
+ this.context.stdout.write(`${colors.dim("\u2192")} creating ${owner}/${finalName} via the GitHub App (no gh)\u2026
14526
+ `);
14527
+ await createBlankRepo({ token: appToken, org: owner, name: finalName, private: !this.public_ });
14528
+ await pushSeed({ token: appToken, org: owner, name: finalName, branch, sourceDir: tmpDir });
14529
+ this.context.stdout.write(`${colors.success("\u2713")} repo created + seeded via the App
14530
+ `);
14531
+ } else if (decision.action === "adopt") {
14532
+ this.context.stdout.write(`${colors.dim("\u2192")} seeding the existing empty repo ${owner}/${finalName} via the GitHub App\u2026
14533
+ `);
14534
+ await pushSeed({ token: appToken, org: owner, name: finalName, branch, sourceDir: tmpDir });
14535
+ this.context.stdout.write(`${colors.success("\u2713")} empty repo seeded via the App
14536
+ `);
14537
+ } else {
14538
+ this.context.stdout.write(`${colors.success("\u2713")} reusing the existing brain ${owner}/${finalName}
14315
14539
  `);
14316
- const pem = readFileSync6(appPemOpt, "utf8");
14317
- const appJwt = signAppJwt({ appId: appIdOpt, privateKeyPem: pem });
14318
- const tokRes = await fetch(
14319
- `https://api.github.com/app/installations/${installationIdOpt}/access_tokens`,
14320
- {
14321
- method: "POST",
14322
- headers: {
14323
- Authorization: `Bearer ${appJwt}`,
14324
- Accept: "application/vnd.github+json",
14325
- "X-GitHub-Api-Version": "2022-11-28",
14326
- "User-Agent": "m8t"
14327
- }
14328
- }
14329
- );
14330
- if (!tokRes.ok) {
14331
- throw new LocalCliError({
14332
- code: "GH_APP_TOKEN_FAILED",
14333
- message: `mint installation token HTTP ${tokRes.status.toString()}: ${(await tokRes.text()).slice(0, 300)}`
14334
- });
14335
14540
  }
14336
- const token = (await tokRes.json()).token;
14337
- await createBlankRepo({ token, org: owner, name: repoName, private: !this.public_ });
14338
- await pushSeed({ token, org: owner, name: repoName, branch, sourceDir: tmpDir });
14339
14541
  resolvedInstallationId = installationIdOpt;
14340
- this.context.stdout.write(`${colors.success("\u2713")} repo created + seeded via the App
14341
- `);
14342
14542
  } else {
14343
- stageAsGitRepo(tmpDir);
14344
- this.context.stdout.write(`${colors.dim("\u2192")} creating repo ${owner}/${repoName} (${this.public_ ? "public" : "private"})\u2026
14543
+ if (decision.action === "create") {
14544
+ stageAsGitRepo(tmpDir);
14545
+ this.context.stdout.write(`${colors.dim("\u2192")} creating repo ${owner}/${finalName} (${this.public_ ? "public" : "private"})\u2026
14546
+ `);
14547
+ await createRepo({ owner, name: finalName, private: !this.public_, source: tmpDir });
14548
+ this.context.stdout.write(`${colors.success("\u2713")} repo created
14549
+ `);
14550
+ } else if (decision.action === "adopt") {
14551
+ this.context.stdout.write(`${colors.dim("\u2192")} seeding the existing empty repo ${owner}/${finalName}\u2026
14345
14552
  `);
14346
- await createRepo({ owner, name: repoName, private: !this.public_, source: tmpDir });
14347
- this.context.stdout.write(`${colors.success("\u2713")} repo created
14553
+ const ghToken = await getGhToken();
14554
+ await pushSeed({ token: ghToken, org: owner, name: finalName, branch, sourceDir: tmpDir });
14555
+ this.context.stdout.write(`${colors.success("\u2713")} empty repo seeded
14348
14556
  `);
14349
- const repoId = await getRepoId(owner, repoName);
14557
+ } else {
14558
+ this.context.stdout.write(`${colors.success("\u2713")} reusing the existing brain ${owner}/${finalName}
14559
+ `);
14560
+ }
14561
+ const repoId = await getRepoId(owner, finalName);
14350
14562
  const { slug, appId: secretAppId, privateKeyPem } = await readAppSecrets({ credential: credential2, kvUri });
14351
14563
  const initialJwt = signAppJwt({ appId: secretAppId, privateKeyPem });
14352
- resolvedInstallationId = await probeAppInstallation({ owner, repo: repoName, jwt: initialJwt });
14564
+ resolvedInstallationId = await probeAppInstallation({ owner, repo: finalName, jwt: initialJwt });
14353
14565
  if (resolvedInstallationId) {
14354
- this.context.stdout.write(` ${colors.success("\u2713")} App already installed on ${colors.field(`${owner}/${repoName}`)} (installation ${resolvedInstallationId}); skipping browser open.
14566
+ this.context.stdout.write(` ${colors.success("\u2713")} App already installed on ${colors.field(`${owner}/${finalName}`)} (installation ${resolvedInstallationId}); skipping browser open.
14355
14567
  `);
14356
14568
  } else {
14357
14569
  const url = installUrl(slug, repoId);
14358
- this.context.stdout.write(`${colors.field("\u2192")} Install the m8t-brain App on ${owner}/${repoName}:
14570
+ this.context.stdout.write(`${colors.field("\u2192")} Install the m8t-brain App on ${owner}/${finalName}:
14359
14571
  ${url}
14360
14572
  `);
14361
14573
  await tryOpenUrl(url);
@@ -14363,10 +14575,10 @@ var BrainCreateCommand = class extends M8tCommand {
14363
14575
  `);
14364
14576
  resolvedInstallationId = await pollForInstallation({
14365
14577
  owner,
14366
- repo: repoName,
14578
+ repo: finalName,
14367
14579
  // Mint fresh JWT each tick — App JWTs are 10-min TTL, poll defaults to 5 min
14368
14580
  // but the timeout is a soft default, so don't depend on the inequality.
14369
- probe: () => probeAppInstallation({ owner, repo: repoName, jwt: signAppJwt({ appId: secretAppId, privateKeyPem }) }),
14581
+ probe: () => probeAppInstallation({ owner, repo: finalName, jwt: signAppJwt({ appId: secretAppId, privateKeyPem }) }),
14370
14582
  onTick: (n) => {
14371
14583
  if (n % 5 === 0) this.context.stderr.write(` ${colors.dim(`\u2026still waiting (${(n * 2).toString()}s)`)}
14372
14584
  `);
@@ -14382,7 +14594,7 @@ var BrainCreateCommand = class extends M8tCommand {
14382
14594
  projectEndpoint: project.endpoint,
14383
14595
  projectArmId: `${project.accountScope}/projects/${project.projectName}`,
14384
14596
  agentName: worker,
14385
- repo: `${owner}/${repoName}`,
14597
+ repo: `${owner}/${finalName}`,
14386
14598
  branch,
14387
14599
  repoRoot,
14388
14600
  installationId: resolvedInstallationId,
@@ -14396,7 +14608,7 @@ var BrainCreateCommand = class extends M8tCommand {
14396
14608
  this.context.stdout.write(
14397
14609
  renderJson({
14398
14610
  worker,
14399
- repo: `${owner}/${repoName}`,
14611
+ repo: `${owner}/${finalName}`,
14400
14612
  branch,
14401
14613
  installationId: resolvedInstallationId,
14402
14614
  connectionName: result.connectionName,
@@ -14406,10 +14618,10 @@ var BrainCreateCommand = class extends M8tCommand {
14406
14618
  return 0;
14407
14619
  }
14408
14620
  this.context.stdout.write(
14409
- `${colors.success("\u2713")} created + linked ${colors.field(worker)} \u2194 ${colors.field(`${owner}/${repoName}`)} (agent version ${result.foundryVersion ?? ""}).
14621
+ `${colors.success("\u2713")} created + linked ${colors.field(worker)} \u2194 ${colors.field(`${owner}/${finalName}`)} (agent version ${result.foundryVersion ?? ""}).
14410
14622
  `
14411
14623
  );
14412
- this.context.stdout.write(` ${colors.hint("brain repo:")} https://github.com/${owner}/${repoName}
14624
+ this.context.stdout.write(` ${colors.hint("brain repo:")} https://github.com/${owner}/${finalName}
14413
14625
  `);
14414
14626
  this.context.stdout.write(` ${colors.hint("token:")} rotates lazily on every invoke (60min TTL, 10min safety margin).
14415
14627
  `);
@@ -15010,7 +15222,7 @@ init_errors();
15010
15222
  // src/lib/deploy-prompt-advisor.ts
15011
15223
  import * as fs12 from "fs";
15012
15224
  import * as path11 from "path";
15013
- import { parse as parseYaml5 } from "yaml";
15225
+ import { parse as parseYaml6 } from "yaml";
15014
15226
  init_foundry_agents();
15015
15227
  init_errors();
15016
15228
  function findPersonasRoot(hint) {
@@ -15038,7 +15250,7 @@ async function deployPromptAdvisor(args) {
15038
15250
  });
15039
15251
  }
15040
15252
  const fmMatch = /^---\n([\s\S]*?)\n---/.exec(raw);
15041
- const fm = fmMatch ? parseYaml5(fmMatch[1]) : {};
15253
+ const fm = fmMatch ? parseYaml6(fmMatch[1]) : {};
15042
15254
  const model = args.model ?? fm.targets?.foundry?.model;
15043
15255
  if (!model) {
15044
15256
  throw new LocalCliError({
@@ -15305,7 +15517,7 @@ async function awaitAgentQueryable(args) {
15305
15517
  init_errors();
15306
15518
  init_esm();
15307
15519
  import * as fs13 from "fs";
15308
- import { parse as parseYaml6 } from "yaml";
15520
+ import { parse as parseYaml7 } from "yaml";
15309
15521
  function readPersonaA2aCard(personaPath) {
15310
15522
  let raw;
15311
15523
  try {
@@ -15315,7 +15527,7 @@ function readPersonaA2aCard(personaPath) {
15315
15527
  }
15316
15528
  const fm = /^---\n([\s\S]*?)\n---/.exec(raw);
15317
15529
  if (!fm) throw new LocalCliError({ code: "PERSONA_NO_FRONTMATTER", message: `Persona '${personaPath}' has no frontmatter.` });
15318
- const front = parseYaml6(fm[1]);
15530
+ const front = parseYaml7(fm[1]);
15319
15531
  const role = typeof front.role === "string" ? front.role : "";
15320
15532
  const cardYaml = front.targets?.foundry?.["a2a-card"];
15321
15533
  if (!cardYaml || typeof cardYaml !== "object") {
@@ -15801,7 +16013,7 @@ init_errors();
15801
16013
  import * as fs15 from "fs";
15802
16014
  import * as os6 from "os";
15803
16015
  import * as path12 from "path";
15804
- import { parse as parseYaml7 } from "yaml";
16016
+ import { parse as parseYaml8 } from "yaml";
15805
16017
  var A2A_PATH = "/api/a2a/mcp";
15806
16018
  function resolveBridgeUrl(opts) {
15807
16019
  const env = opts.env ?? process.env;
@@ -15825,7 +16037,7 @@ function readConfigGatewayUrl(home) {
15825
16037
  const cfg = path12.join(home ?? os6.homedir(), ".m8t-stack", "config.yaml");
15826
16038
  if (!fs15.existsSync(cfg)) return void 0;
15827
16039
  try {
15828
- const o = parseYaml7(fs15.readFileSync(cfg, "utf8"));
16040
+ const o = parseYaml8(fs15.readFileSync(cfg, "utf8"));
15829
16041
  return typeof o.gatewayUrl === "string" ? o.gatewayUrl : void 0;
15830
16042
  } catch {
15831
16043
  return void 0;
@@ -16327,7 +16539,7 @@ async function deployHostedWorker(args) {
16327
16539
  // src/lib/persona.ts
16328
16540
  import * as fs17 from "fs";
16329
16541
  import * as path15 from "path";
16330
- import { parse as parseYaml8 } from "yaml";
16542
+ import { parse as parseYaml9 } from "yaml";
16331
16543
  function findRepoRoot(startDir) {
16332
16544
  let dir = path15.resolve(startDir);
16333
16545
  for (; ; ) {
@@ -16351,7 +16563,7 @@ function resolvePersona(persona, cwd = process.cwd()) {
16351
16563
  if (!match) return { persona, personaVersion: null };
16352
16564
  let fm = null;
16353
16565
  try {
16354
- fm = parseYaml8(match[1]);
16566
+ fm = parseYaml9(match[1]);
16355
16567
  } catch {
16356
16568
  return { persona, personaVersion: null };
16357
16569
  }
@@ -18256,9 +18468,9 @@ var EvalSkillCommand = class extends M8tCommand {
18256
18468
  return Promise.resolve(this._runCommand());
18257
18469
  }
18258
18470
  _runCommand() {
18259
- const candidate = typeof this.candidate === "string" ? this.candidate : void 0;
18471
+ const candidate2 = typeof this.candidate === "string" ? this.candidate : void 0;
18260
18472
  const skillsDir = typeof this.skillsDir === "string" ? this.skillsDir : void 0;
18261
- if (!candidate) {
18473
+ if (!candidate2) {
18262
18474
  throw new LocalCliError({ code: "USAGE", message: "<path> positional argument is required" });
18263
18475
  }
18264
18476
  if (!skillsDir) {
@@ -18267,7 +18479,7 @@ var EvalSkillCommand = class extends M8tCommand {
18267
18479
  const outputFlag = this.output === "json" || this.output === "auto" || this.output === "pretty" ? this.output : "pretty";
18268
18480
  const mode = resolveOutputMode(outputFlag, this.context.stdout);
18269
18481
  const bin = process.env.BRAIN_EVAL_BIN ?? "brain-eval";
18270
- const args = ["skill", candidate, "--skills-dir", skillsDir, "--json"];
18482
+ const args = ["skill", candidate2, "--skills-dir", skillsDir, "--json"];
18271
18483
  if (this.noJudge === true) args.push("--no-judge");
18272
18484
  if (typeof this.deployment === "string") args.push("--deployment", this.deployment);
18273
18485
  const res = spawnSync3(bin, args, { encoding: "utf-8" });
@@ -19256,7 +19468,7 @@ import { Command as Command41, Option as Option39 } from "clipanion";
19256
19468
  // src/lib/profiles.ts
19257
19469
  import * as fs20 from "fs/promises";
19258
19470
  import * as path21 from "path";
19259
- import { parse as parseYaml9, stringify as stringifyYaml4 } from "yaml";
19471
+ import { parse as parseYaml10, stringify as stringifyYaml4 } from "yaml";
19260
19472
  function profilesDir() {
19261
19473
  const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
19262
19474
  return path21.join(home, ".m8t-stack", "profiles");
@@ -19281,7 +19493,7 @@ async function listProfiles() {
19281
19493
  async function readProfile(name) {
19282
19494
  try {
19283
19495
  const raw = await fs20.readFile(getProfilePath(name), "utf8");
19284
- const parsed = parseYaml9(raw);
19496
+ const parsed = parseYaml10(raw);
19285
19497
  if (!parsed || typeof parsed !== "object") return null;
19286
19498
  return parsed;
19287
19499
  } catch (e) {
@@ -20451,16 +20663,16 @@ function buildAdvancePlan(worker, cursor, physicalPks, consumedRowsByPk, failedT
20451
20663
  for (const pk of physicalPks) {
20452
20664
  const rowsForPk = consumedRowsByPk[pk] ?? [];
20453
20665
  const { ts, consumedRowKeys } = computeWatermark(rowsForPk, now.toISOString(), safetyLagSeconds);
20454
- let candidate = ts;
20666
+ let candidate2 = ts;
20455
20667
  const prior = Object.hasOwn(cursor.watermarks, pk) ? cursor.watermarks[pk].ts : void 0;
20456
20668
  if (prior)
20457
20669
  priorTsByPk[pk] = prior;
20458
- if (prior && candidate < prior)
20459
- candidate = prior;
20670
+ if (prior && candidate2 < prior)
20671
+ candidate2 = prior;
20460
20672
  const failed = failedTsByPk[pk];
20461
- if (failed && candidate >= failed)
20462
- candidate = justBefore(failed);
20463
- watermarks[pk] = { ts: candidate, consumedRowKeys };
20673
+ if (failed && candidate2 >= failed)
20674
+ candidate2 = justBefore(failed);
20675
+ watermarks[pk] = { ts: candidate2, consumedRowKeys };
20464
20676
  consumedKeysByPk[pk] = consumedRowKeys;
20465
20677
  }
20466
20678
  return {
@@ -20854,12 +21066,12 @@ function validateDelta(d) {
20854
21066
  }
20855
21067
  function extractJson(text) {
20856
21068
  const fenced = /```(?:json)?\s*([\s\S]*?)```/.exec(text);
20857
- const candidate = (fenced ? fenced[1] : text).trim();
20858
- const start = candidate.indexOf("{");
20859
- const end = candidate.lastIndexOf("}");
21069
+ const candidate2 = (fenced ? fenced[1] : text).trim();
21070
+ const start = candidate2.indexOf("{");
21071
+ const end = candidate2.lastIndexOf("}");
20860
21072
  if (start === -1 || end === -1 || end < start)
20861
21073
  throw new Error("no JSON object found");
20862
- return JSON.parse(candidate.slice(start, end + 1));
21074
+ return JSON.parse(candidate2.slice(start, end + 1));
20863
21075
  }
20864
21076
  async function propose(model, system, user, opts = {}) {
20865
21077
  const sleep2 = opts.sleep ?? defaultSleep2;
@@ -21439,14 +21651,14 @@ function narrowAdvance(src, kept) {
21439
21651
  for (const pk of Object.keys(src.watermarks)) {
21440
21652
  const rows = keptRowsByPk[pk] ?? [];
21441
21653
  const { ts, consumedRowKeys } = computeWatermark(rows, now, safetyLagSeconds);
21442
- let candidate = ts;
21654
+ let candidate2 = ts;
21443
21655
  const prior = priorTsByPk[pk];
21444
- if (prior && candidate < prior)
21445
- candidate = prior;
21656
+ if (prior && candidate2 < prior)
21657
+ candidate2 = prior;
21446
21658
  const failed = src.failedTsByPk[pk];
21447
- if (failed && candidate >= failed)
21448
- candidate = justBefore(failed);
21449
- watermarks[pk] = { ts: candidate, consumedRowKeys };
21659
+ if (failed && candidate2 >= failed)
21660
+ candidate2 = justBefore(failed);
21661
+ watermarks[pk] = { ts: candidate2, consumedRowKeys };
21450
21662
  consumedRowsByPk[pk] = consumedRowKeys;
21451
21663
  }
21452
21664
  return {
@@ -21548,7 +21760,7 @@ async function emitDigest(input, deps, digest) {
21548
21760
  }
21549
21761
 
21550
21762
  // ../../packages/brain/engine/dist/esm/dream/config.js
21551
- import { parse as parseYaml10 } from "yaml";
21763
+ import { parse as parseYaml11 } from "yaml";
21552
21764
  var DEFAULT_DREAM_MODEL = "gpt-5.4";
21553
21765
  function asCadence(v) {
21554
21766
  return v === "nightly" ? "nightly" : "off";
@@ -21556,7 +21768,7 @@ function asCadence(v) {
21556
21768
  function parseDreamerConfig(rawYaml, env) {
21557
21769
  let parsed;
21558
21770
  try {
21559
- parsed = parseYaml10(rawYaml);
21771
+ parsed = parseYaml11(rawYaml);
21560
21772
  } catch {
21561
21773
  return { enabled: false, cadence: "off", model: env.M8T_DREAM_MODEL ?? DEFAULT_DREAM_MODEL };
21562
21774
  }
@@ -21570,16 +21782,16 @@ function parseDreamerConfig(rawYaml, env) {
21570
21782
  }
21571
21783
 
21572
21784
  // ../../packages/brain/engine/dist/esm/cost-report/config.js
21573
- import { parse as parseYaml11 } from "yaml";
21785
+ import { parse as parseYaml12 } from "yaml";
21574
21786
 
21575
21787
  // ../../packages/brain/engine/dist/esm/librarian/codify/persistence-guard.js
21576
21788
  var ZERO_WIDTH_RE = new RegExp("\u200B|\u200C|\u200D|\uFEFF", "g");
21577
21789
 
21578
21790
  // ../../packages/brain/engine/dist/esm/librarian/janitor/frontmatter.js
21579
- import { parse as parseYaml12, stringify as stringifyYaml5 } from "yaml";
21791
+ import { parse as parseYaml13, stringify as stringifyYaml5 } from "yaml";
21580
21792
 
21581
21793
  // ../../packages/brain/engine/dist/esm/librarian/config.js
21582
- import { parse as parseYaml13 } from "yaml";
21794
+ import { parse as parseYaml14 } from "yaml";
21583
21795
 
21584
21796
  // src/lib/dream-discovery.ts
21585
21797
  init_http();