@metasession.co/devaudit-cli 0.3.2 → 0.3.4

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/index.js CHANGED
@@ -56,7 +56,7 @@ function emitJsonResult(payload) {
56
56
 
57
57
  // package.json
58
58
  var package_default = {
59
- version: "0.3.2"};
59
+ version: "0.3.4"};
60
60
 
61
61
  // src/lib/version.ts
62
62
  var CLI_VERSION = package_default.version;
@@ -2015,6 +2015,8 @@ async function syncStackHooks(ctx) {
2015
2015
  }
2016
2016
  return { name: `${ctx.stack} hooks`, filesSynced: count, message: `synced to ${hookInstallDir}/` };
2017
2017
  }
2018
+ var PLAYWRIGHT_POSTINSTALL = "playwright install chromium";
2019
+ var PLAYWRIGHT_DEP = "@playwright/test";
2018
2020
  async function syncStackDeps(ctx) {
2019
2021
  if (ctx.stack !== "node") {
2020
2022
  return { name: `${ctx.stack} deps`, filesSynced: 0, skipped: true };
@@ -2033,26 +2035,51 @@ async function syncStackDeps(ctx) {
2033
2035
  const installed = new Set(Object.keys(pkg.devDependencies ?? {}));
2034
2036
  const missing = required.filter((dep) => !installed.has(dep));
2035
2037
  if (missing.length === 0) {
2036
- return { name: `${ctx.stack} deps`, filesSynced: 0, message: "all present" };
2038
+ const added = await ensurePostinstallScript(pkgPath, required);
2039
+ return { name: `${ctx.stack} deps`, filesSynced: 0, message: added ? "all present, added postinstall" : "all present" };
2037
2040
  }
2038
2041
  const args = ["install", "--save-dev", ...missing];
2039
2042
  const first = await execa("npm", args, { cwd: ctx.projectPath, reject: false, stdio: "inherit" });
2040
2043
  if (first.exitCode === 0) {
2041
- return { name: `${ctx.stack} deps`, filesSynced: missing.length, message: `installed ${missing.join(" ")}` };
2044
+ const added = await ensurePostinstallScript(pkgPath, required);
2045
+ return { name: `${ctx.stack} deps`, filesSynced: missing.length, message: `installed ${missing.join(" ")}${added ? ", added postinstall" : ""}` };
2042
2046
  }
2043
2047
  const legacyArgs = ["install", "--save-dev", "--legacy-peer-deps", ...missing];
2044
2048
  const second = await execa("npm", legacyArgs, { cwd: ctx.projectPath, reject: false, stdio: "inherit" });
2045
2049
  if (second.exitCode === 0) {
2050
+ const added = await ensurePostinstallScript(pkgPath, required);
2046
2051
  return {
2047
2052
  name: `${ctx.stack} deps`,
2048
2053
  filesSynced: missing.length,
2049
- message: `installed ${missing.join(" ")} (with --legacy-peer-deps)`
2054
+ message: `installed ${missing.join(" ")} (with --legacy-peer-deps)${added ? ", added postinstall" : ""}`
2050
2055
  };
2051
2056
  }
2052
2057
  throw new Error(
2053
2058
  `Failed to install ${ctx.stack} deps. Fix manually: cd ${ctx.projectPath} && npm install --save-dev ${missing.join(" ")}`
2054
2059
  );
2055
2060
  }
2061
+ async function ensurePostinstallScript(pkgPath, requiredDeps) {
2062
+ if (!requiredDeps.includes(PLAYWRIGHT_DEP)) {
2063
+ return false;
2064
+ }
2065
+ const raw = await promises.readFile(pkgPath, "utf-8");
2066
+ const pkg = JSON.parse(raw);
2067
+ const scripts = pkg.scripts ?? {};
2068
+ const existing = scripts["postinstall"];
2069
+ if (existing === PLAYWRIGHT_POSTINSTALL) {
2070
+ return false;
2071
+ }
2072
+ if (existing && !existing.includes("playwright install")) {
2073
+ logger().warn(
2074
+ ` postinstall script already exists ("${existing}") \u2014 not overwriting. Add "playwright install chromium" manually if needed.`
2075
+ );
2076
+ return false;
2077
+ }
2078
+ scripts["postinstall"] = PLAYWRIGHT_POSTINSTALL;
2079
+ pkg.scripts = scripts;
2080
+ await promises.writeFile(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf-8");
2081
+ return true;
2082
+ }
2056
2083
  function isTestScript(name) {
2057
2084
  return name.endsWith(".test.sh");
2058
2085
  }
@@ -2452,6 +2479,23 @@ async function syncSdlcEngine(ctx) {
2452
2479
  }
2453
2480
  return { name: "SDLC CLI engine", filesSynced: count, message: "synced to SDLC/bin/ + SDLC/blueprints/" };
2454
2481
  }
2482
+ async function syncWorkflows(ctx) {
2483
+ const src = join(ctx.installerRoot, "sdlc", "files", "_common", "workflows");
2484
+ if (!await isDir(src)) {
2485
+ return { name: "Workflows", filesSynced: 0, skipped: true };
2486
+ }
2487
+ const dst = join(ctx.projectPath, ".devin", "workflows");
2488
+ await ensureDir(dst);
2489
+ const files = await listFiles(src, (n) => n.endsWith(".md"));
2490
+ for (const file of files) {
2491
+ await copyFile(file, join(dst, fileBasename(file)));
2492
+ }
2493
+ return {
2494
+ name: "Workflows",
2495
+ filesSynced: files.length,
2496
+ message: files.length > 0 ? `synced to .devin/workflows/` : "no workflow files found"
2497
+ };
2498
+ }
2455
2499
  var TIER_1_DOCS = ["Test_Policy.md", "Test_Strategy.md", "Test_Architecture.md"];
2456
2500
  async function runValidation(projectPath) {
2457
2501
  const warnings = [];
@@ -2498,7 +2542,8 @@ var SECTION_RUNNERS = [
2498
2542
  { key: "2e-iii", run: syncEvidenceHelper },
2499
2543
  { key: "2f", run: syncCiTemplates },
2500
2544
  { key: "2g", run: syncGitignore },
2501
- { key: "2h", run: syncSdlcEngine }
2545
+ { key: "2h", run: syncSdlcEngine },
2546
+ { key: "2i", run: syncWorkflows }
2502
2547
  ];
2503
2548
  async function syncProject(projectPath) {
2504
2549
  const absPath = resolve(projectPath);