claude-switch-profile 1.4.8 → 1.4.11
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/CHANGELOG.md +30 -0
- package/package.json +1 -1
- package/src/runtime-instance-manager.js +35 -3
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,36 @@ All notable changes to `claude-switch-profile` are documented here.
|
|
|
9
9
|
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
+
## [1.4.10] - 2026-04-01
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
- **Settings Path Mutation Bug**: Fixed a severe issue where hook paths in `settings.json` could exponentially multiply (like `.runtime/default-profiles/.runtime/...`) when saving a profile post-launch. Path mapping logic was strengthened to use exact-boundary Regular Expressions, preventing `.claude` patterns from incorrectly matching adjacent nested paths like `.claude-profiles`.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## [1.4.9] - 2026-04-01
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
- **Hooks execution in isolated mode**: Fixed an issue where Claude Code hook scripts failed to execute in isolated profiles. The runtime instance manager now correctly resolves shell variables (`$HOME`, `${HOME}`, `~`) within `settings.json` hook commands to accurately point to the isolated runtime directory.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## [1.4.8] - 2026-04-01
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
- Re-ran release flow to publish the latest patch after `1.4.7`.
|
|
30
|
+
- No functional code changes compared with `1.4.7`; this release aligns npm package/version metadata.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## [1.4.7] - 2026-04-01
|
|
35
|
+
|
|
36
|
+
### Fixed
|
|
37
|
+
- Release pipeline now restores annotated git tag publishing.
|
|
38
|
+
- Local agent artifacts are ignored by git to keep release working tree clean.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
12
42
|
## [1.4.2] - 2026-03-31
|
|
13
43
|
|
|
14
44
|
### Changed
|
package/package.json
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
readlinkSync,
|
|
12
12
|
} from 'node:fs';
|
|
13
13
|
import { join, dirname } from 'node:path';
|
|
14
|
+
import { homedir } from 'node:os';
|
|
14
15
|
import { MANAGED_ITEMS, COPY_ITEMS, COPY_DIRS, CLAUDE_DIR } from './constants.js';
|
|
15
16
|
import {
|
|
16
17
|
getActive,
|
|
@@ -76,6 +77,8 @@ const shouldSyncDir = (src, dest) => {
|
|
|
76
77
|
}
|
|
77
78
|
};
|
|
78
79
|
|
|
80
|
+
const escapeRegExp = (string) => string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
81
|
+
|
|
79
82
|
const replacePathVariants = (content, fromPath, toPath) => {
|
|
80
83
|
const fromEscaped = fromPath.replaceAll('\\', '\\\\');
|
|
81
84
|
const toEscaped = toPath.replaceAll('\\', '\\\\');
|
|
@@ -83,10 +86,20 @@ const replacePathVariants = (content, fromPath, toPath) => {
|
|
|
83
86
|
const toFwd = toPath.replaceAll('\\', '/');
|
|
84
87
|
|
|
85
88
|
let updated = content;
|
|
86
|
-
|
|
87
|
-
|
|
89
|
+
|
|
90
|
+
// Prevent matching substrings of other paths (e.g. ~/.claude matching ~/.claude-profiles)
|
|
91
|
+
// by ensuring it's not immediately followed by an alphanumeric character or hyphen.
|
|
92
|
+
const negativeLookahead = '(?![a-zA-Z0-9\\-])';
|
|
93
|
+
|
|
94
|
+
const replaceWithRegex = (str, targetF, targetT) => {
|
|
95
|
+
const re = new RegExp(escapeRegExp(targetF) + negativeLookahead, 'g');
|
|
96
|
+
return str.replace(re, targetT);
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
updated = replaceWithRegex(updated, fromEscaped, toEscaped);
|
|
100
|
+
updated = replaceWithRegex(updated, fromFwd, toFwd);
|
|
88
101
|
if (fromPath !== fromEscaped) {
|
|
89
|
-
updated = updated
|
|
102
|
+
updated = replaceWithRegex(updated, fromPath, toPath);
|
|
90
103
|
}
|
|
91
104
|
|
|
92
105
|
return updated;
|
|
@@ -103,6 +116,25 @@ const rewriteSettingsForRuntime = (runtimeDir, sourceDir) => {
|
|
|
103
116
|
updated = replacePathVariants(updated, sourceDir, runtimeDir);
|
|
104
117
|
updated = replacePathVariants(updated, CLAUDE_DIR, runtimeDir);
|
|
105
118
|
|
|
119
|
+
// Also replace shell variable patterns commonly used in hook commands.
|
|
120
|
+
// Hook commands in settings.json often reference paths like:
|
|
121
|
+
// $HOME/.claude/hooks/... or ${HOME}/.claude/hooks/... or ~/.claude/hooks/...
|
|
122
|
+
// These won't match the literal path replacement above.
|
|
123
|
+
const home = homedir();
|
|
124
|
+
const claudeRelSuffix = CLAUDE_DIR.startsWith(home) ? CLAUDE_DIR.slice(home.length) : '/.claude';
|
|
125
|
+
|
|
126
|
+
const shellPatterns = [
|
|
127
|
+
`$HOME${claudeRelSuffix}`,
|
|
128
|
+
`\${HOME}${claudeRelSuffix}`,
|
|
129
|
+
`~${claudeRelSuffix}`,
|
|
130
|
+
];
|
|
131
|
+
|
|
132
|
+
for (const pattern of shellPatterns) {
|
|
133
|
+
if (updated.includes(pattern)) {
|
|
134
|
+
updated = updated.replaceAll(pattern, runtimeDir);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
106
138
|
if (updated !== raw) {
|
|
107
139
|
writeFileSync(settingsPath, updated);
|
|
108
140
|
}
|