@williamthorsen/nmr 0.16.0 → 0.17.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.
Files changed (41) hide show
  1. package/AGENTS.md +1 -1
  2. package/README.md +41 -44
  3. package/dist/esm/.cache +1 -1
  4. package/dist/esm/cli-build.js +5 -5
  5. package/dist/esm/cli-ensure-prepublish-hooks.js +33 -34
  6. package/dist/esm/cli-report-overrides.js +7 -6
  7. package/dist/esm/cli-sync-agent-files.js +20 -22
  8. package/dist/esm/cli-sync-pnpm-version.js +7 -6
  9. package/dist/esm/cli.js +13 -13
  10. package/dist/esm/commands/build.d.ts +2 -8
  11. package/dist/esm/commands/build.js +270 -118
  12. package/dist/esm/commands/ensure-prepublish-hooks.js +66 -69
  13. package/dist/esm/commands/report-overrides.js +10 -13
  14. package/dist/esm/commands/sync-agent-files.js +46 -52
  15. package/dist/esm/commands/sync-pnpm-version.js +35 -42
  16. package/dist/esm/config.js +59 -57
  17. package/dist/esm/context.d.ts +1 -1
  18. package/dist/esm/context.js +70 -72
  19. package/dist/esm/default-scripts.js +63 -68
  20. package/dist/esm/help.d.ts +1 -1
  21. package/dist/esm/help.js +65 -67
  22. package/dist/esm/helpers/code-quality-pnpm-action.js +20 -24
  23. package/dist/esm/helpers/hook-name.js +2 -5
  24. package/dist/esm/helpers/package-json.js +46 -41
  25. package/dist/esm/helpers/type-guards.js +2 -5
  26. package/dist/esm/index.d.ts +3 -3
  27. package/dist/esm/index.js +1 -4
  28. package/dist/esm/resolve-scripts.d.ts +2 -2
  29. package/dist/esm/resolve-scripts.js +7 -11
  30. package/dist/esm/resolver.d.ts +2 -2
  31. package/dist/esm/resolver.js +84 -86
  32. package/dist/esm/runCli.js +136 -144
  33. package/dist/esm/runner.js +35 -34
  34. package/dist/esm/scripts.d.ts +2 -2
  35. package/dist/esm/scripts.js +1 -5
  36. package/dist/esm/tests/consistency.d.ts +1 -1
  37. package/dist/esm/tests/consistency.js +45 -54
  38. package/dist/esm/tests/helpers/get-runtime-version-from-asdf.js +11 -14
  39. package/dist/esm/tests/helpers/get-string-from-yaml-file.js +10 -13
  40. package/dist/esm/tests/helpers/get-value-at-path.js +30 -30
  41. package/package.json +5 -3
@@ -1,64 +1,58 @@
1
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
- import path from "node:path";
3
- import { fileURLToPath } from "node:url";
4
- import { readPackageVersion } from "@williamthorsen/nmr-core";
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { readPackageVersion } from '@williamthorsen/nmr-core';
5
5
  const VERSION = readPackageVersion(import.meta.url);
6
- const PACKAGE_NAME = "@williamthorsen/nmr";
7
- const DESTINATION_RELATIVE_PATH = ".agents/nmr/AGENTS.md";
8
- const SOURCE_FILENAME = "AGENTS.md";
6
+ const PACKAGE_NAME = '@williamthorsen/nmr';
7
+ const DESTINATION_RELATIVE_PATH = '.agents/nmr/AGENTS.md';
8
+ const SOURCE_FILENAME = 'AGENTS.md';
9
9
  const FRONTMATTER_REGEX = /^---\n((?:.*\n)*?)---\n/;
