glab-setup-git-identity 0.6.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 (66) hide show
  1. package/.changeset/README.md +8 -0
  2. package/.changeset/config.json +11 -0
  3. package/.github/workflows/release.yml +372 -0
  4. package/.husky/pre-commit +1 -0
  5. package/.jscpd.json +20 -0
  6. package/.prettierignore +7 -0
  7. package/.prettierrc +10 -0
  8. package/CHANGELOG.md +143 -0
  9. package/LICENSE +24 -0
  10. package/README.md +455 -0
  11. package/bunfig.toml +3 -0
  12. package/deno.json +7 -0
  13. package/docs/case-studies/issue-13/README.md +195 -0
  14. package/docs/case-studies/issue-13/hive-mind-issue-960.json +23 -0
  15. package/docs/case-studies/issue-13/hive-mind-pr-961-diff.txt +773 -0
  16. package/docs/case-studies/issue-13/hive-mind-pr-961.json +126 -0
  17. package/docs/case-studies/issue-21/README.md +384 -0
  18. package/docs/case-studies/issue-21/ci-logs/run-20803315337.txt +1188 -0
  19. package/docs/case-studies/issue-21/ci-logs/run-20885464993.txt +1310 -0
  20. package/docs/case-studies/issue-21/issue-111-data.txt +15 -0
  21. package/docs/case-studies/issue-21/issue-113-data.txt +15 -0
  22. package/docs/case-studies/issue-21/pr-112-data.json +109 -0
  23. package/docs/case-studies/issue-21/pr-112-diff.patch +1336 -0
  24. package/docs/case-studies/issue-21/pr-114-data.json +126 -0
  25. package/docs/case-studies/issue-21/pr-114-diff.patch +879 -0
  26. package/docs/case-studies/issue-3/README.md +338 -0
  27. package/docs/case-studies/issue-3/created-issues.md +32 -0
  28. package/docs/case-studies/issue-3/issue-data.json +29 -0
  29. package/docs/case-studies/issue-3/original-format-release-notes.mjs +212 -0
  30. package/docs/case-studies/issue-3/reference-pr-59-diff.txt +614 -0
  31. package/docs/case-studies/issue-3/reference-pr-59.json +109 -0
  32. package/docs/case-studies/issue-3/release-v0.1.0.json +9 -0
  33. package/docs/case-studies/issue-3/repositories-with-same-script.json +22 -0
  34. package/docs/case-studies/issue-3/research-notes.md +33 -0
  35. package/docs/case-studies/issue-7/BEST-PRACTICES-COMPARISON.md +334 -0
  36. package/docs/case-studies/issue-7/FORMATTER-COMPARISON.md +649 -0
  37. package/docs/case-studies/issue-7/current-repository-analysis.json +70 -0
  38. package/docs/case-studies/issue-7/effect-template-analysis.json +178 -0
  39. package/eslint.config.js +91 -0
  40. package/examples/basic-usage.js +64 -0
  41. package/experiments/test-changeset-scripts.mjs +303 -0
  42. package/experiments/test-failure-detection.mjs +143 -0
  43. package/experiments/test-format-major-changes.mjs +49 -0
  44. package/experiments/test-format-minor-changes.mjs +52 -0
  45. package/experiments/test-format-no-hash.mjs +43 -0
  46. package/experiments/test-format-patch-changes.mjs +46 -0
  47. package/package.json +80 -0
  48. package/scripts/changeset-version.mjs +75 -0
  49. package/scripts/check-changesets.mjs +67 -0
  50. package/scripts/check-version.mjs +129 -0
  51. package/scripts/create-github-release.mjs +93 -0
  52. package/scripts/create-manual-changeset.mjs +89 -0
  53. package/scripts/detect-code-changes.mjs +194 -0
  54. package/scripts/format-github-release.mjs +83 -0
  55. package/scripts/format-release-notes.mjs +219 -0
  56. package/scripts/instant-version-bump.mjs +172 -0
  57. package/scripts/js-paths.mjs +177 -0
  58. package/scripts/merge-changesets.mjs +263 -0
  59. package/scripts/publish-to-npm.mjs +302 -0
  60. package/scripts/setup-npm.mjs +37 -0
  61. package/scripts/validate-changeset.mjs +265 -0
  62. package/scripts/version-and-commit.mjs +284 -0
  63. package/src/cli.js +386 -0
  64. package/src/index.d.ts +255 -0
  65. package/src/index.js +563 -0
  66. package/tests/index.test.js +137 -0
