mason-context 0.17.1 → 0.17.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.17.2 — 2026-09-15
4
+
5
+ - Show progress during standalone installation, upgrades, and project setup, with native download progress and elapsed-time spinners in interactive terminals. Keep redirected progress on stderr and JSON, MCP, and hook output unchanged.
6
+ - Offer Codex and Claude Code setup instructions without assuming an assistant. Show the previous and installed version after an update and remind users to restart running assistants.
7
+
8
+ Run `mason upgrade` for standalone installations, or `npm install -g mason-context@0.17.2` for npm installations, then restart running assistants. Existing project integrations do not need setup again for this release. The first upgrade from an older version still uses its bundled downloader; the new download display appears on subsequent upgrades and fresh installations.
9
+
3
10
  ## 0.17.1 — 2026-09-15
4
11
 
5
12
  - Keep MCP available in fresh clones, with actionable setup instructions and inactive automatic hooks until local setup. Preserve corrupt-setup diagnostics and checkout-specific activation.
@@ -2996,7 +2996,7 @@ var init_evidence = __esm({
2996
2996
  init_storage();
2997
2997
  init_advisory_review();
2998
2998
  exec7 = promisify9(execFile9);
2999
- engineVersion = true ? "0.17.1" : "development";
2999
+ engineVersion = true ? "0.17.2" : "development";
3000
3000
  hash = (value) => createHash3("sha256").update(JSON.stringify(value)).digest("hex");
3001
3001
  content = readAuditInput;
3002
3002
  cacheSchema = z8.object({ version: z8.literal(1), entries: z8.record(z8.object({ key: z8.string(), result: checkResultSchema })), digest: z8.string() });
@@ -3650,7 +3650,7 @@ var init_launcher = __esm({
3650
3650
  "use strict";
3651
3651
  init_evidence();
3652
3652
  init_model();
3653
- executingVersion = () => true ? "0.17.1" : "development";
3653
+ executingVersion = () => true ? "0.17.2" : "development";
3654
3654
  mcpCommand = (host) => globalCommand(["--setup-host", host, "mcp"]);
3655
3655
  hookCommand = (host) => `mason --setup-host ${host} auto`;
3656
3656
  }
@@ -5491,6 +5491,7 @@ async function selectHost(root, explicit) {
5491
5491
  throw new Error("Choose the assistant for setup with --host codex or --host claude.");
5492
5492
  }
5493
5493
  async function setupProject(dir, options = {}) {
5494
+ options.progress?.step("Checking project configuration");
5494
5495
  const ws = await workspace(dir);
5495
5496
  const host = await selectHost(ws.root, options.host);
5496
5497
  return withLock(ws.root, ".mason/reports/setup-lock", async () => {
@@ -5519,11 +5520,14 @@ async function setupProject(dir, options = {}) {
5519
5520
  const revision = !changed && previous ? previous.revision : randomUUID6();
5520
5521
  const setup = existing ?? { version: 2, hosts: {} };
5521
5522
  setup.hosts[host] = { configuredVersion: installed.version, revision, fingerprint, mcpFingerprint, instructions: instructions.map((e) => e.path) };
5523
+ options.progress?.step("Auditing documentation and preserving original findings");
5522
5524
  const initial = await automate(ws.root, { event: "turn_start" });
5525
+ options.progress?.step("Reviewing project context and committed changes");
5523
5526
  const findings = await inspectOnboarding(ws.root, options.base, options.evidence);
5524
5527
  const receiptPath = ws.directory + "/setup-" + host + ".json";
5525
5528
  const initialReportPath = previousReceipt?.initialReportPath ?? initial.report.reportPath;
5526
5529
  const initialBaselinePaths = previousReceipt?.initialBaselinePaths ?? initial.report.baselinePaths;
5530
+ options.progress?.step(`Configuring ${host === "codex" ? "Codex" : "Claude Code"} integration`);
5527
5531
  await writeStoreJson(ws.root, receiptPath, {
5528
5532
  version: 1,
5529
5533
  host,
@@ -5538,6 +5542,7 @@ async function setupProject(dir, options = {}) {
5538
5542
  for (const edit of edits) if (await applyEdit(ws.root, edit)) changedFiles.push(edit.path);
5539
5543
  if (await applyEdit(ws.root, { path: SETUP_PATH, before: setupBefore, after: JSON.stringify(setup, null, 2) + "\n" })) changedFiles.push(SETUP_PATH);
5540
5544
  if (await applyEdit(ws.root, await completedHookOwnership(ws.root, hooks[0].path, configuredHook)) && !changedFiles.includes(ownership.path)) changedFiles.push(ownership.path);
5545
+ options.progress?.step("Checking configuration and retained findings");
5541
5546
  const checked = await automate(ws.root, { event: "turn_start" });
5542
5547
  const configured = await inspectHostConfig(ws.root, host, void 0);
5543
5548
  await writeStoreJson(ws.root, receiptPath, {
@@ -5607,6 +5612,57 @@ init_adapters();
5607
5612
  init_install();
5608
5613
  init_store();
5609
5614
  import { parseArgs } from "util";
5615
+
5616
+ // src/utils/progress.ts
5617
+ function createProgress(options = {}) {
5618
+ const write = options.write ?? ((text2) => {
5619
+ process.stderr.write(text2);
5620
+ });
5621
+ const interactive = options.interactive ?? (!!process.stderr.isTTY && process.env.TERM !== "dumb" && !process.env.CI);
5622
+ const columns = options.columns ?? (() => process.stderr.columns || 80);
5623
+ const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
5624
+ let message2 = "", started = 0, frame = 0;
5625
+ let timer;
5626
+ const elapsed = () => {
5627
+ const seconds = Math.floor((Date.now() - started) / 1e3);
5628
+ return seconds ? ` (${seconds}s)` : "";
5629
+ };
5630
+ const render = (prefix) => {
5631
+ const text2 = `${prefix} ${message2}${elapsed()}`;
5632
+ const width = Math.max(1, columns() - 1);
5633
+ write("\r\x1B[2K" + (text2.length > width ? text2.slice(0, width - 1) + "\u2026" : text2));
5634
+ };
5635
+ const stop = (success = true) => {
5636
+ if (timer) clearInterval(timer);
5637
+ timer = void 0;
5638
+ if (message2 && interactive) {
5639
+ render(success ? "\u2713" : "\u2717");
5640
+ write("\n");
5641
+ }
5642
+ message2 = "";
5643
+ };
5644
+ return {
5645
+ step(next) {
5646
+ stop();
5647
+ message2 = next.replace(/[\x00-\x1f\x7f-\x9f]/g, " ");
5648
+ started = Date.now();
5649
+ frame = 0;
5650
+ if (!interactive) {
5651
+ write(`Mason: ${message2}\u2026
5652
+ `);
5653
+ return;
5654
+ }
5655
+ render(frames[frame]);
5656
+ timer = setInterval(() => {
5657
+ render(frames[++frame % frames.length]);
5658
+ }, 100);
5659
+ timer.unref();
5660
+ },
5661
+ stop
5662
+ };
5663
+ }
5664
+
5665
+ // src/automation/cli.ts
5610
5666
  var TEARDOWN_USAGE = `Usage: mason teardown [options]
5611
5667
 
5612
5668
  Disconnect Mason from this Git project. Defaults to all project hosts.
@@ -5655,11 +5711,13 @@ function isHookCommand(argv2) {
5655
5711
  return false;
5656
5712
  }
5657
5713
  }
5658
- async function runAutomationCli(argv2, stdin = "", io = {
5714
+ var defaultIo = {
5659
5715
  out: (s) => process.stdout.write(s + "\n"),
5660
5716
  err: (s) => process.stderr.write(s + "\n")
5661
- }, options = {}) {
5717
+ };
5718
+ async function runAutomationCli(argv2, stdin = "", io = defaultIo, options = {}) {
5662
5719
  let action = "";
5720
+ let progress;
5663
5721
  try {
5664
5722
  const { values, positionals } = parseCli(argv2);
5665
5723
  if (values.help || !positionals.length) {
@@ -5687,7 +5745,13 @@ async function runAutomationCli(argv2, stdin = "", io = {
5687
5745
  if (action === "setup") {
5688
5746
  if (values.command) throw new Error("--command applies to install/config, not managed setup.");
5689
5747
  const { setupProject: setupProject2, summarizeSetup: summarizeSetup2 } = await Promise.resolve().then(() => (init_setup(), setup_exports));
5690
- const result = await setupProject2(dir, { host: values.host ? hostSchema.parse(values.host) : void 0 });
5748
+ const host = values.host ? hostSchema.parse(values.host) : void 0;
5749
+ if (!values.json) progress = createProgress(io === defaultIo ? {} : {
5750
+ write: (text2) => io.err(text2.replace(/\n$/, "")),
5751
+ interactive: false
5752
+ });
5753
+ const result = await setupProject2(dir, { host, progress });
5754
+ progress?.stop();
5691
5755
  io.out(values.json ? JSON.stringify(result, null, 2) : summarizeSetup2(result));
5692
5756
  return 0;
5693
5757
  }
@@ -5709,6 +5773,7 @@ async function runAutomationCli(argv2, stdin = "", io = {
5709
5773
  io.out(values.json ? JSON.stringify(report, null, 2) : summarize(report));
5710
5774
  return report.status === "verified" ? 0 : report.status === "issues-remain" ? 1 : 2;
5711
5775
  } catch (error) {
5776
+ progress?.stop(false);
5712
5777
  const message2 = action === "setup" ? "Mason setup incomplete: " + automationFailure(error).message + ". Rerun the same setup command to resume; retained audit evidence is preserved." : action === "teardown" ? "Mason teardown incomplete: " + automationFailure(error).message + ". Inspect the reported input, then rerun teardown; knowledge and repair evidence are retained." : failureMessage(error);
5713
5778
  if (action === "hook" || isHookCommand(argv2)) {
5714
5779
  io.out(JSON.stringify({ systemMessage: message2 }));