10
- function check(destinationDir) {
11
- const destinationPath = getDestinationPath(destinationDir);
12
- if (!existsSync(destinationPath)) {
13
- return {
14
- ok: false,
15
- reason: `${DESTINATION_RELATIVE_PATH} is missing. Run \`nmr sync-agent-files\`.`
16
- };
17
- }
18
- const expectedBody = stripFrontmatter(readFileSync(getSourcePath(), "utf8"));
19
- const foundBody = stripFrontmatter(readFileSync(destinationPath, "utf8"));
20
- if (foundBody !== expectedBody) {
21
- return {
22
- ok: false,
23
- reason: `${DESTINATION_RELATIVE_PATH} content is out of date. Run \`nmr sync-agent-files\`.`
24
- };
25
- }
26
- return { ok: true };
10
+ export function check(destinationDir) {
11
+ const destinationPath = getDestinationPath(destinationDir);
12
+ if (!existsSync(destinationPath)) {
13
+ return {
14
+ ok: false,
15
+ reason: `${DESTINATION_RELATIVE_PATH} is missing. Run \`nmr sync-agent-files\`.`,
16
+ };
17
+ }
18
+ const expectedBody = stripFrontmatter(readFileSync(getSourcePath(), 'utf8'));
19
+ const foundBody = stripFrontmatter(readFileSync(destinationPath, 'utf8'));
20
+ if (foundBody !== expectedBody) {
21
+ return {
22
+ ok: false,
23
+ reason: `${DESTINATION_RELATIVE_PATH} content is out of date. Run \`nmr sync-agent-files\`.`,
24
+ };
25
+ }
26
+ return { ok: true };
27
27
  }
28
- function sync(destinationDir) {
29
- const body = stripFrontmatter(readFileSync(getSourcePath(), "utf8"));
30
- const packageSpecifier = buildPackageSpecifier();
31
- const destinationPath = getDestinationPath(destinationDir);
32
- if (existsSync(destinationPath) && stripFrontmatter(readFileSync(destinationPath, "utf8")) === body) {
33
- return { path: destinationPath, packageSpecifier, changed: false };
34
- }
35
- const output = `---
36
- source: '${packageSpecifier}'
37
- ---
38
- ${body}`;
39
- mkdirSync(path.dirname(destinationPath), { recursive: true });
40
- writeFileSync(destinationPath, output, "utf8");
41
- return { path: destinationPath, packageSpecifier, changed: true };
28
+ export function sync(destinationDir) {
29
+ const body = stripFrontmatter(readFileSync(getSourcePath(), 'utf8'));
30
+ const packageSpecifier = buildPackageSpecifier();
31
+ const destinationPath = getDestinationPath(destinationDir);
32
+ if (existsSync(destinationPath) && stripFrontmatter(readFileSync(destinationPath, 'utf8')) === body) {
33
+ return { path: destinationPath, packageSpecifier, changed: false };
34
+ }
35
+ const output = `---\nsource: '${packageSpecifier}'\n---\n${body}`;
36
+ mkdirSync(path.dirname(destinationPath), { recursive: true });
37
+ writeFileSync(destinationPath, output, 'utf8');
38
+ return { path: destinationPath, packageSpecifier, changed: true };
42
39
  }
43
40
  function buildPackageSpecifier() {
44
- return `${PACKAGE_NAME}@${VERSION}`;
41
+ return `${PACKAGE_NAME}@${VERSION}`;
45
42
  }
46
43
  function getDestinationPath(destinationDir) {
47
- return path.join(destinationDir, DESTINATION_RELATIVE_PATH);
44
+ return path.join(destinationDir, DESTINATION_RELATIVE_PATH);
48
45
  }
49
46
  function getSourcePath() {
50
- let dir = path.dirname(fileURLToPath(import.meta.url));
51
- while (dir !== path.dirname(dir)) {
52
- const candidate = path.join(dir, SOURCE_FILENAME);
53
- if (existsSync(candidate)) return candidate;
54
- dir = path.dirname(dir);
55
- }
56
- throw new Error(`Could not locate ${SOURCE_FILENAME} in any parent of ${fileURLToPath(import.meta.url)}`);
47
+ let dir = path.dirname(fileURLToPath(import.meta.url));
48
+ while (dir !== path.dirname(dir)) {
49
+ const candidate = path.join(dir, SOURCE_FILENAME);
50
+ if (existsSync(candidate))
51
+ return candidate;
52
+ dir = path.dirname(dir);
53
+ }
54
+ throw new Error(`Could not locate ${SOURCE_FILENAME} in any parent of ${fileURLToPath(import.meta.url)}`);
57
55
  }
58
56
  function stripFrontmatter(content) {
59
- return content.replace(FRONTMATTER_REGEX, "");
57
+ return content.replace(FRONTMATTER_REGEX, '');
60
58
  }
61
- export {
62
- check,
63
- sync
64
- };
@@ -1,47 +1,40 @@
1
- import { readFileSync, writeFileSync } from "node:fs";
2
- import path from "node:path";
3
- import { parseDocument } from "yaml";
1
+ import { readFileSync, writeFileSync } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { parseDocument } from 'yaml';
4
4
  import { CodeQualityPnpmWorkflowSchema, getPnpmVersionNodes } from "../helpers/code-quality-pnpm-action.js";
5
5
  import { readPackageJson } from "../helpers/package-json.js";
6
- const WORKFLOW_RELATIVE_PATH = ".github/workflows/code-quality.yaml";
6
+ const WORKFLOW_RELATIVE_PATH = '.github/workflows/code-quality.yaml';
7
7
  function extractPnpmVersion(packageManager) {
8
- if (!packageManager) {
9
- return null;
10
- }
11
- const match = /^pnpm@(.+)$/.exec(packageManager);
12
- return match?.[1] ?? null;
8
+ if (!packageManager) {
9
+ return null;
10
+ }
11
+ const match = /^pnpm@(.+)$/.exec(packageManager);
12
+ return match?.[1] ?? null;
13
13
  }
14
- function syncPnpmVersion(monorepoRoot) {
15
- console.info("Synchronizing pnpm version in GitHub workflow...");
16
- const pkg = readPackageJson(monorepoRoot);
17
- const pnpmVersion = extractPnpmVersion(pkg.packageManager);
18
- if (!pnpmVersion) {
19
- throw new Error(
20
- `Could not extract pnpm version from package.json packageManager field
21
- packageManager field: ${pkg.packageManager ?? "(not set)"}`
22
- );
23
- }
24
- console.info(`Package.json pnpm version: ${pnpmVersion}`);
25
- const workflowPath = path.join(monorepoRoot, WORKFLOW_RELATIVE_PATH);
26
- const doc = parseDocument(readFileSync(workflowPath, "utf8"));
27
- const [parseError] = doc.errors;
28
- if (parseError) {
29
- throw new Error(`Failed to parse workflow file: ${workflowPath}
30
- ${parseError.message}`);
31
- }
32
- CodeQualityPnpmWorkflowSchema.parse(doc.toJS());
33
- const outdatedNodes = getPnpmVersionNodes(doc).filter((node) => String(node.value) !== pnpmVersion);
34
- if (outdatedNodes.length === 0) {
35
- console.info("Workflow pnpm version is already up to date");
36
- return;
37
- }
38
- for (const node of outdatedNodes) {
39
- node.value = pnpmVersion;
40
- }
41
- writeFileSync(workflowPath, doc.toString(), "utf8");
42
- console.info(`\u2713 Updated ${outdatedNodes.length} pnpm-version occurrence(s) \u2192 ${pnpmVersion}`);
14
+ export function syncPnpmVersion(monorepoRoot) {
15
+ console.info('Synchronizing pnpm version in GitHub workflow...');
16
+ const pkg = readPackageJson(monorepoRoot);
17
+ const pnpmVersion = extractPnpmVersion(pkg.packageManager);
18
+ if (!pnpmVersion) {
19
+ throw new Error(`Could not extract pnpm version from package.json packageManager field\npackageManager field: ${pkg.packageManager ?? '(not set)'}`);
20
+ }
21
+ console.info(`Package.json pnpm version: ${pnpmVersion}`);
22
+ const workflowPath = path.join(monorepoRoot, WORKFLOW_RELATIVE_PATH);
23
+ const doc = parseDocument(readFileSync(workflowPath, 'utf8'));
24
+ const [parseError] = doc.errors;
25
+ if (parseError) {
26
+ throw new Error(`Failed to parse workflow file: ${workflowPath}\n${parseError.message}`);
27
+ }
28
+ CodeQualityPnpmWorkflowSchema.parse(doc.toJS());
29
+ const outdatedNodes = getPnpmVersionNodes(doc).filter((node) => String(node.value) !== pnpmVersion);
30
+ if (outdatedNodes.length === 0) {
31
+ console.info('Workflow pnpm version is already up to date');
32
+ return;
33
+ }
34
+ for (const node of outdatedNodes) {
35
+ node.value = pnpmVersion;
36
+ }
37
+ writeFileSync(workflowPath, doc.toString(), 'utf8');
38
+ console.info(`✓ Updated ${outdatedNodes.length} pnpm-version occurrence(s) → ${pnpmVersion}`);
43
39
  }
44
- export {
45
- extractPnpmVersion,
46
- syncPnpmVersion
47
- };
40
+ export { extractPnpmVersion };
@@ -1,70 +1,72 @@
1
- import { existsSync } from "node:fs";
2
- import path from "node:path";
3
- import { createJiti } from "jiti";
1
+ import { existsSync } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { createJiti } from 'jiti';
4
4
  import { isObject } from "./helpers/type-guards.js";
5
- const CONFIG_FILENAME = "nmr.config.ts";
6
- const CONFIG_DIR = ".config";
7
- function defineConfig(config) {
8
- return config;
5
+ const CONFIG_FILENAME = 'nmr.config.ts';
6
+ const CONFIG_DIR = '.config';
7
+ export function defineConfig(config) {
8
+ return config;
9
9
  }
10
10
  function isScriptRecord(value) {
11
- if (!isObject(value)) return false;
12
- for (const v of Object.values(value)) {
13
- if (typeof v !== "string" && !Array.isArray(v)) return false;
14
- if (Array.isArray(v) && v.some((item) => typeof item !== "string")) return false;
15
- }
16
- return true;
11
+ if (!isObject(value))
12
+ return false;
13
+ for (const v of Object.values(value)) {
14
+ if (typeof v !== 'string' && !Array.isArray(v))
15
+ return false;
16
+ if (Array.isArray(v) && v.some((item) => typeof item !== 'string'))
17
+ return false;
18
+ }
19
+ return true;
17
20
  }
18
21
  function validateScriptField(value, fieldName, configPath) {
19
- if (!(fieldName in value) || value[fieldName] === void 0) {
20
- return void 0;
21
- }
22
- if (!isScriptRecord(value[fieldName])) {
23
- throw new Error(
24
- `Invalid nmr config at ${configPath}: \`${fieldName}\` must be a Record<string, string | string[]>`
25
- );
26
- }
27
- return value[fieldName];
22
+ if (!(fieldName in value) || value[fieldName] === undefined) {
23
+ return undefined;
24
+ }
25
+ if (!isScriptRecord(value[fieldName])) {
26
+ throw new Error(`Invalid nmr config at ${configPath}: \`${fieldName}\` must be a Record<string, string | string[]>`);
27
+ }
28
+ return value[fieldName];
28
29
  }
29
30
  function isStringRecord(value) {
30
- if (!isObject(value)) return false;
31
- for (const v of Object.values(value)) {
32
- if (typeof v !== "string") return false;
33
- }
34
- return true;
31
+ if (!isObject(value))
32
+ return false;
33
+ for (const v of Object.values(value)) {
34
+ if (typeof v !== 'string')
35
+ return false;
36
+ }
37
+ return true;
35
38
  }
36
39
  function validateStringRecordField(value, fieldName, configPath) {
37
- if (!(fieldName in value) || value[fieldName] === void 0) {
38
- return void 0;
39
- }
40
- if (!isStringRecord(value[fieldName])) {
41
- throw new Error(`Invalid nmr config at ${configPath}: \`${fieldName}\` must be a Record<string, string>`);
42
- }
43
- return value[fieldName];
40
+ if (!(fieldName in value) || value[fieldName] === undefined) {
41
+ return undefined;
42
+ }
43
+ if (!isStringRecord(value[fieldName])) {
44
+ throw new Error(`Invalid nmr config at ${configPath}: \`${fieldName}\` must be a Record<string, string>`);
45
+ }
46
+ return value[fieldName];
44
47
  }
45
48
  function validateConfig(value, configPath) {
46
- if (!isObject(value)) {
47
- throw new Error(`Invalid nmr config at ${configPath}: expected an object, got ${typeof value}`);
48
- }
49
- const config = {};
50
- const devBin = validateStringRecordField(value, "devBin", configPath);
51
- if (devBin) config.devBin = devBin;
52
- const workspaceScripts = validateScriptField(value, "workspaceScripts", configPath);
53
- if (workspaceScripts) config.workspaceScripts = workspaceScripts;
54
- const rootScripts = validateScriptField(value, "rootScripts", configPath);
55
- if (rootScripts) config.rootScripts = rootScripts;
56
- return config;
49
+ if (!isObject(value)) {
50
+ throw new Error(`Invalid nmr config at ${configPath}: expected an object, got ${typeof value}`);
51
+ }
52
+ const config = {};
53
+ const devBin = validateStringRecordField(value, 'devBin', configPath);
54
+ if (devBin)
55
+ config.devBin = devBin;
56
+ const workspaceScripts = validateScriptField(value, 'workspaceScripts', configPath);
57
+ if (workspaceScripts)
58
+ config.workspaceScripts = workspaceScripts;
59
+ const rootScripts = validateScriptField(value, 'rootScripts', configPath);
60
+ if (rootScripts)
61
+ config.rootScripts = rootScripts;
62
+ return config;
57
63
  }
58
- async function loadConfig(monorepoRoot) {
59
- const configPath = path.join(monorepoRoot, CONFIG_DIR, CONFIG_FILENAME);
60
- if (!existsSync(configPath)) {
61
- return {};
62
- }
63
- const jiti = createJiti(path.join(monorepoRoot, "package.json"));
64
- const loaded = await jiti.import(configPath, { default: true });
65
- return validateConfig(loaded, configPath);
64
+ export async function loadConfig(monorepoRoot) {
65
+ const configPath = path.join(monorepoRoot, CONFIG_DIR, CONFIG_FILENAME);
66
+ if (!existsSync(configPath)) {
67
+ return {};
68
+ }
69
+ const jiti = createJiti(path.join(monorepoRoot, 'package.json'));
70
+ const loaded = await jiti.import(configPath, { default: true });
71
+ return validateConfig(loaded, configPath);
66
72
  }
67
- export {
68
- defineConfig,
69
- loadConfig
70
- };
@@ -1,4 +1,4 @@
1
- import type { NmrConfig } from './config.ts';
1
+ import type { NmrConfig } from './config.js';
2
2
  export interface ResolvedContext {
3
3
  monorepoRoot: string;
4
4
  isRoot: boolean;
@@ -1,84 +1,82 @@
1
- import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
2
- import path from "node:path";
3
- import { parse } from "yaml";
1
+ import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { parse } from 'yaml';
4
4
  import { loadConfig } from "./config.js";
5
5
  import { isObject } from "./helpers/type-guards.js";
6
- function findMonorepoRoot(startDir) {
7
- let dir = path.resolve(startDir ?? process.cwd());
8
- for (; ; ) {
9
- if (existsSync(path.join(dir, "pnpm-workspace.yaml"))) {
10
- return dir;
11
- }
12
- const parent = path.dirname(dir);
13
- if (parent === dir) {
14
- throw new Error("Could not find monorepo root: no pnpm-workspace.yaml found in any parent directory");
6
+ export function findMonorepoRoot(startDir) {
7
+ let dir = path.resolve(startDir ?? process.cwd());
8
+ for (;;) {
9
+ if (existsSync(path.join(dir, 'pnpm-workspace.yaml'))) {
10
+ return dir;
11
+ }
12
+ const parent = path.dirname(dir);
13
+ if (parent === dir) {
14
+ throw new Error('Could not find monorepo root: no pnpm-workspace.yaml found in any parent directory');
15
+ }
16
+ dir = parent;
15
17
  }
16
- dir = parent;
17
- }
18
18
  }
19
- function getWorkspacePackageDirs(monorepoRoot) {
20
- const workspaceFile = path.join(monorepoRoot, "pnpm-workspace.yaml");
21
- const content = readFileSync(workspaceFile, "utf8");
22
- const parsed = parse(content);
23
- const packages = getPackagesFromParsedYaml(parsed);
24
- if (!packages) {
25
- return [];
26
- }
27
- const dirs = [];
28
- for (const pattern of packages) {
29
- if (pattern.endsWith("/*")) {
30
- const prefix = pattern.slice(0, -2);
31
- const prefixDir = path.resolve(monorepoRoot, prefix);
32
- if (existsSync(prefixDir)) {
33
- for (const entry of readdirSync(prefixDir)) {
34
- const fullPath = path.join(prefixDir, entry);
35
- if (statSync(fullPath).isDirectory() && existsSync(path.join(fullPath, "package.json"))) {
36
- dirs.push(fullPath);
37
- }
19
+ export function getWorkspacePackageDirs(monorepoRoot) {
20
+ const workspaceFile = path.join(monorepoRoot, 'pnpm-workspace.yaml');
21
+ const content = readFileSync(workspaceFile, 'utf8');
22
+ const parsed = parse(content);
23
+ const packages = getPackagesFromParsedYaml(parsed);
24
+ if (!packages) {
25
+ return [];
26
+ }
27
+ const dirs = [];
28
+ for (const pattern of packages) {
29
+ if (pattern.endsWith('/*')) {
30
+ const prefix = pattern.slice(0, -2);
31
+ const prefixDir = path.resolve(monorepoRoot, prefix);
32
+ if (existsSync(prefixDir)) {
33
+ for (const entry of readdirSync(prefixDir)) {
34
+ const fullPath = path.join(prefixDir, entry);
35
+ if (statSync(fullPath).isDirectory() && existsSync(path.join(fullPath, 'package.json'))) {
36
+ dirs.push(fullPath);
37
+ }
38
+ }
39
+ }
40
+ }
41
+ else if (!pattern.includes('*')) {
42
+ const fullPath = path.resolve(monorepoRoot, pattern);
43
+ if (existsSync(fullPath) && existsSync(path.join(fullPath, 'package.json'))) {
44
+ dirs.push(fullPath);
45
+ }
38
46
  }
39
- }
40
- } else if (!pattern.includes("*")) {
41
- const fullPath = path.resolve(monorepoRoot, pattern);
42
- if (existsSync(fullPath) && existsSync(path.join(fullPath, "package.json"))) {
43
- dirs.push(fullPath);
44
- }
45
47
  }
46
- }
47
- return dirs;
48
+ return dirs;
48
49
  }
49
- function findContainingPackageDir(dir, workspacePackageDirs) {
50
- const resolved = path.resolve(dir);
51
- for (const pkgDir of workspacePackageDirs) {
52
- const resolvedPkgDir = path.resolve(pkgDir);
53
- if (resolved === resolvedPkgDir || resolved.startsWith(resolvedPkgDir + path.sep)) {
54
- return resolvedPkgDir;
50
+ export function findContainingPackageDir(dir, workspacePackageDirs) {
51
+ const resolved = path.resolve(dir);
52
+ for (const pkgDir of workspacePackageDirs) {
53
+ const resolvedPkgDir = path.resolve(pkgDir);
54
+ if (resolved === resolvedPkgDir || resolved.startsWith(resolvedPkgDir + path.sep)) {
55
+ return resolvedPkgDir;
56
+ }
55
57
  }
56
- }
57
- return void 0;
58
+ return undefined;
58
59
  }
59
60
  function getPackagesFromParsedYaml(parsed) {
60
- if (!isObject(parsed)) return void 0;
61
- const packages = parsed.packages;
62
- if (!Array.isArray(packages)) return void 0;
63
- if (!packages.every((p) => typeof p === "string")) return void 0;
64
- return packages;
61
+ if (!isObject(parsed))
62
+ return undefined;
63
+ const packages = parsed.packages;
64
+ if (!Array.isArray(packages))
65
+ return undefined;
66
+ if (!packages.every((p) => typeof p === 'string'))
67
+ return undefined;
68
+ return packages;
65
69
  }
66
- async function resolveContext(cwd) {
67
- const resolvedCwd = path.resolve(cwd ?? process.cwd());
68
- const monorepoRoot = findMonorepoRoot(resolvedCwd);
69
- const config = await loadConfig(monorepoRoot);
70
- const workspaceDirs = getWorkspacePackageDirs(monorepoRoot);
71
- const packageDir = findContainingPackageDir(resolvedCwd, workspaceDirs);
72
- return {
73
- monorepoRoot,
74
- isRoot: packageDir === void 0,
75
- ...packageDir === void 0 ? {} : { packageDir },
76
- config
77
- };
70
+ export async function resolveContext(cwd) {
71
+ const resolvedCwd = path.resolve(cwd ?? process.cwd());
72
+ const monorepoRoot = findMonorepoRoot(resolvedCwd);
73
+ const config = await loadConfig(monorepoRoot);
74
+ const workspaceDirs = getWorkspacePackageDirs(monorepoRoot);
75
+ const packageDir = findContainingPackageDir(resolvedCwd, workspaceDirs);
76
+ return {
77
+ monorepoRoot,
78
+ isRoot: packageDir === undefined,
79
+ ...(packageDir === undefined ? {} : { packageDir }),
80
+ config,
81
+ };
78
82
  }
79
- export {
80
- findContainingPackageDir,
81
- findMonorepoRoot,
82
- getWorkspacePackageDirs,
83
- resolveContext
84
- };
@@ -1,72 +1,67 @@
1
- const commonWorkspaceScripts = {
2
- build: ["compile", "generate-typings"],
3
- check: ["typecheck", "fmt:check", "lint:check", "test"],
4
- "check:strict": ["typecheck", "fmt:check", "lint:strict", "test:coverage"],
5
- clean: "pnpm exec rimraf dist/*",
6
- compile: "nmr-compile",
7
- fix: ["lint", "fmt"],
8
- "fix:check": ["fmt:check", "lint:check"],
9
- fmt: "prettier --list-different --write .",
10
- "fmt:check": "prettier --check .",
11
- "generate-typings": "tsc --project tsconfig.generate-typings.json",
12
- lint: "eslint --fix .",
13
- "lint:check": "eslint .",
14
- "lint:strict": "strict-lint",
15
- typecheck: "tsgo --noEmit",
16
- "view-coverage": "open coverage/index.html"
1
+ export const commonWorkspaceScripts = {
2
+ attw: 'attw --pack --profile esm-only',
3
+ build: ['compile'],
4
+ check: ['typecheck', 'fmt:check', 'lint:check', 'test'],
5
+ 'check:strict': ['typecheck', 'fmt:check', 'lint:strict', 'test:coverage', 'attw'],
6
+ clean: 'pnpm exec rimraf dist/*',
7
+ compile: 'nmr-compile',
8
+ fix: ['lint', 'fmt'],
9
+ 'fix:check': ['fmt:check', 'lint:check'],
10
+ fmt: 'prettier --list-different --write .',
11
+ 'fmt:check': 'prettier --check .',
12
+ lint: 'eslint --fix .',
13
+ 'lint:check': 'eslint .',
14
+ 'lint:strict': 'strict-lint',
15
+ typecheck: 'tsgo --noEmit',
16
+ 'view-coverage': 'open coverage/index.html',
17
17
  };
18
- const integrationTestScripts = {
19
- test: "pnpm exec vitest --config=vitest.standalone.config.ts",
20
- "test:all": "pnpm exec vitest",
21
- "test:coverage": "pnpm exec vitest --config=vitest.standalone.config.ts --coverage",
22
- "test:integration": "pnpm exec vitest --config=vitest.integration.config.ts",
23
- "test:watch": "pnpm exec vitest --config=vitest.standalone.config.ts --watch"
18
+ export const integrationTestScripts = {
19
+ test: 'pnpm exec vitest --config=vitest.standalone.config.ts',
20
+ 'test:all': 'pnpm exec vitest',
21
+ 'test:coverage': 'pnpm exec vitest --config=vitest.standalone.config.ts --coverage',
22
+ 'test:integration': 'pnpm exec vitest --config=vitest.integration.config.ts',
23
+ 'test:watch': 'pnpm exec vitest --config=vitest.standalone.config.ts --watch',
24
24
  };
25
- const standardTestScripts = {
26
- test: "pnpm exec vitest",
27
- "test:coverage": "pnpm exec vitest --coverage",
28
- "test:watch": "pnpm exec vitest --watch"
25
+ export const standardTestScripts = {
26
+ test: 'pnpm exec vitest',
27
+ 'test:coverage': 'pnpm exec vitest --coverage',
28
+ 'test:watch': 'pnpm exec vitest --watch',
29
29
  };
30
- const rootScripts = {
31
- audit: ["audit:prod", "audit:dev"],
32
- "audit:dev": "pnpm exec v11y --dev",
33
- "audit:prod": "pnpm exec v11y --prod",
34
- build: "pnpm --recursive exec nmr build",
35
- check: ["typecheck", "fmt:check", "lint:check", "test"],
36
- "check:agent-files": "nmr-sync-agent-files --check",
37
- "check:strict": ["typecheck", "fmt:check", "lint:strict", "test:coverage", "check:agent-files"],
38
- ci: ["build", "check:strict", "audit"],
39
- clean: "pnpm --recursive exec nmr clean",
40
- fix: ["lint", "fmt"],
41
- "fix:check": ["fmt:check", "lint:check"],
42
- fmt: `sh -c 'prettier --list-different --write "\${@:-.}"' --`,
43
- "fmt:all": ["fmt", "fmt:sh"],
44
- "fmt:check": `sh -c 'prettier --check "\${@:-.}"' --`,
45
- "fmt:sh": "shfmt --write **/*.sh",
46
- lint: "nmr root:lint && pnpm --recursive exec nmr lint",
47
- "lint:check": "nmr root:lint:check && pnpm --recursive exec nmr lint:check",
48
- "lint:strict": "nmr root:lint:strict && pnpm --recursive exec nmr lint:strict",
49
- outdated: "pnpm outdated --compatible --recursive",
50
- "outdated:latest": "pnpm outdated --recursive",
51
- "report-overrides": "nmr-report-overrides",
52
- "root:check": ["root:typecheck", "fmt:check", "root:lint:check", "root:test"],
53
- "root:lint": "eslint --fix --ignore-pattern 'packages/**' .",
54
- "root:lint:check": "eslint --ignore-pattern 'packages/**' .",
55
- "root:lint:strict": "strict-lint --ignore-pattern 'packages/**' .",
56
- "root:test": "vitest --config ./vitest.root.config.ts",
57
- "root:typecheck": "tsgo --noEmit",
58
- "sync-agent-files": "nmr-sync-agent-files",
59
- "sync-pnpm-version": "nmr-sync-pnpm-version",
60
- test: "nmr root:test && pnpm --recursive exec nmr test",
61
- "test:coverage": "nmr root:test && pnpm --recursive exec nmr test:coverage",
62
- "test:watch": "vitest --watch",
63
- typecheck: "nmr root:typecheck && pnpm --recursive exec nmr typecheck",
64
- update: "pnpm update --recursive",
65
- "update:latest": "pnpm update --latest --recursive"
66
- };
67
- export {
68
- commonWorkspaceScripts,
69
- integrationTestScripts,
70
- rootScripts,
71
- standardTestScripts
30
+ export const rootScripts = {
31
+ attw: 'pnpm --recursive exec nmr attw',
32
+ audit: ['audit:prod', 'audit:dev'],
33
+ 'audit:dev': 'pnpm exec v11y --dev',
34
+ 'audit:prod': 'pnpm exec v11y --prod',
35
+ build: 'pnpm --recursive exec nmr build',
36
+ check: ['typecheck', 'fmt:check', 'lint:check', 'test'],
37
+ 'check:agent-files': 'nmr-sync-agent-files --check',
38
+ 'check:strict': ['typecheck', 'fmt:check', 'lint:strict', 'test:coverage', 'attw', 'check:agent-files'],
39
+ ci: ['build', 'check:strict', 'audit'],
40
+ clean: 'pnpm --recursive exec nmr clean',
41
+ fix: ['lint', 'fmt'],
42
+ 'fix:check': ['fmt:check', 'lint:check'],
43
+ fmt: 'sh -c \'prettier --list-different --write "${@:-.}"\' --',
44
+ 'fmt:all': ['fmt', 'fmt:sh'],
45
+ 'fmt:check': 'sh -c \'prettier --check "${@:-.}"\' --',
46
+ 'fmt:sh': 'shfmt --write **/*.sh',
47
+ lint: 'nmr root:lint && pnpm --recursive exec nmr lint',
48
+ 'lint:check': 'nmr root:lint:check && pnpm --recursive exec nmr lint:check',
49
+ 'lint:strict': 'nmr root:lint:strict && pnpm --recursive exec nmr lint:strict',
50
+ outdated: 'pnpm outdated --compatible --recursive',
51
+ 'outdated:latest': 'pnpm outdated --recursive',
52
+ 'report-overrides': 'nmr-report-overrides',
53
+ 'root:check': ['root:typecheck', 'fmt:check', 'root:lint:check', 'root:test'],
54
+ 'root:lint': "eslint --fix --ignore-pattern 'packages/**' .",
55
+ 'root:lint:check': "eslint --ignore-pattern 'packages/**' .",
56
+ 'root:lint:strict': "strict-lint --ignore-pattern 'packages/**' .",
57
+ 'root:test': 'vitest --config ./vitest.root.config.ts',
58
+ 'root:typecheck': 'tsgo --noEmit',
59
+ 'sync-agent-files': 'nmr-sync-agent-files',
60
+ 'sync-pnpm-version': 'nmr-sync-pnpm-version',
61
+ test: 'nmr root:test && pnpm --recursive exec nmr test',
62
+ 'test:coverage': 'nmr root:test && pnpm --recursive exec nmr test:coverage',
63
+ 'test:watch': 'vitest --watch',
64
+ typecheck: 'nmr root:typecheck && pnpm --recursive exec nmr typecheck',
65
+ update: 'pnpm update --recursive',
66
+ 'update:latest': 'pnpm update --latest --recursive',
72
67
  };