@grunnverk/kodrdriv 1.3.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 (84) hide show
  1. package/.claude/settings.local.json +12 -0
  2. package/.cursor/rules/no-local-dependencies.md +6 -0
  3. package/.gitignore~ +23 -0
  4. package/.kodrdriv-example-branch-targeting.yaml +71 -0
  5. package/BUG_TREE_PUBLISH_CONFIG_DIR.md +79 -0
  6. package/LICENSE +190 -0
  7. package/README.md +218 -0
  8. package/dist/application.js +228 -0
  9. package/dist/application.js.map +1 -0
  10. package/dist/arguments.js +1307 -0
  11. package/dist/arguments.js.map +1 -0
  12. package/dist/constants.js +255 -0
  13. package/dist/constants.js.map +1 -0
  14. package/dist/logging.js +176 -0
  15. package/dist/logging.js.map +1 -0
  16. package/dist/main.js +24 -0
  17. package/dist/main.js.map +1 -0
  18. package/dist/mcp/prompts/check_development.md +169 -0
  19. package/dist/mcp/prompts/dependency_update.md +62 -0
  20. package/dist/mcp/prompts/fix_and_commit.md +53 -0
  21. package/dist/mcp/prompts/publish.md +100 -0
  22. package/dist/mcp/prompts/tree_fix_and_commit.md +102 -0
  23. package/dist/mcp/prompts/tree_publish.md +118 -0
  24. package/dist/mcp-server.js +15601 -0
  25. package/dist/mcp-server.js.map +7 -0
  26. package/dist/types.js +303 -0
  27. package/dist/types.js.map +1 -0
  28. package/guide/ai-system.md +522 -0
  29. package/guide/architecture.md +349 -0
  30. package/guide/commands.md +383 -0
  31. package/guide/configuration.md +516 -0
  32. package/guide/debugging.md +587 -0
  33. package/guide/development.md +632 -0
  34. package/guide/index.md +224 -0
  35. package/guide/integration.md +510 -0
  36. package/guide/monorepo.md +533 -0
  37. package/guide/quickstart.md +249 -0
  38. package/guide/testing.md +463 -0
  39. package/guide/tree-operations.md +621 -0
  40. package/guide/usage.md +578 -0
  41. package/input/250509-kodrdriv-library-rules.m4a +0 -0
  42. package/package.json +105 -0
  43. package/packages/components/package.json +7 -0
  44. package/packages/tools/package.json +7 -0
  45. package/packages/utils/package.json +7 -0
  46. package/processed/250705-kodrdriv-confirm-editor-for-commit-and-release.m4a +0 -0
  47. package/processed/250705-kodrdriv-confirm-flag-release.m4a +0 -0
  48. package/processed/250705-kodrdriv-context-for-review.m4a +0 -0
  49. package/processed/250705-kodrdriv-feedback-on-publish-pipeline.m4a +0 -0
  50. package/processed/250705-kodrdriv-intelligent-eslint-style.m4a +0 -0
  51. package/processed/250705-kodrdriv-make-review-less-strict.m4a +0 -0
  52. package/processed/250705-kodrdriv-multilevel-transcription.m4a +0 -0
  53. package/processed/250705-kodrdriv-opinionated-review.m4a +0 -0
  54. package/processed/250705-kodrdriv-publish-next-version.m4a +0 -0
  55. package/processed/250705-kodrdriv-release-branches-and-milestones.m4a +0 -0
  56. package/processed/250705-kodrdriv-scope-check-fix-or-ignore.m4a +0 -0
  57. package/processed/250705-kodrdriv-scope-checker.m4a +0 -0
  58. package/processed/250705-kodrdriv-specify-a-release-note-for-publish.m4a +0 -0
  59. package/scripts/build-mcp.js +111 -0
  60. package/scripts/pre-commit-hook.sh +52 -0
  61. package/scripts/test-get-version-tool.js +102 -0
  62. package/scripts/test-mcp-compliance.js +254 -0
  63. package/scripts/update-test-log-assertions.js +73 -0
  64. package/temp-dist/arguments.js +817 -0
  65. package/temp-dist/constants.js +202 -0
  66. package/temp-dist/logging.js +130 -0
  67. package/temp-dist/types.js +112 -0
  68. package/temp-dist/util/stdin.js +132 -0
  69. package/temp-dist/util/storage.js +149 -0
  70. package/temp-dist/util/validation.js +110 -0
  71. package/test-external-unlink/package.json +16 -0
  72. package/test-externals/package.json +8 -0
  73. package/test-increment.js +0 -0
  74. package/test-multiline/cli/package.json +8 -0
  75. package/test-multiline/core/package.json +5 -0
  76. package/test-multiline/mobile/package.json +8 -0
  77. package/test-multiline/web/package.json +8 -0
  78. package/test-project/package-lock.json +21 -0
  79. package/test-project/package.json +1 -0
  80. package/test-review-flow.sh +15 -0
  81. package/test-sort-files/alpha.md +3 -0
  82. package/test-sort-files/middle.txt +3 -0
  83. package/test-sort-files/zebra.txt +3 -0
  84. package/test_output.txt +161 -0
