@sayknow-cli/coding-agent 0.5.15 → 0.5.17
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/package.json +7 -7
- package/src/hooks/native-skill-hook.ts +88 -53
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.5.17] - 2026-09-16
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Compute the bundled UI-skill directive before workflow-state lookups in `UserPromptSubmit`, and isolate each lookup so a Linux CI recovery/activation failure cannot return empty context for `animate` / `ralplan` routing.
|
|
10
|
+
|
|
11
|
+
## [0.5.16] - 2026-09-16
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- Native skill hooks never throw out of `UserPromptSubmit` / `Stop`. A failed install-root or state lookup returns empty context instead of aborting the turn, which is what collapsed the bundled UI-skill directive in Linux CI.
|
|
16
|
+
|
|
5
17
|
## [0.5.15] - 2026-09-16
|
|
6
18
|
|
|
7
19
|
### Fixed
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@sayknow-cli/coding-agent",
|
|
4
|
-
"version": "0.5.
|
|
4
|
+
"version": "0.5.17",
|
|
5
5
|
"description": "Sayknow-CLI CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://sayknow-cli.com",
|
|
7
7
|
"author": "jaybeyond",
|
|
@@ -54,12 +54,12 @@
|
|
|
54
54
|
"@agentclientprotocol/sdk": "1.3.0",
|
|
55
55
|
"@babel/parser": "^7.29.3",
|
|
56
56
|
"@mozilla/readability": "^0.6.0",
|
|
57
|
-
"@sayknow-cli/stats": "0.5.
|
|
58
|
-
"@sayknow-cli/agent-core": "0.5.
|
|
59
|
-
"@sayknow-cli/ai": "0.5.
|
|
60
|
-
"@sayknow-cli/natives": "0.5.
|
|
61
|
-
"@sayknow-cli/tui": "0.5.
|
|
62
|
-
"@sayknow-cli/utils": "0.5.
|
|
57
|
+
"@sayknow-cli/stats": "0.5.17",
|
|
58
|
+
"@sayknow-cli/agent-core": "0.5.17",
|
|
59
|
+
"@sayknow-cli/ai": "0.5.17",
|
|
60
|
+
"@sayknow-cli/natives": "0.5.17",
|
|
61
|
+
"@sayknow-cli/tui": "0.5.17",
|
|
62
|
+
"@sayknow-cli/utils": "0.5.17",
|
|
63
63
|
"@puppeteer/browsers": "^2.13.0",
|
|
64
64
|
"@types/turndown": "5.0.6",
|
|
65
65
|
"@xterm/headless": "^6.0.0",
|
|
@@ -288,47 +288,98 @@ function readSessionFile(payload: HookPayload): string | undefined {
|
|
|
288
288
|
export async function dispatchSkcNativeSkillHook(
|
|
289
289
|
payload: HookPayload,
|
|
290
290
|
options: SkcNativeHookDispatchOptions = {},
|
|
291
|
+
): Promise<SkcNativeHookDispatchResult> {
|
|
292
|
+
try {
|
|
293
|
+
return await dispatchSkcNativeSkillHookInner(payload, options);
|
|
294
|
+
} catch {
|
|
295
|
+
// A native hook must never fail the turn. Surface nothing rather than
|
|
296
|
+
// aborting UserPromptSubmit / Stop over an install-root or state lookup.
|
|
297
|
+
const hookEventName = readHookEventName(payload);
|
|
298
|
+
return { hookEventName, outputJson: null };
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
async function dispatchSkcNativeSkillHookInner(
|
|
303
|
+
payload: HookPayload,
|
|
304
|
+
options: SkcNativeHookDispatchOptions = {},
|
|
291
305
|
): Promise<SkcNativeHookDispatchResult> {
|
|
292
306
|
const hookEventName = readHookEventName(payload);
|
|
293
307
|
const cwd = (options.cwd ?? safeString(payload.cwd).trim()) || process.cwd();
|
|
294
308
|
if (hookEventName === "UserPromptSubmit") {
|
|
295
|
-
const recoveryDiagnostics = await collectUserPromptStateRecoveryDiagnostics({
|
|
296
|
-
cwd,
|
|
297
|
-
sessionId: readSessionId(payload),
|
|
298
|
-
threadId: readThreadId(payload),
|
|
299
|
-
stateDir: options.stateDir,
|
|
300
|
-
prompt: readPromptText(payload),
|
|
301
|
-
sessionFile: readSessionFile(payload),
|
|
302
|
-
});
|
|
303
|
-
const recoveryContext = buildStateRecoveryDiagnosticsContext(recoveryDiagnostics);
|
|
304
309
|
const prompt = readPromptText(payload);
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
310
|
+
// Compute the bundled UI-skill directive first so a later state/recovery
|
|
311
|
+
// lookup cannot abort the turn without it.
|
|
312
|
+
const uiSkillContext = buildUiSkillActivationContext(prompt);
|
|
313
|
+
let externalUiContext: string | null = null;
|
|
314
|
+
try {
|
|
315
|
+
externalUiContext = await buildExternalUiSkillContext({
|
|
316
|
+
cwd,
|
|
317
|
+
home: options.home ?? os.homedir(),
|
|
318
|
+
text: prompt,
|
|
319
|
+
});
|
|
320
|
+
} catch {
|
|
321
|
+
externalUiContext = null;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
let recoveryContext: string | null = null;
|
|
325
|
+
try {
|
|
326
|
+
const recoveryDiagnostics = await collectUserPromptStateRecoveryDiagnostics({
|
|
327
|
+
cwd,
|
|
328
|
+
sessionId: readSessionId(payload),
|
|
329
|
+
threadId: readThreadId(payload),
|
|
330
|
+
stateDir: options.stateDir,
|
|
331
|
+
prompt,
|
|
332
|
+
sessionFile: readSessionFile(payload),
|
|
333
|
+
});
|
|
334
|
+
recoveryContext = buildStateRecoveryDiagnosticsContext(recoveryDiagnostics);
|
|
335
|
+
} catch {
|
|
336
|
+
recoveryContext = null;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
let skillState = null;
|
|
340
|
+
try {
|
|
341
|
+
skillState = prompt
|
|
342
|
+
? await recordSkillActivation({
|
|
343
|
+
cwd,
|
|
344
|
+
text: prompt,
|
|
345
|
+
sessionId: readSessionId(payload),
|
|
346
|
+
threadId: readThreadId(payload),
|
|
347
|
+
turnId: readTurnId(payload),
|
|
348
|
+
stateDir: options.stateDir,
|
|
349
|
+
})
|
|
350
|
+
: null;
|
|
351
|
+
} catch {
|
|
352
|
+
skillState = null;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
let effectiveSkillConfig: EffectiveSkillConfigInput | undefined;
|
|
356
|
+
try {
|
|
357
|
+
effectiveSkillConfig = skillState
|
|
358
|
+
? await resolveEffectiveSkillConfig(cwd, options.effectiveSkillConfig, options.configPaths, {
|
|
359
|
+
sessionId: readSessionId(payload),
|
|
360
|
+
threadId: readThreadId(payload),
|
|
361
|
+
stateDir: options.stateDir,
|
|
362
|
+
})
|
|
363
|
+
: undefined;
|
|
364
|
+
} catch {
|
|
365
|
+
effectiveSkillConfig = undefined;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
let activeUltragoalContext: string | null = null;
|
|
369
|
+
try {
|
|
370
|
+
activeUltragoalContext = skillState
|
|
371
|
+
? null
|
|
372
|
+
: await buildActiveUltragoalPromptContext({
|
|
373
|
+
cwd,
|
|
374
|
+
sessionId: readSessionId(payload),
|
|
375
|
+
threadId: readThreadId(payload),
|
|
376
|
+
stateDir: options.stateDir,
|
|
377
|
+
prompt,
|
|
378
|
+
sessionFile: readSessionFile(payload),
|
|
379
|
+
});
|
|
380
|
+
} catch {
|
|
381
|
+
activeUltragoalContext = null;
|
|
382
|
+
}
|
|
332
383
|
if (activeUltragoalContext?.startsWith("BLOCK_ULTRAGOAL_COMPLETION:")) {
|
|
333
384
|
return {
|
|
334
385
|
hookEventName,
|
|
@@ -342,25 +393,9 @@ export async function dispatchSkcNativeSkillHook(
|
|
|
342
393
|
},
|
|
343
394
|
};
|
|
344
395
|
}
|
|
345
|
-
// Frontend skills SKC routes to but does not vendor (license-restricted
|
|
346
|
-
// collections). Resolved against the user's own install roots. A lookup
|
|
347
|
-
// failure must not swallow the bundled UI-skill directive.
|
|
348
|
-
let externalUiContext: string | null = null;
|
|
349
|
-
try {
|
|
350
|
-
externalUiContext = await buildExternalUiSkillContext({
|
|
351
|
-
cwd,
|
|
352
|
-
home: options.home ?? os.homedir(),
|
|
353
|
-
text: prompt,
|
|
354
|
-
});
|
|
355
|
-
} catch {
|
|
356
|
-
externalUiContext = null;
|
|
357
|
-
}
|
|
358
396
|
const additionalContext = [
|
|
359
397
|
skillState ? buildSkillActivationAdditionalContext(skillState, effectiveSkillConfig) : activeUltragoalContext,
|
|
360
|
-
|
|
361
|
-
// activation: they have no mode state and must fire even when a
|
|
362
|
-
// workflow keyword already matched.
|
|
363
|
-
buildUiSkillActivationContext(prompt),
|
|
398
|
+
uiSkillContext,
|
|
364
399
|
externalUiContext,
|
|
365
400
|
recoveryContext,
|
|
366
401
|
classifyQuestionOnlyPrompt(prompt),
|