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/dist/mason.js CHANGED
@@ -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, {
@@ -5660,9 +5665,11 @@ async function configurePath(bin, previous, save, options = {}) {
5660
5665
  const changes = [...previous];
5661
5666
  const currentPath = platform === "win32" ? Object.entries(env).find(([key]) => key.toLowerCase() === "path")?.[1] : env.PATH;
5662
5667
  const alreadyOnPath = platform === "win32" ? hasWindowsEntry(currentPath ?? null, bin, env) : (currentPath ?? "").split(":").some((entry) => path26.posix.isAbsolute(entry) && path26.posix.resolve(entry) === path26.posix.resolve(bin));
5663
- const message2 = alreadyOnPath ? "Run: mason setup --host codex" : "Open a new terminal, then run: mason setup --host codex";
5668
+ const setupHint = "To connect a project, run one of these inside its directory:\n Codex: mason setup --host codex\n Claude Code: mason setup --host claude";
5669
+ const message2 = (alreadyOnPath ? "" : "Open a new terminal to use mason.\n") + setupHint;
5664
5670
  const manual = (reason2) => ({ status: "manual", changes, message: `${reason2}
5665
- ${alreadyOnPath ? message2 : `Add ${bin} to your PATH, then run: mason setup --host codex`}` });
5671
+ ${alreadyOnPath ? "" : `Add ${bin} to your PATH.
5672
+ `}${setupHint}` });
5666
5673
  if (env.MASON_NO_MODIFY_PATH === "1") return manual("Automatic PATH setup is disabled (MASON_NO_MODIFY_PATH=1).");
5667
5674
  if (/[\r\n\0]/.test(bin) || bin.includes(platform === "win32" ? ";" : ":")) return manual("This installation path cannot be represented safely in PATH.");
5668
5675
  try {
@@ -5853,7 +5860,8 @@ async function replace(file, content2, mode = 384) {
5853
5860
  await fs22.rm(temp, { force: true });
5854
5861
  }
5855
5862
  }
5856
- async function installStandalone(source) {
5863
+ async function installStandalone(source, progress2) {
5864
+ progress2?.step("Checking installation files and location");
5857
5865
  const bundle = await verifyBundle(source);
5858
5866
  const selectedHome = path27.resolve(defaultHome());
5859
5867
  await fs22.mkdir(selectedHome, { recursive: true });
@@ -5914,6 +5922,7 @@ exec ${shQuote(path27.join(destination, "node"))} ${shQuote(path27.join(destinat
5914
5922
  if (actual !== null && actual !== expected) throw new Error("Retired launcher was edited; retained: " + name);
5915
5923
  };
5916
5924
  for (const [name, expected] of retired) await checkRetired(name, expected);
5925
+ progress2?.step(`Installing Mason ${bundle.manifest.version}`);
5917
5926
  const receipt = { format: 1, home, bin, current: id, version: bundle.manifest.version, launchers, pathChanges: previous?.pathChanges ?? [] };
5918
5927
  await writeStoreJson(home, "install.json", { ...receipt, previousLaunchers: previous?.previousLaunchers ?? previous?.launchers });
5919
5928
  const stage = await storePath(home, "versions/.install-" + randomUUID8(), true);
@@ -5940,11 +5949,12 @@ exec ${shQuote(path27.join(destination, "node"))} ${shQuote(path27.join(destinat
5940
5949
  } finally {
5941
5950
  await fs22.rm(stage, { recursive: true, force: true });
5942
5951
  }
5952
+ progress2?.step("Checking terminal command availability");
5943
5953
  const pathResult = await configurePath(bin, receipt.pathChanges, async (changes) => {
5944
5954
  receipt.pathChanges = changes;
5945
5955
  await writeStoreJson(home, "install.json", receipt);
5946
5956
  });
5947
- return { home, bin, version: bundle.manifest.version, path: pathResult };
5957
+ return { home, bin, version: bundle.manifest.version, previousVersion: previous?.version, path: pathResult };
5948
5958
  });
5949
5959
  }
5950
5960
  async function currentInstallation() {
@@ -5956,12 +5966,14 @@ async function currentInstallation() {
5956
5966
  if (record.home !== await fs22.realpath(home) || path27.dirname(bundle) !== path27.join(home, "versions")) throw new Error("Invalid standalone installation receipt.");
5957
5967
  return { home, bundle, record };
5958
5968
  }
5959
- async function upgradeStandalone(version) {
5969
+ async function upgradeStandalone(version, progress2) {
5960
5970
  if (version && !/^v?\d+\.\d+\.\d+(?:-[A-Za-z0-9.-]+)?$/.test(version)) throw new Error("Expected a release version such as 0.14.0.");
5971
+ progress2?.step("Checking current installation");
5961
5972
  const { home, bundle, record } = await currentInstallation();
5962
5973
  await verifyBundle(bundle);
5963
5974
  const windows = process.platform === "win32";
5964
5975
  const script = path27.join(bundle, windows ? "install.ps1" : "install.sh");
5976
+ progress2?.stop();
5965
5977
  return new Promise((resolve, reject) => {
5966
5978
  const child = spawn(
5967
5979
  windows ? "powershell.exe" : "sh",
@@ -6031,6 +6043,57 @@ init_adapters();
6031
6043
  init_install();
6032
6044
  init_store();
6033
6045
  import { parseArgs } from "util";
6046
+
6047
+ // src/utils/progress.ts
6048
+ function createProgress(options = {}) {
6049
+ const write = options.write ?? ((text2) => {
6050
+ process.stderr.write(text2);
6051
+ });
6052
+ const interactive = options.interactive ?? (!!process.stderr.isTTY && process.env.TERM !== "dumb" && !process.env.CI);
6053
+ const columns = options.columns ?? (() => process.stderr.columns || 80);
6054
+ const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
6055
+ let message2 = "", started = 0, frame = 0;
6056
+ let timer;
6057
+ const elapsed = () => {
6058
+ const seconds = Math.floor((Date.now() - started) / 1e3);
6059
+ return seconds ? ` (${seconds}s)` : "";
6060
+ };
6061
+ const render = (prefix) => {
6062
+ const text2 = `${prefix} ${message2}${elapsed()}`;
6063
+ const width = Math.max(1, columns() - 1);
6064
+ write("\r\x1B[2K" + (text2.length > width ? text2.slice(0, width - 1) + "\u2026" : text2));
6065
+ };
6066
+ const stop = (success = true) => {
6067
+ if (timer) clearInterval(timer);
6068
+ timer = void 0;
6069
+ if (message2 && interactive) {
6070
+ render(success ? "\u2713" : "\u2717");
6071
+ write("\n");
6072
+ }
6073
+ message2 = "";
6074
+ };
6075
+ return {
6076
+ step(next) {
6077
+ stop();
6078
+ message2 = next.replace(/[\x00-\x1f\x7f-\x9f]/g, " ");
6079
+ started = Date.now();
6080
+ frame = 0;
6081
+ if (!interactive) {
6082
+ write(`Mason: ${message2}\u2026
6083
+ `);
6084
+ return;
6085
+ }
6086
+ render(frames[frame]);
6087
+ timer = setInterval(() => {
6088
+ render(frames[++frame % frames.length]);
6089
+ }, 100);
6090
+ timer.unref();
6091
+ },
6092
+ stop
6093
+ };
6094
+ }
6095
+
6096
+ // src/automation/cli.ts
6034
6097
  var TEARDOWN_USAGE = `Usage: mason teardown [options]
6035
6098
 
6036
6099
  Disconnect Mason from this Git project. Defaults to all project hosts.
@@ -6079,11 +6142,13 @@ function isHookCommand(argv) {
6079
6142
  return false;
6080
6143
  }
6081
6144
  }
6082
- async function runAutomationCli(argv, stdin = "", io = {
6145
+ var defaultIo = {
6083
6146
  out: (s) => process.stdout.write(s + "\n"),
6084
6147
  err: (s) => process.stderr.write(s + "\n")
6085
- }, options = {}) {
6148
+ };
6149
+ async function runAutomationCli(argv, stdin = "", io = defaultIo, options = {}) {
6086
6150
  let action = "";
6151
+ let progress2;
6087
6152
  try {
6088
6153
  const { values, positionals } = parseCli(argv);
6089
6154
  if (values.help || !positionals.length) {
@@ -6111,7 +6176,13 @@ async function runAutomationCli(argv, stdin = "", io = {
6111
6176
  if (action === "setup") {
6112
6177
  if (values.command) throw new Error("--command applies to install/config, not managed setup.");
6113
6178
  const { setupProject: setupProject2, summarizeSetup: summarizeSetup2 } = await Promise.resolve().then(() => (init_setup(), setup_exports));
6114
- const result = await setupProject2(dir, { host: values.host ? hostSchema.parse(values.host) : void 0 });
6179
+ const host = values.host ? hostSchema.parse(values.host) : void 0;
6180
+ if (!values.json) progress2 = createProgress(io === defaultIo ? {} : {
6181
+ write: (text2) => io.err(text2.replace(/\n$/, "")),
6182
+ interactive: false
6183
+ });
6184
+ const result = await setupProject2(dir, { host, progress: progress2 });
6185
+ progress2?.stop();
6115
6186
  io.out(values.json ? JSON.stringify(result, null, 2) : summarizeSetup2(result));
6116
6187
  return 0;
6117
6188
  }
@@ -6133,6 +6204,7 @@ async function runAutomationCli(argv, stdin = "", io = {
6133
6204
  io.out(values.json ? JSON.stringify(report, null, 2) : summarize(report));
6134
6205
  return report.status === "verified" ? 0 : report.status === "issues-remain" ? 1 : 2;
6135
6206
  } catch (error) {
6207
+ progress2?.stop(false);
6136
6208
  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);
6137
6209
  if (action === "hook" || isHookCommand(argv)) {
6138
6210
  io.out(JSON.stringify({ systemMessage: message2 }));
@@ -6149,7 +6221,7 @@ var inputArgs = process.argv.slice(2);
6149
6221
  var managedLaunch = inputArgs[0] === "--setup-host";
6150
6222
  var setupHost = managedLaunch ? inputArgs.splice(0, 2)[1] : void 0;
6151
6223
  var [command, ...args] = inputArgs;
6152
- var usage = `Mason ${"0.17.1"}
6224
+ var usage = `Mason ${"0.17.2"}
6153
6225
 
6154
6226
  Usage: mason <command> [options]
6155
6227
 
@@ -6166,6 +6238,7 @@ Usage: mason <command> [options]
6166
6238
 
6167
6239
  Use mason <command> --help for options. npm users can keep using mason-auto,
6168
6240
  mason-audit, mason-review, mason-drift, mason-hook and mason-mcp.`;
6241
+ var progress;
6169
6242
  try {
6170
6243
  if (managedLaunch) {
6171
6244
  if (!setupHost || !["codex", "claude"].includes(setupHost) || !["mcp", "auto"].includes(command)) throw new Error("Invalid setup invocation.");
@@ -6174,23 +6247,29 @@ try {
6174
6247
  await prepareLaunch2(setupHost, { allowInactive: command === "mcp" });
6175
6248
  }
6176
6249
  }
6177
- if (command === "internal-integration-version") console.log(JSON.stringify({ protocol: 1, version: "0.17.1" }));
6250
+ if (command === "internal-integration-version") console.log(JSON.stringify({ protocol: 1, version: "0.17.2" }));
6178
6251
  else if (!command || ["--help", "-h", "help"].includes(command)) console.log(usage);
6179
- else if (["--version", "-v"].includes(command)) console.log("0.17.1");
6252
+ else if (["--version", "-v"].includes(command)) console.log("0.17.2");
6180
6253
  else if (command === "internal-install") {
6181
6254
  if (args.length) throw new Error("internal-install takes no arguments.");
6182
6255
  const { installStandalone: installStandalone2 } = await Promise.resolve().then(() => (init_install2(), install_exports2));
6183
6256
  const bundleRoot = fileURLToPath2(new URL("../..", import.meta.url));
6184
- const installed = await installStandalone2(bundleRoot);
6185
- console.log(`Installed Mason ${installed.version} in ${installed.home}.
6257
+ progress = createProgress();
6258
+ const installed = await installStandalone2(bundleRoot, progress);
6259
+ progress.stop();
6260
+ const outcome = installed.previousVersion && installed.previousVersion !== installed.version ? `Updated Mason ${installed.previousVersion} \u2192 ${installed.version}` : `Installed Mason ${installed.version}`;
6261
+ console.log(`${outcome} in ${installed.home}.
6186
6262
  ${installed.path.message}`);
6187
6263
  } else if (command === "upgrade" || command === "uninstall") {
6188
6264
  if (args.includes("--help")) console.log(command === "upgrade" ? "Usage: mason upgrade [version]. Configured projects use the upgraded command on their next launch. Restart running assistants." : "Usage: mason uninstall. Removes the standalone user installation; project configuration and knowledge are retained. Run mason teardown in each project first to disconnect its integrations.");
6189
6265
  else {
6190
6266
  const { upgradeStandalone: upgradeStandalone2, uninstallStandalone: uninstallStandalone2 } = await Promise.resolve().then(() => (init_install2(), install_exports2));
6191
6267
  if (args.length > (command === "upgrade" ? 1 : 0)) throw new Error("Unexpected arguments.");
6192
- if (command === "upgrade") process.exitCode = await upgradeStandalone2(args[0]);
6193
- else console.log((process.platform === "win32" ? "Finishing installation cleanup after runtime exit: " : "Removed standalone installation: ") + await uninstallStandalone2() + ". Project configuration and knowledge were retained. Reinstall Mason to use its integrations.");
6268
+ if (command === "upgrade") {
6269
+ progress = createProgress();
6270
+ process.exitCode = await upgradeStandalone2(args[0], progress);
6271
+ if (process.exitCode === 0) console.log("Restart running assistants to use this installation. Existing project integrations use mason from PATH.");
6272
+ } else console.log((process.platform === "win32" ? "Finishing installation cleanup after runtime exit: " : "Removed standalone installation: ") + await uninstallStandalone2() + ". Project configuration and knowledge were retained. Reinstall Mason to use its integrations.");
6194
6273
  }
6195
6274
  } else if (["setup", "teardown", "status", "check", "auto"].includes(command)) {
6196
6275
  const forwarded = command === "auto" ? args : [command, ...args];
@@ -6211,6 +6290,7 @@ ${installed.path.message}`);
6211
6290
  await import(binary.href);
6212
6291
  } else throw new Error("Unknown command: " + command + ". Run mason --help.");
6213
6292
  } catch (error) {
6293
+ progress?.stop(false);
6214
6294
  const message2 = "Mason: " + (error instanceof Error ? error.message : String(error));
6215
6295
  if (command === "auto" && isHookCommand(args)) {
6216
6296
  console.log(JSON.stringify({ systemMessage: message2 + " Verification was not established." }));