@sayknow-cli/coding-agent 0.5.14 → 0.5.16

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 CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.5.16] - 2026-09-16
6
+
7
+ ### Fixed
8
+
9
+ - 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.
10
+
11
+ ## [0.5.15] - 2026-09-16
12
+
13
+ ### Fixed
14
+
15
+ - Native `UserPromptSubmit` UI-skill routing no longer lets a failed install-root lookup swallow the bundled skill directive. Candidate `SKILL.md` probes are best-effort, and hook tests isolate `home` so a runner's `~/.agents/skills` cannot pollute CI.
16
+
5
17
  ## [0.5.14] - 2026-09-16
6
18
 
7
19
  ### Added
@@ -7,6 +7,7 @@ export interface SkcNativeHookDispatchResult {
7
7
  type HookPayload = Record<string, unknown>;
8
8
  interface SkcNativeHookDispatchOptions {
9
9
  cwd?: string;
10
+ home?: string;
10
11
  stateDir?: string;
11
12
  effectiveSkillConfig?: EffectiveSkillConfigInput;
12
13
  configPaths?: string[];
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.14",
4
+ "version": "0.5.16",
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.14",
58
- "@sayknow-cli/agent-core": "0.5.14",
59
- "@sayknow-cli/ai": "0.5.14",
60
- "@sayknow-cli/natives": "0.5.14",
61
- "@sayknow-cli/tui": "0.5.14",
62
- "@sayknow-cli/utils": "0.5.14",
57
+ "@sayknow-cli/stats": "0.5.16",
58
+ "@sayknow-cli/agent-core": "0.5.16",
59
+ "@sayknow-cli/ai": "0.5.16",
60
+ "@sayknow-cli/natives": "0.5.16",
61
+ "@sayknow-cli/tui": "0.5.16",
62
+ "@sayknow-cli/utils": "0.5.16",
63
63
  "@puppeteer/browsers": "^2.13.0",
64
64
  "@types/turndown": "5.0.6",
65
65
  "@xterm/headless": "^6.0.0",
@@ -28,6 +28,7 @@ type HookPayload = Record<string, unknown>;
28
28
 
29
29
  interface SkcNativeHookDispatchOptions {
30
30
  cwd?: string;
31
+ home?: string;
31
32
  stateDir?: string;
32
33
  effectiveSkillConfig?: EffectiveSkillConfigInput;
33
34
  configPaths?: string[];
@@ -287,6 +288,20 @@ function readSessionFile(payload: HookPayload): string | undefined {
287
288
  export async function dispatchSkcNativeSkillHook(
288
289
  payload: HookPayload,
289
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 = {},
290
305
  ): Promise<SkcNativeHookDispatchResult> {
291
306
  const hookEventName = readHookEventName(payload);
292
307
  const cwd = (options.cwd ?? safeString(payload.cwd).trim()) || process.cwd();
@@ -342,12 +357,18 @@ export async function dispatchSkcNativeSkillHook(
342
357
  };
343
358
  }
344
359
  // Frontend skills SKC routes to but does not vendor (license-restricted
345
- // collections). Resolved against the user's own install roots.
346
- const externalUiContext = await buildExternalUiSkillContext({
347
- cwd,
348
- home: os.homedir(),
349
- text: prompt,
350
- });
360
+ // collections). Resolved against the user's own install roots. A lookup
361
+ // failure must not swallow the bundled UI-skill directive.
362
+ let externalUiContext: string | null = null;
363
+ try {
364
+ externalUiContext = await buildExternalUiSkillContext({
365
+ cwd,
366
+ home: options.home ?? os.homedir(),
367
+ text: prompt,
368
+ });
369
+ } catch {
370
+ externalUiContext = null;
371
+ }
351
372
  const additionalContext = [
352
373
  skillState ? buildSkillActivationAdditionalContext(skillState, effectiveSkillConfig) : activeUltragoalContext,
353
374
  // Bundled frontend UI skills are advertised independently of workflow
@@ -264,7 +264,11 @@ function skillCandidatePaths(cwd: string, home: string, skill: string): string[]
264
264
 
265
265
  async function isSkillInstalled(cwd: string, home: string, skill: string): Promise<boolean> {
266
266
  for (const candidate of skillCandidatePaths(cwd, home, skill)) {
267
- if (await Bun.file(candidate).exists()) return true;
267
+ try {
268
+ if (await Bun.file(candidate).exists()) return true;
269
+ } catch {
270
+ // Permission or I/O on a candidate must not fail the prompt hook.
271
+ }
268
272
  }
269
273
  return false;
270
274
  }