@@ -0,0 +1,126 @@
1
+ {
2
+ "additions": 644,
3
+ "author": {
4
+ "id": "MDQ6VXNlcjE0MzE5MDQ=",
5
+ "is_bot": false,
6
+ "login": "konard",
7
+ "name": "Konstantin Diachenko"
8
+ },
9
+ "baseRefName": "main",
10
+ "body": "## Summary\n\nThis PR makes the changeset CI/CD system more robust by addressing the issue where PRs fail validation when multiple PRs merge before a release cycle completes.\n\n### Changes Made\n\n- **Update validate-changeset.mjs to check only PR-added changesets**\n - Uses git diff to compare base vs head SHA\n - Only validates changesets ADDED by the current PR (not pre-existing ones from merged PRs)\n - Falls back to checking all changesets for local development\n\n- **Add merge-changesets.mjs script**\n - Combines multiple pending changesets into a single merged changeset during release\n - Uses the highest version bump type (major > minor > patch)\n - Preserves all descriptions in chronological order (by file modification time)\n - Cleans up individual changeset files after merging\n\n- **Update release workflow**\n - Adds step to merge multiple changesets before running `changeset version`\n - Passes proper environment variables (GITHUB_BASE_SHA, GITHUB_HEAD_SHA) to validation script\n\n- **Add comprehensive tests**\n - Tests for both validate-changeset.mjs and merge-changesets.mjs\n - Tests for bump type priority, chronological ordering, edge cases\n\n### How It Works\n\n**During PR validation:**\n```\nBefore: Check all .changeset/*.md files → Fail if >1 exists\nAfter: Check only files ADDED in this PR → Fail if >1 was added\n```\n\n**During release:**\n```\nBefore: changeset version → (fail if multiple changesets)\nAfter: merge-changesets.mjs → changeset version → (always single changeset)\n```\n\n### Benefits\n\n1. **No more false failures** - PRs won't fail just because other PRs merged first\n2. **Preserved sequence** - Changesets are merged chronologically\n3. **Correct version bumps** - Major changes won't be downgraded to patch\n4. **Backward compatible** - Local development still works without git context\n\n### Testing\n\nAll tests pass locally:\n- `node experiments/test-changeset-scripts.mjs` - 10/10 tests pass\n- `npm run format:check` - passes\n- `npm run lint` - passes\n\n## Fixes\n\nFixes #960\n\n---\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n",
11
+ "commits": [
12
+ {
13
+ "authoredDate": "2025-12-22T06:32:45Z",
14
+ "authors": [
15
+ {
16
+ "email": "drakonard@gmail.com",
17
+ "id": "MDQ6VXNlcjE0MzE5MDQ=",
18
+ "login": "konard",
19
+ "name": "konard"
20
+ }
21
+ ],
22
+ "committedDate": "2025-12-22T06:32:45Z",
23
+ "messageBody": "Adding CLAUDE.md with task information for AI processing.\nThis file will be removed when the task is complete.\n\nIssue: https://github.com/link-assistant/hive-mind/issues/960",
24
+ "messageHeadline": "Initial commit with task details",
25
+ "oid": "a352ed4055d96cbc47e3bad062674c37104f2705"
26
+ },
27
+ {
28
+ "authoredDate": "2025-12-22T06:39:54Z",
29
+ "authors": [
30
+ {
31
+ "email": "drakonard@gmail.com",
32
+ "id": "MDQ6VXNlcjE0MzE5MDQ=",
33
+ "login": "konard",
34
+ "name": "konard"
35
+ },
36
+ {
37
+ "email": "noreply@anthropic.com",
38
+ "id": "MDQ6VXNlcjgxODQ3",
39
+ "login": "claude",
40
+ "name": "Claude"
41
+ }
42
+ ],
43
+ "committedDate": "2025-12-22T06:39:54Z",
44
+ "messageBody": "- Update validate-changeset.mjs to check only changesets ADDED by the PR\n (uses git diff to compare base vs head, not all files in .changeset/)\n- Add merge-changesets.mjs to combine multiple pending changesets during release\n (uses highest bump type, preserves descriptions chronologically)\n- Update release workflow to merge multiple changesets before version bump\n- Add comprehensive tests for both changeset scripts\n\nThis fixes the issue where PRs fail validation when multiple PRs merge\nbefore a release cycle completes (each PR sees the other's changesets).\n\nFixes #960\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
45
+ "messageHeadline": "Improve changeset CI/CD robustness for concurrent PRs",
46
+ "oid": "8934ed62e8436b80ab0d620e24731d1d447fbe06"
47
+ },
48
+ {
49
+ "authoredDate": "2025-12-22T06:41:49Z",
50
+ "authors": [
51
+ {
52
+ "email": "drakonard@gmail.com",
53
+ "id": "MDQ6VXNlcjE0MzE5MDQ=",
54
+ "login": "konard",
55
+ "name": "konard"
56
+ },
57
+ {
58
+ "email": "noreply@anthropic.com",
59
+ "id": "MDQ6VXNlcjgxODQ3",
60
+ "login": "claude",
61
+ "name": "Claude"
62
+ }
63
+ ],
64
+ "committedDate": "2025-12-22T06:41:49Z",
65
+ "messageBody": "🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
66
+ "messageHeadline": "Remove CLAUDE.md task file (not needed in PR)",
67
+ "oid": "70607f2aa60aca2c1ee985f6327dacc5dbc4e9bf"
68
+ },
69
+ {
70
+ "authoredDate": "2025-12-22T07:22:07Z",
71
+ "authors": [
72
+ {
73
+ "email": "drakonard@gmail.com",
74
+ "id": "MDQ6VXNlcjE0MzE5MDQ=",
75
+ "login": "konard",
76
+ "name": "konard"
77
+ },
78
+ {
79
+ "email": "noreply@anthropic.com",
80
+ "id": "MDQ6VXNlcjgxODQ3",
81
+ "login": "claude",
82
+ "name": "Claude"
83
+ }
84
+ ],
85
+ "committedDate": "2025-12-22T07:22:07Z",
86
+ "messageBody": "The test script is not part of regular CI/CD runs, it's meant\nfor one-time verification during development. Per feedback,\nmoving it to experiments folder to better reflect its purpose.\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
87
+ "messageHeadline": "Move test-changeset-scripts.mjs to experiments folder",
88
+ "oid": "4b415eca0a66154fea175a8f68121fea5ed509ca"
89
+ }
90
+ ],
91
+ "createdAt": "2025-12-22T06:32:52Z",
92
+ "deletions": 53,
93
+ "files": [
94
+ {
95
+ "path": ".changeset/robust-changeset-cicd.md",
96
+ "additions": 11,
97
+ "deletions": 0
98
+ },
99
+ {
100
+ "path": ".github/workflows/release.yml",
101
+ "additions": 14,
102
+ "deletions": 0
103
+ },
104
+ {
105
+ "path": "experiments/test-changeset-scripts.mjs",
106
+ "additions": 257,
107
+ "deletions": 0
108
+ },
109
+ {
110
+ "path": "scripts/merge-changesets.mjs",
111
+ "additions": 184,
112
+ "deletions": 0
113
+ },
114
+ {
115
+ "path": "scripts/validate-changeset.mjs",
116
+ "additions": 178,
117
+ "deletions": 53
118
+ }
119
+ ],
120
+ "headRefName": "issue-960-4b0fdff43593",
121
+ "labels": [],
122
+ "mergedAt": "2025-12-22T19:22:16Z",
123
+ "number": 961,
124
+ "state": "MERGED",
125
+ "title": "Improve changeset CI/CD robustness for concurrent PRs"
126
+ }
@@ -0,0 +1,384 @@
1
+ # Case Study: Issue #21 - Supporting Both Single-Language and Multi-Language Repositories
2
+
3
+ ## Executive Summary
4
+
5
+ This case study analyzes two related CI/CD pipeline failures in the [link-assistant/agent](https://github.com/link-assistant/agent) repository and documents best practices for supporting both single-language and multi-language repository structures in CI/CD scripts.
6
+
7
+ The issues stemmed from:
8
+
9
+ 1. **Issue #111**: npm peer dependency conflicts requiring `--legacy-peer-deps` flag
10
+ 2. **Issue #113**: Working directory corruption caused by the `command-stream` library's virtual `cd` command
11
+
12
+ ## Background
13
+
14
+ The link-assistant/agent repository is a multi-language monorepo containing:
15
+
16
+ - JavaScript/TypeScript code in the `js/` subfolder
17
+ - Rust code in the `rust/` subfolder
18
+
19
+ The CI/CD scripts needed to support both:
20
+
21
+ - **Multi-language repositories** (like link-assistant/agent) where `package.json` is at `./js/package.json`
22
+ - **Single-language repositories** where `package.json` is at `./package.json` (repository root)
23
+
24
+ ## Timeline of Events
25
+
26
+ ### Issue #111 - npm ERESOLVE Error
27
+
28
+ | Timestamp (UTC) | Event |
29
+ | ------------------- | ------------------------------------------------------ |
30
+ | 2026-01-08 02:22:24 | CI Run #20803315337 triggered on push to main branch |
31
+ | 2026-01-08 02:22:46 | Lint and Format Check completed successfully |
32
+ | 2026-01-08 02:22:29 | Ubuntu unit tests passed |
33
+ | 2026-01-08 02:22:32 | macOS unit tests passed |
34
+ | 2026-01-08 02:23:24 | Windows unit tests passed |
35
+ | 2026-01-08 02:23:32 | Release job started |
36
+ | 2026-01-08 02:23:55 | Changeset version ran successfully |
37
+ | 2026-01-08 02:23:56 | `npm install --package-lock-only` failed with ERESOLVE |
38
+ | 2026-01-08 02:23:58 | Release job failed with exit code 1 |
39
+
40
+ ### Issue #113 - Working Directory Corruption
41
+
42
+ | Timestamp (UTC) | Event |
43
+ | ------------------- | ------------------------------------------------------------------ |
44
+ | 2026-01-10 22:38:48 | PR #112 merged (fixed --legacy-peer-deps) |
45
+ | 2026-01-10 22:38:56 | CI Run #20885464993 triggered |
46
+ | 2026-01-10 22:40:29 | Version bump completed successfully |
47
+ | 2026-01-10 22:40:29 | Error: ENOENT: no such file or directory, open './js/package.json' |
48
+ | 2026-01-10 22:40:29 | Release job failed with exit code 1 |
49
+
50
+ ## Root Cause Analysis
51
+
52
+ ### Root Cause #1: Missing `--legacy-peer-deps` Flag
53
+
54
+ **Problem**: The release scripts (`changeset-version.mjs` and `instant-version-bump.mjs`) were running `npm install --package-lock-only` without the `--legacy-peer-deps` flag.
55
+
56
+ **Error Message**:
57
+
58
+ ```
59
+ npm error code ERESOLVE
60
+ npm error ERESOLVE could not resolve
61
+ npm error While resolving: @opentui/solid@0.1.60
62
+ npm error Found: solid-js@1.9.10
63
+ npm error Could not resolve dependency:
64
+ npm error peer solid-js@"1.9.9" from @opentui/solid@0.1.60
65
+ ```
66
+
67
+ **Root Cause**: Starting with npm 7, the package manager enforces stricter peer dependency rules. The project had conflicting peer dependency requirements:
68
+
69
+ - `@opentui/solid@0.1.60` required exactly `solid-js@1.9.9`
70
+ - The root project specified `solid-js@^1.9.10`
71
+
72
+ **Inconsistency**: The workflow file (`js.yml`) correctly used `--legacy-peer-deps` for initial `npm install`, but the release scripts did not.
73
+
74
+ ### Root Cause #2: Virtual `cd` Command Behavior
75
+
76
+ **Problem**: The `command-stream` library implements `cd` as a virtual command that calls `process.chdir()` on the Node.js process itself, permanently changing the working directory.
77
+
78
+ **Code Flow**:
79
+
80
+ ```
81
+ Repository Root (/)
82
+ ├── js/
83
+ │ └── package.json <- Target file
84
+ └── scripts/
85
+ └── version-and-commit.mjs
86
+
87
+ 1. Script starts with cwd = /
88
+ 2. Script runs: await $`cd js && npm run changeset:version`
89
+ 3. command-stream's cd command calls: process.chdir('js')
90
+ 4. cwd is now /js/
91
+ 5. Script tries to read: readFileSync('./js/package.json')
92
+ 6. This resolves to: /js/js/package.json <- DOES NOT EXIST!
93
+ 7. Error: ENOENT
94
+ ```
95
+
96
+ **Error Message**:
97
+
98
+ ```
99
+ Error: ENOENT: no such file or directory, open './js/package.json'
100
+ ```
101
+
102
+ **Why This Was Hard to Detect**:
103
+
104
+ - The `cd` command in most shell scripts only affects the subprocess, not the parent process
105
+ - Developers familiar with Unix shells would not expect `cd` to affect the Node.js process
106
+ - The error message didn't clearly indicate that the working directory had changed
107
+ - The `command-stream` library documentation doesn't prominently warn about this behavior
108
+
109
+ ## Solutions Implemented
110
+
111
+ ### Solution #1: Add `--legacy-peer-deps` Flag (PR #112)
112
+
113
+ **Files Modified**:
114
+
115
+ - `scripts/changeset-version.mjs`
116
+ - `scripts/instant-version-bump.mjs`
117
+
118
+ **Change**:
119
+
120
+ ```javascript
121
+ // Before
122
+ await $`npm install --package-lock-only`;
123
+
124
+ // After
125
+ await $`npm install --package-lock-only --legacy-peer-deps`;
126
+ ```
127
+
128
+ ### Solution #2: Working Directory Restoration and Auto-Detection (PR #114)
129
+
130
+ **New Utility Modules Created**:
131
+
132
+ - `scripts/js-paths.mjs` - JavaScript package root detection
133
+ - `scripts/rust-paths.mjs` - Rust package root detection
134
+
135
+ **Key Features**:
136
+
137
+ 1. **Automatic Package Root Detection**:
138
+ - Check for `./package.json` or `./Cargo.toml` first (single-language repo)
139
+ - If not found, check `./js/` or `./rust/` subfolder (multi-language repo)
140
+ - Throw helpful error if neither exists
141
+
142
+ 2. **Explicit Configuration Options**:
143
+ - CLI arguments: `--js-root <path>` or `--rust-root <path>`
144
+ - Environment variables: `JS_ROOT` or `RUST_ROOT`
145
+
146
+ 3. **Working Directory Preservation**:
147
+
148
+ ```javascript
149
+ // Store the original working directory
150
+ const originalCwd = process.cwd();
151
+
152
+ try {
153
+ // Code that uses cd
154
+ await $`cd js && npm run changeset:version`;
155
+
156
+ // Restore the original working directory
157
+ process.chdir(originalCwd);
158
+
159
+ // Now file operations work correctly
160
+ const packageJson = JSON.parse(readFileSync('./js/package.json', 'utf8'));
161
+ } catch (error) {
162
+ // Handle error
163
+ }
164
+ ```
165
+
166
+ **Updated Scripts**:
167
+
168
+ - `scripts/version-and-commit.mjs`
169
+ - `scripts/instant-version-bump.mjs`
170
+ - `scripts/publish-to-npm.mjs`
171
+ - `scripts/rust-version-and-commit.mjs`
172
+ - `scripts/rust-collect-changelog.mjs`
173
+ - `scripts/rust-get-bump-type.mjs`
174
+
175
+ ## Best Practices for Multi-Language Repositories
176
+
177
+ Based on this case study and industry research, here are recommended best practices:
178
+
179
+ ### 1. Consistent npm Flag Usage
180
+
181
+ **Problem**: Using `--legacy-peer-deps` in some places but not others causes inconsistent behavior.
182
+
183
+ **Best Practice**:
184
+
185
+ - If using `--legacy-peer-deps`, use it consistently across all npm install commands
186
+ - Consider adding a `.npmrc` file with `legacy-peer-deps=true` for project-wide consistency
187
+ - Document the reason for using this flag for future maintainers
188
+
189
+ ### 2. Automatic Package Root Detection
190
+
191
+ **Problem**: Hardcoding paths like `./js/package.json` doesn't work for single-language repos.
192
+
193
+ **Best Practice**:
194
+
195
+ ```javascript
196
+ // Detect JavaScript package root
197
+ function getJsRoot() {
198
+ if (existsSync('./package.json')) return '.'; // Single-language
199
+ if (existsSync('./js/package.json')) return 'js'; // Multi-language
200
+ throw new Error('package.json not found');
201
+ }
202
+ ```
203
+
204
+ ### 3. Working Directory Management
205
+
206
+ **Problem**: Some shell libraries modify `process.cwd()` unexpectedly.
207
+
208
+ **Best Practice**:
209
+
210
+ - Always save and restore the original working directory when using `cd` commands
211
+ - Use absolute paths when possible
212
+ - Prefer `--prefix` or `--cwd` options over `cd` when available
213
+
214
+ ### 4. Modular Project Structure
215
+
216
+ **Best Practice**: Organize multi-language repositories with clear separation:
217
+
218
+ ```
219
+ repository/
220
+ ├── js/ # JavaScript/TypeScript
221
+ │ ├── package.json
222
+ │ └── src/
223
+ ├── rust/ # Rust
224
+ │ ├── Cargo.toml
225
+ │ └── src/
226
+ ├── scripts/ # Shared CI/CD scripts
227
+ └── .github/workflows/
228
+ ```
229
+
230
+ ### 5. Unified Task Commands
231
+
232
+ **Best Practice**: Provide unified scripts that work across both repo structures:
233
+
234
+ ```bash
235
+ # Auto-detection (default)
236
+ node scripts/version-and-commit.mjs --mode changeset
237
+
238
+ # Explicit configuration
239
+ node scripts/version-and-commit.mjs --mode changeset --js-root js
240
+
241
+ # Via environment variable
242
+ JS_ROOT=js node scripts/version-and-commit.mjs --mode changeset
243
+ ```
244
+
245
+ ### 6. Caching Language-Specific Artifacts
246
+
247
+ **Best Practice**: Cache appropriately based on language:
248
+
249
+ - JavaScript: `node_modules/`, `package-lock.json`
250
+ - Rust: `target/`, `Cargo.lock`
251
+ - Use remote caches for CI efficiency
252
+
253
+ ## Lessons Learned
254
+
255
+ 1. **Understand Library Internals**: Third-party libraries may have non-obvious behaviors. The `command-stream` library's virtual `cd` command is powerful but can cause issues if not handled properly.
256
+
257
+ 2. **Consistency is Key**: When using npm flags like `--legacy-peer-deps`, ensure they are used consistently across all npm install commands in both workflow files and scripts.
258
+
259
+ 3. **Test Release Workflows**: Release workflows often run in different conditions than regular CI. Test them separately to catch issues like these.
260
+
261
+ 4. **Add Defensive Code**: When using commands that modify process state, always save and restore the original state.
262
+
263
+ 5. **Document Non-Obvious Behaviors**: Include detailed comments explaining why certain patterns (like `process.chdir()` restoration) are necessary.
264
+
265
+ 6. **Support Multiple Repository Structures**: Design CI/CD scripts to auto-detect and support both single-language and multi-language repository structures.
266
+
267
+ ## References
268
+
269
+ ### External Resources
270
+
271
+ - [Managing multiple languages in a monorepo](https://graphite.dev/guides/managing-multiple-languages-in-a-monorepo)
272
+ - [Monorepo Explained](https://monorepo.tools/)
273
+ - [Benefits and challenges of monorepo development practices - CircleCI](https://circleci.com/blog/monorepo-dev-practices/)
274
+ - [Building a Monorepo with Rust - Earthly Blog](https://earthly.dev/blog/rust-monorepo/)
275
+ - [Node.js process.chdir() Method - GeeksforGeeks](https://www.geeksforgeeks.org/node-js-process-chdir-method/)
276
+ - [Fix 'npm ERR! ERESOLVE unable to resolve dependency tree'](https://blog.openreplay.com/fix-npm-err-eresolve-dependency/)
277
+ - [Resolving NPM Peer Dependency Conflicts](https://medium.com/@robert.maiersilldorff/resolving-npm-peer-dependency-conflicts-70d67f4ca7dc)
278
+
279
+ ### Related Issues and Pull Requests
280
+
281
+ - [Issue #111](https://github.com/link-assistant/agent/issues/111) - JS release does not work
282
+ - [Issue #113](https://github.com/link-assistant/agent/issues/113) - JavaScript publish does not work
283
+ - [PR #112](https://github.com/link-assistant/agent/pull/112) - fix: Add --legacy-peer-deps flag to release scripts
284
+ - [PR #114](https://github.com/link-assistant/agent/pull/114) - feat: Add configurable package root for release scripts
285
+
286
+ ### CI Logs (Preserved)
287
+
288
+ - `ci-logs/run-20803315337.txt` - Issue #111 CI failure log
289
+ - `ci-logs/run-20885464993.txt` - Issue #113 CI failure log
290
+
291
+ ## Proposed Solutions for This Template Repository
292
+
293
+ Based on the analysis above, this template repository (js-ai-driven-development-pipeline-template) should incorporate these solutions to ensure best practices by default:
294
+
295
+ ### 1. Add Path Detection Utilities
296
+
297
+ Create `scripts/js-paths.mjs` with automatic package root detection:
298
+
299
+ - Support `./package.json` for single-language repos
300
+ - Support `./js/package.json` for multi-language repos
301
+ - Provide CLI and environment variable configuration options
302
+
303
+ ### 2. Update Release Scripts
304
+
305
+ Modify all release scripts to:
306
+
307
+ - Use the path detection utilities
308
+ - Save and restore `process.cwd()` after `cd` commands
309
+ - Use `--legacy-peer-deps` consistently for npm commands
310
+
311
+ ### 3. Add `.npmrc` Configuration (Optional)
312
+
313
+ Consider adding a `.npmrc` file with:
314
+
315
+ ```
316
+ legacy-peer-deps=true
317
+ ```
318
+
319
+ ### 4. Document the Approach
320
+
321
+ Update repository documentation to explain:
322
+
323
+ - How scripts auto-detect repository structure
324
+ - How to configure for different project layouts
325
+ - Known limitations and workarounds
326
+
327
+ ### 5. Prevent False Positives in CI/CD (Based on Issue #115/PR #116)
328
+
329
+ **Problem**: The `changeset publish` command exits with code 0 even when packages fail to publish. The `command-stream` library doesn't throw exceptions on non-zero exit codes. This can result in false positive CI/CD statuses where failures are reported as successes.
330
+
331
+ **Best Practice**: Implement multi-layer failure detection:
332
+
333
+ 1. **Output pattern matching** - Scan command output for failure patterns:
334
+
335
+ ```javascript
336
+ const FAILURE_PATTERNS = [
337
+ 'packages failed to publish',
338
+ 'error occurred while publishing',
339
+ 'npm error code E',
340
+ 'npm error 404',
341
+ 'npm error 401',
342
+ 'npm error 403',
343
+ 'Access token expired',
344
+ 'ENEEDAUTH',
345
+ ];
346
+
347
+ function detectPublishFailure(output) {
348
+ const lowerOutput = output.toLowerCase();
349
+ for (const pattern of FAILURE_PATTERNS) {
350
+ if (lowerOutput.includes(pattern.toLowerCase())) {
351
+ return pattern;
352
+ }
353
+ }
354
+ return null;
355
+ }
356
+ ```
357
+
358
+ 2. **Exit code checking** - Check the exit code even though `changeset` may return 0 on failure:
359
+
360
+ ```javascript
361
+ if (result.code !== 0) {
362
+ throw new Error(`Publish failed with exit code ${result.code}`);
363
+ }
364
+ ```
365
+
366
+ 3. **Post-publish verification** - Verify the package is actually on npm:
367
+
368
+ ```javascript
369
+ async function verifyPublished(packageName, version) {
370
+ const result = await $`npm view "${packageName}@${version}" version`.run({
371
+ capture: true,
372
+ });
373
+ return result.code === 0 && result.stdout.trim().includes(version);
374
+ }
375
+ ```
376
+
377
+ 4. **Use `.run({ capture: true })`** - Capture command output for analysis instead of just running and assuming success.
378
+
379
+ **Related References**:
380
+
381
+ - [Issue #115](https://github.com/link-assistant/agent/issues/115) - Error was treated as success
382
+ - [PR #116](https://github.com/link-assistant/agent/pull/116) - fix: Add publish verification and failure detection to prevent false positives
383
+ - [Changesets Issue #1621](https://github.com/changesets/changesets/issues/1621) - Git tag failure isn't handled
384
+ - [Changesets Issue #1280](https://github.com/changesets/changesets/issues/1280) - Action succeeds but package is never published