@launchfile/macos-dev 0.8.0 → 0.9.0

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.
@@ -101,6 +101,13 @@ export type BootstrapExec = (cmd: string, args: string[], opts: {
101
101
  export declare function launchBootstrap(opts?: {
102
102
  component?: string;
103
103
  projectDir?: string;
104
+ /**
105
+ * Print sensitive captures instead of masking them — the operator's
106
+ * explicit act on the invoking command (`launchfile bootstrap
107
+ * --reveal`). Display only: the values are registered with the
108
+ * redactor either way.
109
+ */
110
+ reveal?: boolean;
104
111
  exec?: BootstrapExec;
105
112
  }): Promise<BootstrapResult[]>;
106
113
  //# sourceMappingURL=bootstrap.d.ts.map
package/dist/bootstrap.js CHANGED
@@ -16,10 +16,10 @@
16
16
  import { readFile } from "node:fs/promises";
17
17
  import { join } from "node:path";
18
18
  import { spawn } from "node:child_process";
19
- import { parseDurationMs, readLaunch, resolveExpression, } from "@launchfile/sdk";
19
+ import { formatCaptures, parseDurationMs, readLaunch, resolveExpression, sensitiveCaptureValues, } from "@launchfile/sdk";
20
20
  import { loadState, saveState } from "./state.js";
21
21
  import { buildResolverContext, computeAppProperties, resolveComponentEnv, resolveGenerators, } from "./env-writer.js";
22
- import { redactSecrets } from "./redact.js";
22
+ import { redactSecrets, registerDeclaredSecret } from "./redact.js";
23
23
  import { getProvisioner } from "./resources/index.js";
24
24
  /** Default budget for a bootstrap command when no `timeout` is declared. */
25
25
  export const DEFAULT_BOOTSTRAP_TIMEOUT_MS = 120_000;
@@ -184,6 +184,7 @@ const defaultExec = (cmd, args, opts) => new Promise((resolveP) => {
184
184
  */
185
185
  export async function launchBootstrap(opts = {}) {
186
186
  const projectDir = opts.projectDir ?? process.cwd();
187
+ const reveal = opts.reveal === true;
187
188
  const launchfileContent = await readFile(join(projectDir, "Launchfile"), "utf8");
188
189
  const launch = readLaunch(launchfileContent);
189
190
  const state = await loadState(projectDir);
@@ -259,26 +260,31 @@ export async function launchBootstrap(opts = {}) {
259
260
  env,
260
261
  timeoutMs: item.timeoutMs,
261
262
  });
263
+ const captureMeta = item.capture ?? {};
262
264
  const captures = item.capture ? extractCaptures(stdout, item.capture) : {};
265
+ // A `sensitive: true` capture is a declared secret (D-18): it registers
266
+ // before any result or printed line is built, so the value can leak
267
+ // through neither (CWE-532). `--reveal` changes what the display loop
268
+ // below prints, never this.
269
+ for (const value of sensitiveCaptureValues(captures, captureMeta)) {
270
+ registerDeclaredSecret(value);
271
+ }
263
272
  results.push({
264
273
  component: name,
265
274
  command: item.command,
266
275
  ok: exitCode === 0,
267
276
  exitCode,
268
277
  captures,
269
- captureMeta: item.capture ?? {},
278
+ captureMeta,
270
279
  stdout,
271
280
  stderr,
272
281
  });
273
282
  // Print captures inline so the user sees them immediately.
274
- if (Object.keys(captures).length > 0) {
275
- console.log("\n Captured:");
276
- for (const [key, value] of Object.entries(captures)) {
277
- const meta = item.capture?.[key];
278
- const displayValue = meta?.sensitive ? "***" : value;
279
- const desc = meta?.description ? ` — ${meta.description}` : "";
280
- console.log(` ${key}: ${displayValue}${desc}`);
281
- }
283
+ const lines = formatCaptures(captures, captureMeta, reveal);
284
+ if (lines.length > 0) {
285
+ console.log("");
286
+ for (const line of lines)
287
+ console.log(line);
282
288
  }
283
289
  if (exitCode !== 0) {
284
290
  console.error(` \u2717 Bootstrap [${name}] failed with exit code ${exitCode}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@launchfile/macos-dev",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "macOS dev provider for Launchfile — run apps locally via brew services and native runtimes",
5
5
  "os": [
6
6
  "darwin"
@@ -36,7 +36,7 @@
36
36
  "directory": "providers/macos-dev"
37
37
  },
38
38
  "dependencies": {
39
- "@launchfile/sdk": "^0.8.0",
39
+ "@launchfile/sdk": "^0.9.0",
40
40
  "semver": "^7.7.4"
41
41
  },
42
42
  "devDependencies": {