throughline 0.3.21 → 0.3.22
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/package.json +1 -1
- package/src/cli/install.mjs +1 -1
- package/src/cli/install.test.mjs +29 -0
package/package.json
CHANGED
package/src/cli/install.mjs
CHANGED
|
@@ -39,7 +39,7 @@ const SC_HOOKS = {
|
|
|
39
39
|
hooks: [{ type: 'command', command: 'throughline session-start' }],
|
|
40
40
|
},
|
|
41
41
|
Stop: {
|
|
42
|
-
hooks: [{ type: 'command', command: 'throughline process-turn' }],
|
|
42
|
+
hooks: [{ type: 'command', command: 'throughline process-turn', async: true }],
|
|
43
43
|
},
|
|
44
44
|
UserPromptSubmit: {
|
|
45
45
|
hooks: [{ type: 'command', command: 'throughline prompt-submit' }],
|
package/src/cli/install.test.mjs
CHANGED
|
@@ -124,6 +124,35 @@ test('uninstall preserves unrelated slash commands in the same dir', async () =>
|
|
|
124
124
|
}
|
|
125
125
|
});
|
|
126
126
|
|
|
127
|
+
test('Stop hook is registered with async:true so it does not block ターン完了 UX', async () => {
|
|
128
|
+
const home = makeTempHome();
|
|
129
|
+
if (home.resolved !== home.dir) {
|
|
130
|
+
home.restore();
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const unsilence = silence();
|
|
134
|
+
try {
|
|
135
|
+
await run([]);
|
|
136
|
+
const settings = JSON.parse(readFileSync(join(home.dir, '.claude', 'settings.json'), 'utf8'));
|
|
137
|
+
const processTurnHook = settings.hooks.Stop
|
|
138
|
+
.flatMap(g => g.hooks ?? [])
|
|
139
|
+
.find(h => h.command === 'throughline process-turn');
|
|
140
|
+
assert.ok(processTurnHook, 'Stop should have throughline process-turn');
|
|
141
|
+
assert.equal(processTurnHook.async, true, 'Stop hook must be async to avoid blocking ターン完了');
|
|
142
|
+
const sessionStartHook = settings.hooks.SessionStart
|
|
143
|
+
.flatMap(g => g.hooks ?? [])
|
|
144
|
+
.find(h => h.command === 'throughline session-start');
|
|
145
|
+
assert.notEqual(sessionStartHook.async, true, 'SessionStart stays synchronous (needs to inject context before turn)');
|
|
146
|
+
const promptSubmitHook = settings.hooks.UserPromptSubmit
|
|
147
|
+
.flatMap(g => g.hooks ?? [])
|
|
148
|
+
.find(h => h.command === 'throughline prompt-submit');
|
|
149
|
+
assert.notEqual(promptSubmitHook.async, true, 'UserPromptSubmit stays synchronous (needs baton write committed before turn)');
|
|
150
|
+
} finally {
|
|
151
|
+
unsilence();
|
|
152
|
+
home.restore();
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
|
|
127
156
|
test('install is idempotent: second run keeps exactly one tl.md and one hook entry', async () => {
|
|
128
157
|
const home = makeTempHome();
|
|
129
158
|
if (home.resolved !== home.dir) {
|