@@ -0,0 +1,149 @@
1
+ // eslint-disable-next-line no-restricted-imports
2
+ import * as fs from 'fs';
3
+ import { glob } from 'glob';
4
+ import path from 'path';
5
+ import crypto from 'crypto';
6
+ export const create = (params) => {
7
+ // eslint-disable-next-line no-console
8
+ const log = params.log || console.log;
9
+ const exists = async (path) => {
10
+ try {
11
+ await fs.promises.stat(path);
12
+ return true;
13
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
14
+ }
15
+ catch (error) {
16
+ return false;
17
+ }
18
+ };
19
+ const isDirectory = async (path) => {
20
+ const stats = await fs.promises.stat(path);
21
+ if (!stats.isDirectory()) {
22
+ // Log at debug level since this is expected when scanning directories
23
+ // that contain both files and directories
24
+ return false;
25
+ }
26
+ return true;
27
+ };
28
+ const isFile = async (path) => {
29
+ const stats = await fs.promises.stat(path);
30
+ if (!stats.isFile()) {
31
+ // Log removed since this is expected when checking file types
32
+ return false;
33
+ }
34
+ return true;
35
+ };
36
+ const isReadable = async (path) => {
37
+ try {
38
+ await fs.promises.access(path, fs.constants.R_OK);
39
+ }
40
+ catch (error) {
41
+ log(`${path} is not readable: %s %s`, error.message, error.stack);
42
+ return false;
43
+ }
44
+ return true;
45
+ };
46
+ const isWritable = async (path) => {
47
+ try {
48
+ await fs.promises.access(path, fs.constants.W_OK);
49
+ }
50
+ catch (error) {
51
+ log(`${path} is not writable: %s %s`, error.message, error.stack);
52
+ return false;
53
+ }
54
+ return true;
55
+ };
56
+ const isFileReadable = async (path) => {
57
+ return await exists(path) && await isFile(path) && await isReadable(path);
58
+ };
59
+ const isDirectoryWritable = async (path) => {
60
+ return await exists(path) && await isDirectory(path) && await isWritable(path);
61
+ };
62
+ const isDirectoryReadable = async (path) => {
63
+ return await exists(path) && await isDirectory(path) && await isReadable(path);
64
+ };
65
+ const createDirectory = async (path) => {
66
+ try {
67
+ await fs.promises.mkdir(path, { recursive: true });
68
+ }
69
+ catch (mkdirError) {
70
+ throw new Error(`Failed to create output directory ${path}: ${mkdirError.message} ${mkdirError.stack}`);
71
+ }
72
+ };
73
+ const ensureDirectory = async (path) => {
74
+ if (!(await exists(path))) {
75
+ await createDirectory(path);
76
+ }
77
+ };
78
+ const removeDirectory = async (path) => {
79
+ try {
80
+ if (await exists(path)) {
81
+ await fs.promises.rm(path, { recursive: true, force: true });
82
+ }
83
+ }
84
+ catch (rmError) {
85
+ throw new Error(`Failed to remove directory ${path}: ${rmError.message} ${rmError.stack}`);
86
+ }
87
+ };
88
+ const readFile = async (path, encoding) => {
89
+ return await fs.promises.readFile(path, { encoding: encoding });
90
+ };
91
+ const writeFile = async (path, data, encoding) => {
92
+ await fs.promises.writeFile(path, data, { encoding: encoding });
93
+ };
94
+ const rename = async (oldPath, newPath) => {
95
+ await fs.promises.rename(oldPath, newPath);
96
+ };
97
+ const deleteFile = async (path) => {
98
+ try {
99
+ if (await exists(path)) {
100
+ await fs.promises.unlink(path);
101
+ }
102
+ }
103
+ catch (deleteError) {
104
+ throw new Error(`Failed to delete file ${path}: ${deleteError.message} ${deleteError.stack}`);
105
+ }
106
+ };
107
+ const forEachFileIn = async (directory, callback, options = { pattern: '*.*' }) => {
108
+ try {
109
+ const files = await glob(options.pattern, { cwd: directory, nodir: true });
110
+ for (const file of files) {
111
+ await callback(path.join(directory, file));
112
+ }
113
+ }
114
+ catch (err) {
115
+ throw new Error(`Failed to glob pattern ${options.pattern} in ${directory}: ${err.message}`);
116
+ }
117
+ };
118
+ const readStream = async (path) => {
119
+ return fs.createReadStream(path);
120
+ };
121
+ const hashFile = async (path, length) => {
122
+ const file = await readFile(path, 'utf8');
123
+ return crypto.createHash('sha256').update(file).digest('hex').slice(0, length);
124
+ };
125
+ const listFiles = async (directory) => {
126
+ return await fs.promises.readdir(directory);
127
+ };
128
+ return {
129
+ exists,
130
+ isDirectory,
131
+ isFile,
132
+ isReadable,
133
+ isWritable,
134
+ isFileReadable,
135
+ isDirectoryWritable,
136
+ isDirectoryReadable,
137
+ createDirectory,
138
+ ensureDirectory,
139
+ readFile,
140
+ readStream,
141
+ writeFile,
142
+ rename,
143
+ deleteFile,
144
+ forEachFileIn,
145
+ hashFile,
146
+ listFiles,
147
+ removeDirectory,
148
+ };
149
+ };
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Runtime validation utilities for safe type handling
3
+ */
4
+ /**
5
+ * Validates and safely casts data to ReleaseSummary type
6
+ */
7
+ export const validateReleaseSummary = (data) => {
8
+ if (!data || typeof data !== 'object') {
9
+ throw new Error('Invalid release summary: not an object');
10
+ }
11
+ if (typeof data.title !== 'string') {
12
+ throw new Error('Invalid release summary: title must be a string');
13
+ }
14
+ if (typeof data.body !== 'string') {
15
+ throw new Error('Invalid release summary: body must be a string');
16
+ }
17
+ return data;
18
+ };
19
+ /**
20
+ * Validates and safely casts data to LinkBackup type
21
+ */
22
+ export const validateLinkBackup = (data) => {
23
+ if (!data || typeof data !== 'object') {
24
+ throw new Error('Invalid link backup: not an object');
25
+ }
26
+ // Validate each backup entry
27
+ for (const [key, value] of Object.entries(data)) {
28
+ if (!value || typeof value !== 'object') {
29
+ throw new Error(`Invalid link backup entry for ${key}: not an object`);
30
+ }
31
+ const entry = value;
32
+ if (typeof entry.originalVersion !== 'string') {
33
+ throw new Error(`Invalid link backup entry for ${key}: originalVersion must be a string`);
34
+ }
35
+ if (typeof entry.dependencyType !== 'string') {
36
+ throw new Error(`Invalid link backup entry for ${key}: dependencyType must be a string`);
37
+ }
38
+ if (typeof entry.relativePath !== 'string') {
39
+ throw new Error(`Invalid link backup entry for ${key}: relativePath must be a string`);
40
+ }
41
+ }
42
+ return data;
43
+ };
44
+ /**
45
+ * Validates transcription result has required text property
46
+ */
47
+ export const validateTranscriptionResult = (data) => {
48
+ if (!data || typeof data !== 'object') {
49
+ throw new Error('Invalid transcription result: not an object');
50
+ }
51
+ if (typeof data.text !== 'string') {
52
+ throw new Error('Invalid transcription result: text property must be a string');
53
+ }
54
+ return data;
55
+ };
56
+ /**
57
+ * Safely parses JSON with error handling
58
+ */
59
+ export const safeJsonParse = (jsonString, context) => {
60
+ try {
61
+ const parsed = JSON.parse(jsonString);
62
+ if (parsed === null || parsed === undefined) {
63
+ throw new Error('Parsed JSON is null or undefined');
64
+ }
65
+ return parsed;
66
+ }
67
+ catch (error) {
68
+ const contextStr = context ? ` (${context})` : '';
69
+ throw new Error(`Failed to parse JSON${contextStr}: ${error instanceof Error ? error.message : 'Unknown error'}`);
70
+ }
71
+ };
72
+ /**
73
+ * Validates that a value is a non-empty string
74
+ */
75
+ export const validateString = (value, fieldName) => {
76
+ if (typeof value !== 'string') {
77
+ throw new Error(`${fieldName} must be a string, got ${typeof value}`);
78
+ }
79
+ if (value.trim() === '') {
80
+ throw new Error(`${fieldName} cannot be empty`);
81
+ }
82
+ return value;
83
+ };
84
+ /**
85
+ * Validates that a value exists and has a specific property
86
+ */
87
+ export const validateHasProperty = (obj, property, context) => {
88
+ if (!obj || typeof obj !== 'object') {
89
+ const contextStr = context ? ` in ${context}` : '';
90
+ throw new Error(`Object is null or not an object${contextStr}`);
91
+ }
92
+ if (!(property in obj)) {
93
+ const contextStr = context ? ` in ${context}` : '';
94
+ throw new Error(`Missing required property '${property}'${contextStr}`);
95
+ }
96
+ };
97
+ /**
98
+ * Validates package.json structure has basic required fields
99
+ */
100
+ export const validatePackageJson = (data, context, requireName = true) => {
101
+ if (!data || typeof data !== 'object') {
102
+ const contextStr = context ? ` (${context})` : '';
103
+ throw new Error(`Invalid package.json${contextStr}: not an object`);
104
+ }
105
+ if (requireName && typeof data.name !== 'string') {
106
+ const contextStr = context ? ` (${context})` : '';
107
+ throw new Error(`Invalid package.json${contextStr}: name must be a string`);
108
+ }
109
+ return data;
110
+ };
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "@test/external-unlink-test",
3
+ "version": "1.0.0",
4
+ "description": "Test package for external unlink patterns",
5
+ "main": "index.js",
6
+ "dependencies": {
7
+ "@somelib/core": "^1.0.0",
8
+ "@somelib/utils": "^1.0.0",
9
+ "lodash": "^4.17.21",
10
+ "express": "^4.18.2"
11
+ },
12
+ "devDependencies": {
13
+ "@somelib/dev": "^1.0.0",
14
+ "jest": "^29.0.0"
15
+ }
16
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "@test/app",
3
+ "version": "1.0.0",
4
+ "dependencies": {
5
+ "@external/lib": "^1.0.0",
6
+ "lodash": "^4.17.0"
7
+ }
8
+ }
File without changes
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "cli-tool",
3
+ "version": "1.0.0",
4
+ "description": "Command line tool",
5
+ "dependencies": {
6
+ "core-library": "^1.0.0"
7
+ }
8
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "core-library",
3
+ "version": "1.0.0",
4
+ "description": "Core library"
5
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "mobile-app",
3
+ "version": "1.0.0",
4
+ "description": "Mobile application",
5
+ "dependencies": {
6
+ "core-library": "^1.0.0"
7
+ }
8
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "web-app",
3
+ "version": "1.0.0",
4
+ "description": "Web application",
5
+ "dependencies": {
6
+ "core-library": "^1.0.0"
7
+ }
8
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "test-project",
3
+ "lockfileVersion": 3,
4
+ "requires": true,
5
+ "packages": {
6
+ "": {
7
+ "name": "test-project",
8
+ "dependencies": {
9
+ "@myorg/utils": "file:../packages/utils"
10
+ }
11
+ },
12
+ "../packages/utils": {
13
+ "name": "@myorg/utils",
14
+ "version": "1.2.3"
15
+ },
16
+ "node_modules/@myorg/utils": {
17
+ "resolved": "../packages/utils",
18
+ "link": true
19
+ }
20
+ }
21
+ }
@@ -0,0 +1 @@
1
+ {"name": "test-project", "dependencies": {"@myorg/utils": "file:../packages/utils"}}
@@ -0,0 +1,15 @@
1
+ #!/bin/bash
2
+
3
+ echo "Testing the new two-phase review flow..."
4
+ echo "This will test the file selection phase and then the analysis phase"
5
+
6
+ # Test with a single file in the test-project directory
7
+ echo "Test review note content" > test-project/test-review.md
8
+
9
+ echo "Running review command in test-project directory..."
10
+ echo "You should see:"
11
+ echo "1. File selection phase with c/s/a options"
12
+ echo "2. Analysis phase after files are selected"
13
+
14
+ cd test-project
15
+ ../dist/main.js review --directory .
@@ -0,0 +1,3 @@
1
+ # Alpha Review
2
+
3
+ This file should be processed first alphabetically.
@@ -0,0 +1,3 @@
1
+ # Middle Review
2
+
3
+ This file should be processed in the middle alphabetically.
@@ -0,0 +1,3 @@
1
+ # Zebra Review
2
+
3
+ This file should be processed last alphabetically.
@@ -0,0 +1,161 @@
1
+
2
+ > @grunnverk/kodrdriv@1.2.3-dev.0 test
3
+ > vitest run --coverage tests/commands/tree.test.ts
4
+
5
+
6
+ RUN v3.2.4 kodrdriv
7
+ Coverage enabled with v8
8
+
9
+ ❯ tests/commands/tree.test.ts (60 tests | 6 failed) 57ms
10
+ ✓ tree > execute > should handle empty directory with no package.json files 3ms
11
+ ✓ tree > execute > should scan and build dependency graph for simple packages 1ms
12
+ ✓ tree > execute > should handle circular dependencies 1ms
13
+ ✓ tree > execute > should exclude packages based on patterns 1ms
14
+ ✓ tree > execute > should start from specified package 1ms
15
+ ✓ tree > execute > should throw error for invalid startFrom package 0ms
16
+ ✓ tree > execute > should stop at specified package 0ms
17
+ ✓ tree > execute > should stop at specified package with multiple dependencies 1ms
18
+ ✓ tree > execute > should combine startFrom and stopAt options 0ms
19
+ ✓ tree > execute > should throw error for invalid stopAt package 0ms
20
+ ✓ tree > execute > should execute command in dry run mode 1ms
21
+ ✓ tree > execute > should execute command in packages 1ms
22
+ ✓ tree > execute > should handle command execution failure and provide recovery command 1ms
23
+ ✓ tree > execute > should handle package.json without name field 1ms
24
+ ✓ tree > execute > should handle invalid JSON in package.json 1ms
25
+ ✓ tree > execute > should handle file system errors during scanning 0ms
26
+ ✓ tree > execute > should use custom directories from config 0ms
27
+ ✓ tree > execute > should return build order without executing command when no cmd provided 1ms
28
+ ✓ tree > execute > should collect all dependency types 1ms
29
+ ✓ tree > error formatting and handling > should format command errors with stderr and stdout 1ms
30
+ ✓ tree > error formatting and handling > should format simple errors without stderr/stdout 1ms
31
+ ✓ tree > error formatting and handling > should restore working directory after command failure 1ms
32
+ ✓ tree > error formatting and handling > should handle packages with no version field 1ms
33
+ ✓ tree > complex dependency scenarios > should handle deep dependency chains 1ms
34
+ ✓ tree > complex dependency scenarios > should handle diamond dependency pattern 1ms
35
+ ✓ tree > complex dependency scenarios > should handle multiple independent packages 1ms
36
+ ✓ tree > complex dependency scenarios > should handle mixed dependency types 1ms
37
+ ✓ tree > inter-project dependency updates for tree publish > should handle dry run for inter-project dependency updates 1ms
38
+ ✓ tree > continue functionality and execution context > should handle missing execution context gracefully 1ms
39
+ × tree > continue functionality and execution context > should save execution context for publish commands 6ms
40
+ → Failed to analyze workspace: Command failed in package package-a
41
+ × tree > continue functionality and execution context > should cleanup context on successful completion 1ms
42
+ → Failed to analyze workspace: Command failed in package package-a
43
+ ✓ tree > built-in command execution > should execute commit command across packages 1ms
44
+ ✓ tree > built-in command execution > should execute link command with package argument 1ms
45
+ ✓ tree > built-in command execution > should execute unlink command with clean-node-modules option 1ms
46
+ × tree > built-in command execution > should propagate global options to built-in commands 2ms
47
+ → expected "spy" to be called at least once
48
+ ✓ tree > built-in command execution > should handle link status subcommand 1ms
49
+ ✓ tree > built-in command execution > should handle unlink status subcommand 1ms
50
+ ✓ tree > built-in command execution > should throw error for unsupported built-in command 1ms
51
+ × tree > inter-project dependency updates > should update inter-project dependencies before publish 1ms
52
+ → Failed to analyze workspace: Command failed in package package-a
53
+ × tree > inter-project dependency updates > should commit dependency updates before publish 1ms
54
+ → Failed to analyze workspace: Command failed in package package-a
55
+ ✓ tree > error handling edge cases > should handle working directory restoration failure 2ms
56
+ × tree > error handling edge cases > should handle storage errors during context operations 1ms
57
+ → Failed to analyze workspace: Command failed in package package-a
58
+ ✓ tree > error handling edge cases > should handle invalid execution context data 1ms
59
+ ✓ tree > multiple directory scenarios > should handle empty directories gracefully 1ms
60
+ ✓ tree > multiple directory scenarios > should handle mixed directory scenarios 1ms
61
+ ✓ tree > exclusion pattern edge cases > should handle complex glob patterns 1ms
62
+ ✓ tree > exclusion pattern edge cases > should handle exclusion patterns with special characters 1ms
63
+ ✓ tree > package logger functionality > should create package-specific loggers with correct prefixes 1ms
64
+ ✓ tree > package logger functionality > should handle dry run logging correctly 1ms
65
+ ✓ tree > branches command advanced features > should handle packages with consumers and link problems 1ms
66
+ ✓ tree > branches command advanced features > should handle ANSI color support detection 1ms
67
+ ✓ tree > verbose and debug logging modes > should provide detailed logging in verbose mode 1ms
68
+ ✓ tree > additional tree functionality > should handle exclusion patterns correctly 1ms
69
+ ✓ tree > additional tree functionality > should handle multiple directories scanning 1ms
70
+ ✓ tree > additional tree functionality > should show appropriate logging levels for command execution 1ms
71
+ ✓ tree > branches command > should display branch status table for all packages 1ms
72
+ ✓ tree > branches command > should handle git errors gracefully in branches command 1ms
73
+ ✓ tree > branches command > should format table columns correctly with varying lengths 1ms
74
+ ✓ tree > branches command > should not execute other commands when branches is specified 1ms
75
+ ✓ tree > branches command > should display asterisk for packages with linked dependencies 1ms
76
+
77
+ ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 6 ⎯⎯⎯⎯⎯⎯⎯
78
+
79
+ FAIL tests/commands/tree.test.ts > tree > continue functionality and execution context > should save execution context for publish commands
80
+ Error: Failed to analyze workspace: Command failed in package package-a
81
+ ❯ Module.execute src/commands/tree.ts:1648:15
82
+ 1646| const errorMessage = `Failed to analyze workspace: ${error.mes…
83
+ 1647| logger.error(errorMessage);
84
+ 1648| throw new Error(errorMessage);
85
+ | ^
86
+ 1649| } finally {
87
+ 1650| // Clean up mutex resources to prevent memory leaks
88
+ ❯ tests/commands/tree.test.ts:968:13
89
+
90
+ ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/6]⎯
91
+
92
+ FAIL tests/commands/tree.test.ts > tree > continue functionality and execution context > should cleanup context on successful completion
93
+ Error: Failed to analyze workspace: Command failed in package package-a
94
+ ❯ Module.execute src/commands/tree.ts:1648:15
95
+ 1646| const errorMessage = `Failed to analyze workspace: ${error.mes…
96
+ 1647| logger.error(errorMessage);
97
+ 1648| throw new Error(errorMessage);
98
+ | ^
99
+ 1649| } finally {
100
+ 1650| // Clean up mutex resources to prevent memory leaks
101
+ ❯ tests/commands/tree.test.ts:993:13
102
+
103
+ ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/6]⎯
104
+
105
+ FAIL tests/commands/tree.test.ts > tree > built-in command execution > should propagate global options to built-in commands
106
+ AssertionError: expected "spy" to be called at least once
107
+ ❯ tests/commands/tree.test.ts:1105:37
108
+ 1103|
109
+ 1104| // Verify the command was executed (basic check)
110
+ 1105| expect(mockExecPromise).toHaveBeenCalled();
111
+ | ^
112
+ 1106| });
113
+ 1107|
114
+
115
+ ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/6]⎯
116
+
117
+ FAIL tests/commands/tree.test.ts > tree > inter-project dependency updates > should update inter-project dependencies before publish
118
+ Error: Failed to analyze workspace: Command failed in package package-a
119
+ ❯ Module.execute src/commands/tree.ts:1648:15
120
+ 1646| const errorMessage = `Failed to analyze workspace: ${error.mes…
121
+ 1647| logger.error(errorMessage);
122
+ 1648| throw new Error(errorMessage);
123
+ | ^
124
+ 1649| } finally {
125
+ 1650| // Clean up mutex resources to prevent memory leaks
126
+ ❯ tests/commands/tree.test.ts:1186:13
127
+
128
+ ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/6]⎯
129
+
130
+ FAIL tests/commands/tree.test.ts > tree > inter-project dependency updates > should commit dependency updates before publish
131
+ Error: Failed to analyze workspace: Command failed in package package-a
132
+ ❯ Module.execute src/commands/tree.ts:1648:15
133
+ 1646| const errorMessage = `Failed to analyze workspace: ${error.mes…
134
+ 1647| logger.error(errorMessage);
135
+ 1648| throw new Error(errorMessage);
136
+ | ^
137
+ 1649| } finally {
138
+ 1650| // Clean up mutex resources to prevent memory leaks
139
+ ❯ tests/commands/tree.test.ts:1206:13
140
+
141
+ ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[5/6]⎯
142
+
143
+ FAIL tests/commands/tree.test.ts > tree > error handling edge cases > should handle storage errors during context operations
144
+ Error: Failed to analyze workspace: Command failed in package package-a
145
+ ❯ Module.execute src/commands/tree.ts:1648:15
146
+ 1646| const errorMessage = `Failed to analyze workspace: ${error.mes…
147
+ 1647| logger.error(errorMessage);
148
+ 1648| throw new Error(errorMessage);
149
+ | ^
150
+ 1649| } finally {
151
+ 1650| // Clean up mutex resources to prevent memory leaks
152
+ ❯ tests/commands/tree.test.ts:1253:13
153
+
154
+ ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[6/6]⎯
155
+
156
+
157
+ Test Files 1 failed (1)
158
+ Tests 6 failed | 54 passed (60)
159
+ Start at 10:00:29
160
+ Duration 500ms (transform 80ms, setup 0ms, collect 97ms, tests 57ms, environment 0ms, prepare 35ms)
161
+