sshlg-skills 1.63.1 → 1.63.2
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 +12 -0
- package/lib/claude-pinned.js +2 -1
- package/lib/json-spans.js +23 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## v1.63.2 — the Claude transaction keeps settings in Claude Code's format
|
|
2
|
+
|
|
3
|
+
- Replacing a marketplace source in `~/.claude/settings.json` wrote the new object on one
|
|
4
|
+
line inside a 2-space file. The same `update` then refused to wire hooks ("not in the
|
|
5
|
+
2-space JSON format Claude Code writes"). A replaced object or array now keeps the
|
|
6
|
+
layout of its line: pretty inside a multi-line object, compact inside a single-line one.
|
|
7
|
+
Inserting a source — no marketplace map yet, an empty map, a new member or an empty
|
|
8
|
+
member entry — writes the missing branch in the file's own layout too.
|
|
9
|
+
- Found by the 1.63.1 installed update on a real profile: the native transaction verified
|
|
10
|
+
its three members, then hook wiring degraded. Running `update` again with 1.63.2
|
|
11
|
+
rewrites those sources in the file's own layout and wires hooks.
|
|
12
|
+
|
|
1
13
|
## v1.63.1 — Claude update works on hosts with live sessions
|
|
2
14
|
|
|
3
15
|
- `update` no longer refuses a Claude member whose installed payload already equals its
|
package/lib/claude-pinned.js
CHANGED
|
@@ -34,7 +34,8 @@ function editAt(text,keys,value) {
|
|
|
34
34
|
const parsed=J.parse(text);let node=parsed.root;
|
|
35
35
|
for(let i=0;i<keys.length-1;i++) {
|
|
36
36
|
let entry=node.props && node.props.find(p=>p.key===keys[i]);
|
|
37
|
-
|
|
37
|
+
// Insert the whole missing branch in one edit so it takes the file's layout.
|
|
38
|
+
if(!entry) return J.edit(text,node,keys[i],keys.slice(i+1).reduceRight((v,k)=>({[k]:v}),value));
|
|
38
39
|
if(!entry.value.props) throw Error('native Claude settings field is not an object');
|
|
39
40
|
node=entry.value;
|
|
40
41
|
}
|
package/lib/json-spans.js
CHANGED
|
@@ -53,7 +53,18 @@ function edit(text, object, key, value) {
|
|
|
53
53
|
if (!object || !object.props) throw new Error('target is not an object');
|
|
54
54
|
const ps = object.props, index = ps.findIndex(p => p.key === key), p = ps[index];
|
|
55
55
|
const splice = (start, end, insert = '') => text.slice(0, start) + insert + text.slice(end);
|
|
56
|
-
if (p && value !== undefined)
|
|
56
|
+
if (p && value !== undefined) {
|
|
57
|
+
// A replaced object or array keeps the layout of its line: pretty in a multi-line
|
|
58
|
+
// object (the format Claude Code itself writes), compact in a single-line one.
|
|
59
|
+
const nl = text.includes('\r\n') ? '\r\n' : '\n';
|
|
60
|
+
const lineStart = text.lastIndexOf('\n', p.start - 1) + 1;
|
|
61
|
+
const lead = text.slice(lineStart, p.start);
|
|
62
|
+
const multiline = /[\r\n]/.test(text.slice(object.start + 1, ps[0].start)) && /^[ \t]*$/.test(lead);
|
|
63
|
+
const unit = lead.includes('\t') ? '\t' : 2;
|
|
64
|
+
const encoded = multiline && value !== null && typeof value === 'object'
|
|
65
|
+
? JSON.stringify(value, null, unit).replace(/\n/g, nl + lead) : JSON.stringify(value);
|
|
66
|
+
return splice(p.value.start, p.value.end, encoded);
|
|
67
|
+
}
|
|
57
68
|
if (p) {
|
|
58
69
|
if (ps.length === 1) {
|
|
59
70
|
// Insertion into an empty object precedes its original whitespace.
|
|
@@ -72,7 +83,17 @@ function edit(text, object, key, value) {
|
|
|
72
83
|
const encoded = multiline ? JSON.stringify(value, null, 2).replace(/\n/g, newline + indent) : JSON.stringify(value);
|
|
73
84
|
const member = JSON.stringify(key) + colon + encoded;
|
|
74
85
|
if (ps.length) return splice(ps[ps.length - 1].end, ps[ps.length - 1].end, ',' + (multiline ? newline + indent : '') + member);
|
|
75
|
-
// Empty object has no foreign property bytes to alter.
|
|
86
|
+
// Empty object has no foreign property bytes to alter. In a multi-line document an
|
|
87
|
+
// empty `{}` that starts its own line opens onto lines of its own, one level deeper,
|
|
88
|
+
// which is the layout Claude Code writes; otherwise its existing gap is kept.
|
|
89
|
+
const lineStart = text.lastIndexOf('\n', object.start - 1) + 1;
|
|
90
|
+
const before = text.slice(lineStart, object.start);
|
|
91
|
+
const opens = /\n/.test(text) && text.slice(object.start, object.end) === '{}' && /^[ \t]*(?:"(?:[^"\\]|\\.)*"[ \t]*:[ \t]*)?$/.test(before);
|
|
92
|
+
if (opens) {
|
|
93
|
+
const base = before.match(/^[ \t]*/)[0], step = base.includes('\t') ? '\t' : ' ', inner = base + step;
|
|
94
|
+
const pretty = JSON.stringify(key) + ': ' + JSON.stringify(value, null, step === '\t' ? '\t' : 2).replace(/\n/g, newline + inner);
|
|
95
|
+
return splice(object.start + 1, object.start + 1, newline + inner + pretty + newline + base);
|
|
96
|
+
}
|
|
76
97
|
return splice(object.start + 1, object.start + 1, member);
|
|
77
98
|
}
|
|
78
99
|
|
package/package.json
CHANGED