@hasna/skills 0.8.5 → 0.8.6

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/README.md CHANGED
@@ -246,8 +246,11 @@ select complete skill instructions from that verified cache using explicit
246
246
  A session retains its selected versions; compaction restores loaded instructions,
247
247
  and subagents inherit the parent's selection. Instructions that exceed the
248
248
  context budget produce an explicit `skills load` command. A hook never executes
249
- a skill. Cached use is explicit and expires after 24 hours; authentication
250
- failures do not silently switch to a local catalog.
249
+ a skill. Cached use is explicit and expires after 24 hours. When cached context
250
+ expires or is missing, the hook makes one authenticated API attempt for the same
251
+ pinned session. It preserves exact versions and does not extend an expired
252
+ receipt's lifetime. Authentication, integrity and native discovery failures still
253
+ block; they do not silently switch to a local catalog.
251
254
 
252
255
  ## Profiles, station sync and rollback
253
256
 
package/bin/index.js CHANGED
@@ -36868,7 +36868,7 @@ var package_default;
36868
36868
  var init_package = __esm(() => {
36869
36869
  package_default = {
36870
36870
  name: "@hasna/skills",
36871
- version: "0.8.5",
36871
+ version: "0.8.6",
36872
36872
  description: "Skills library for AI coding agents",
36873
36873
  type: "module",
36874
36874
  bin: {
@@ -105416,6 +105416,34 @@ __export(exports_agent_integration, {
105416
105416
  });
105417
105417
  import { readFileSync as readFileSync37 } from "fs";
105418
105418
  import { isAbsolute as isAbsolute17 } from "path";
105419
+ async function contextForHook(input3, profileId, cached2, deadline) {
105420
+ const remaining = deadline - Date.now();
105421
+ if (remaining <= 0)
105422
+ throw new Error("Skills hook deadline exceeded");
105423
+ const args2 = [process.execPath, process.argv[1], "context", "--stdin", "--json", "--selection-profile", profileId];
105424
+ if (cached2)
105425
+ args2.push("--cached");
105426
+ const child = Bun.spawn(args2, { stdin: new Blob([JSON.stringify(input3)]), stdout: "pipe", stderr: "pipe", env: { ...process.env, NO_COLOR: "1" } });
105427
+ const timer = setTimeout(() => child.kill("SIGKILL"), Math.min(6500, remaining));
105428
+ let result2;
105429
+ let status;
105430
+ try {
105431
+ const [stdout, , exitCode] = await Promise.all([new Response(child.stdout).text(), new Response(child.stderr).text(), child.exited]);
105432
+ status = exitCode;
105433
+ result2 = JSON.parse(stdout);
105434
+ } finally {
105435
+ clearTimeout(timer);
105436
+ }
105437
+ if (status !== 0) {
105438
+ if (cached2 && RECOVERABLE_CONTEXT_CACHE_ERRORS.has(result2?.error?.code)) {
105439
+ return contextForHook(input3, profileId, false, deadline);
105440
+ }
105441
+ throw new Error("Skills context could not be resolved");
105442
+ }
105443
+ if (typeof result2?.context !== "string")
105444
+ throw new Error("Invalid Skills context response");
105445
+ return result2;
105446
+ }
105419
105447
  function agents(value) {
105420
105448
  if (value === "all")
105421
105449
  return [...INTEGRATION_AGENTS];
@@ -105444,6 +105472,7 @@ function registerAgentIntegration(parent) {
105444
105472
  }
105445
105473
  });
105446
105474
  hook.command("user-prompt").requiredOption("--agent <agent>", `Native payload/output adapter: ${INTEGRATION_AGENTS.join(", ")}`).option("--event <event>", "Native lifecycle event supplied by the installed adapter").option("--selection-profile <id>", "Selection profile to load").description("Read native lifecycle JSON on stdin and return selected context").action(async (options) => {
105475
+ const deadline = Date.now() + 12000;
105447
105476
  let event = options.agent === "hermes" && options.event === "pre_tool_call" ? "pre_tool_call" : "UserPromptSubmit";
105448
105477
  try {
105449
105478
  if (agents(options.agent).length !== 1)
@@ -105492,38 +105521,29 @@ function registerAgentIntegration(parent) {
105492
105521
  if (typeof input3.prompt === "string")
105493
105522
  input3.prompt = normalizeAgentHookPrompt(options.agent, nativeEvent, input3.prompt);
105494
105523
  if (event === "SessionStart") {
105524
+ const remaining = deadline - Date.now();
105525
+ if (remaining <= 0)
105526
+ throw new Error("Skills hook deadline exceeded");
105495
105527
  const refresh = Bun.spawn([process.execPath, process.argv[1], "sync", "--selection-profile", selectionProfile, "--json"], { stdin: "ignore", stdout: "pipe", stderr: "pipe", env: { ...process.env, NO_COLOR: "1" } });
105496
- const timer2 = setTimeout(() => refresh.kill("SIGKILL"), 6500);
105528
+ const timer = setTimeout(() => refresh.kill("SIGKILL"), Math.min(6500, remaining));
105497
105529
  try {
105498
105530
  const [, , status] = await Promise.all([new Response(refresh.stdout).text(), new Response(refresh.stderr).text(), refresh.exited]);
105499
105531
  if (status !== 0)
105500
105532
  throw new Error("Session profile refresh failed");
105501
105533
  } finally {
105502
- clearTimeout(timer2);
105534
+ clearTimeout(timer);
105503
105535
  }
105504
105536
  }
105505
- const args2 = [process.execPath, process.argv[1], "context", "--stdin", "--json", "--cached", "--selection-profile", selectionProfile];
105506
- const child = Bun.spawn(args2, { stdin: new Blob([JSON.stringify(input3)]), stdout: "pipe", stderr: "pipe", env: { ...process.env, NO_COLOR: "1" } });
105507
- const timer = setTimeout(() => child.kill("SIGKILL"), 6500);
105508
- try {
105509
- const [stdout, , status] = await Promise.all([new Response(child.stdout).text(), new Response(child.stderr).text(), child.exited]);
105510
- if (status !== 0)
105511
- throw new Error("Skills context could not be resolved");
105512
- const result2 = JSON.parse(stdout);
105513
- if (typeof result2.context !== "string")
105514
- throw new Error("Invalid Skills context response");
105515
- const output2 = hookContextOutput(event, result2);
105516
- if (options.agent === "hermes") {
105517
- await writeCliOutput(JSON.stringify({ context: output2.hookSpecificOutput?.additionalContext ?? "" }));
105518
- } else if (options.agent === "cursor") {
105519
- await writeCliOutput(JSON.stringify(event === "SessionStart" ? { additional_context: output2.hookSpecificOutput?.additionalContext ?? "" } : { continue: true }));
105520
- } else {
105521
- if (options.agent === "gemini" && output2.hookSpecificOutput)
105522
- output2.hookSpecificOutput.hookEventName = nativeEvent;
105523
- await writeCliOutput(JSON.stringify(output2));
105524
- }
105525
- } finally {
105526
- clearTimeout(timer);
105537
+ const result2 = await contextForHook(input3, selectionProfile, true, deadline);
105538
+ const output2 = hookContextOutput(event, result2);
105539
+ if (options.agent === "hermes") {
105540
+ await writeCliOutput(JSON.stringify({ context: output2.hookSpecificOutput?.additionalContext ?? "" }));
105541
+ } else if (options.agent === "cursor") {
105542
+ await writeCliOutput(JSON.stringify(event === "SessionStart" ? { additional_context: output2.hookSpecificOutput?.additionalContext ?? "" } : { continue: true }));
105543
+ } else {
105544
+ if (options.agent === "gemini" && output2.hookSpecificOutput)
105545
+ output2.hookSpecificOutput.hookEventName = nativeEvent;
105546
+ await writeCliOutput(JSON.stringify(output2));
105527
105547
  }
105528
105548
  } catch (error61) {
105529
105549
  const reason = error61 instanceof Error && error61.message.startsWith("NATIVE_SKILL_DRIFT:") ? error61.message : "Skills context is unavailable. Run skills sync --selection-profile <id> and skills context --stdin --json to diagnose the selected profile.";
@@ -105559,11 +105579,13 @@ function registerAgentIntegration(parent) {
105559
105579
  }
105560
105580
  });
105561
105581
  }
105582
+ var RECOVERABLE_CONTEXT_CACHE_ERRORS;
105562
105583
  var init_agent_integration2 = __esm(() => {
105563
105584
  init_agent_hermes();
105564
105585
  init_context();
105565
105586
  init_agent_adapters();
105566
105587
  init_agent_integration();
105588
+ RECOVERABLE_CONTEXT_CACHE_ERRORS = new Set(["CACHED_PROFILE_EXPIRED", "CACHED_PROFILE_MISSING", "CACHED_BUNDLE_MISSING"]);
105567
105589
  });
105568
105590
 
105569
105591
  // src/lib/profile-admin.ts
package/bin/mcp.js CHANGED
@@ -20019,7 +20019,7 @@ var package_default;
20019
20019
  var init_package = __esm(() => {
20020
20020
  package_default = {
20021
20021
  name: "@hasna/skills",
20022
- version: "0.8.5",
20022
+ version: "0.8.6",
20023
20023
  description: "Skills library for AI coding agents",
20024
20024
  type: "module",
20025
20025
  bin: {
package/bin/migrate.js CHANGED
@@ -7,7 +7,7 @@ import { join as join5 } from "path";
7
7
  // package.json
8
8
  var package_default = {
9
9
  name: "@hasna/skills",
10
- version: "0.8.5",
10
+ version: "0.8.6",
11
11
  description: "Skills library for AI coding agents",
12
12
  type: "module",
13
13
  bin: {
package/bin/server.js CHANGED
@@ -83749,7 +83749,7 @@ var require_protocols9 = __commonJS((exports) => {
83749
83749
  // package.json
83750
83750
  var package_default = {
83751
83751
  name: "@hasna/skills",
83752
- version: "0.8.5",
83752
+ version: "0.8.6",
83753
83753
  description: "Skills library for AI coding agents",
83754
83754
  type: "module",
83755
83755
  bin: {
package/bin/worker.js CHANGED
@@ -76168,7 +76168,7 @@ import { randomUUID as randomUUID6 } from "crypto";
76168
76168
  // package.json
76169
76169
  var package_default = {
76170
76170
  name: "@hasna/skills",
76171
- version: "0.8.5",
76171
+ version: "0.8.6",
76172
76172
  description: "Skills library for AI coding agents",
76173
76173
  type: "module",
76174
76174
  bin: {
package/dist/index.js CHANGED
@@ -37660,7 +37660,7 @@ import { dirname as dirname14, relative as relative7 } from "path";
37660
37660
  // package.json
37661
37661
  var package_default = {
37662
37662
  name: "@hasna/skills",
37663
- version: "0.8.5",
37663
+ version: "0.8.6",
37664
37664
  description: "Skills library for AI coding agents",
37665
37665
  type: "module",
37666
37666
  bin: {
package/dist/sdk/index.js CHANGED
@@ -96141,7 +96141,7 @@ async function resolveExecutionGrant(input) {
96141
96141
  // package.json
96142
96142
  var package_default = {
96143
96143
  name: "@hasna/skills",
96144
- version: "0.8.5",
96144
+ version: "0.8.6",
96145
96145
  description: "Skills library for AI coding agents",
96146
96146
  type: "module",
96147
96147
  bin: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/skills",
3
- "version": "0.8.5",
3
+ "version": "0.8.6",
4
4
  "description": "Skills library for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {