@hasna/hooks 0.6.3 → 0.6.5

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/bin/serve.js CHANGED
@@ -4657,7 +4657,7 @@ var CREATE_HOOK_EVENTS_TABLE = `
4657
4657
  timestamp TEXT NOT NULL,
4658
4658
  session_id TEXT NOT NULL,
4659
4659
  hook_name TEXT NOT NULL,
4660
- event_type TEXT NOT NULL CHECK (event_type IN ('PreToolUse', 'PostToolUse', 'Stop', 'Notification', 'SessionStart', 'SessionEnd', 'UserPromptSubmit')),
4660
+ event_type TEXT NOT NULL CHECK (event_type IN ('PreToolUse', 'PostToolUse', 'Stop', 'Notification', 'SessionStart', 'SessionEnd', 'UserPromptSubmit', 'SubagentStart')),
4661
4661
  tool_name TEXT,
4662
4662
  tool_input TEXT,
4663
4663
  result TEXT CHECK (result IN ('continue', 'block', NULL)),
@@ -4759,12 +4759,39 @@ function up4(db) {
4759
4759
  }
4760
4760
  }
4761
4761
 
4762
+ // src/db/migrations/005_subagent_start_event.ts
4763
+ function up5(db) {
4764
+ const row = db.query("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = ?").get("hook_events");
4765
+ if (!row?.sql)
4766
+ return;
4767
+ if (row.sql.includes("SubagentStart"))
4768
+ return;
4769
+ db.exec("BEGIN");
4770
+ try {
4771
+ db.exec("ALTER TABLE hook_events RENAME TO hook_events_old");
4772
+ db.exec(CREATE_HOOK_EVENTS_TABLE);
4773
+ db.exec(`INSERT INTO hook_events
4774
+ (id, timestamp, session_id, hook_name, event_type, tool_name, tool_input, result, error, duration_ms, project_dir, metadata)
4775
+ SELECT id, timestamp, session_id, hook_name, event_type, tool_name, tool_input, result, error, duration_ms, project_dir, metadata
4776
+ FROM hook_events_old`);
4777
+ db.exec("DROP TABLE hook_events_old");
4778
+ for (const idx of CREATE_INDEXES) {
4779
+ db.exec(idx);
4780
+ }
4781
+ db.exec("COMMIT");
4782
+ } catch (err) {
4783
+ db.exec("ROLLBACK");
4784
+ throw err;
4785
+ }
4786
+ }
4787
+
4762
4788
  // src/db/migrations/index.ts
4763
4789
  var MIGRATIONS = [
4764
4790
  { version: "001_initial", up },
4765
4791
  { version: "002_session_events", up: up2 },
4766
4792
  { version: "003_user_prompt_submit_event", up: up3 },
4767
- { version: "004_hooks_table", up: up4 }
4793
+ { version: "004_hooks_table", up: up4 },
4794
+ { version: "005_subagent_start_event", up: up5 }
4768
4795
  ];
4769
4796
  function ensureMigrationsTable(db) {
4770
4797
  db.exec(`
@@ -4954,6 +4981,7 @@ function getDb() {
4954
4981
  const isNew = dbPath === ":memory:" || !existsSync3(dbPath);
4955
4982
  ensureDir(dbPath);
4956
4983
  instance = new Database(dbPath);
4984
+ instance.exec("PRAGMA busy_timeout=5000");
4957
4985
  instance.exec("PRAGMA journal_mode=WAL");
4958
4986
  instance.exec("PRAGMA foreign_keys=ON");
4959
4987
  runMigrations(instance);
@@ -5114,7 +5142,8 @@ function resolveHook(name) {
5114
5142
  events: custom2.manifest.events,
5115
5143
  description: custom2.manifest.description ?? "Custom hook",
5116
5144
  scriptPath: custom2.scriptPath,
5117
- meta: meta2
5145
+ meta: meta2,
5146
+ timeoutMs: custom2.manifest.timeout_ms ?? null
5118
5147
  };
5119
5148
  }
5120
5149
  const meta = getHook(shortManifestName(name));
@@ -5128,7 +5157,8 @@ function resolveHook(name) {
5128
5157
  events: meta.events && meta.events.length > 0 ? meta.events : [meta.event],
5129
5158
  description: meta.description,
5130
5159
  scriptPath,
5131
- meta
5160
+ meta,
5161
+ timeoutMs: null
5132
5162
  };
5133
5163
  }
5134
5164
 
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Migration 005 — SubagentStart event support.
3
+ *
4
+ * The event_type CHECK constraint previously accepted seven events; Codewith
5
+ * exposes SubagentStart (installer EVENT_MAP) and runs can legitimately carry
6
+ * it. SQLite cannot ALTER a CHECK, so the table is rebuilt and rows copied,
7
+ * exactly as migration 002 did for SessionStart/SessionEnd.
8
+ */
9
+ import type { Database } from "bun:sqlite";
10
+ export declare function up(db: Database): void;
@@ -3,14 +3,14 @@
3
3
  * Owned by this package (no shared runtime dependency).
4
4
  */
5
5
  import type { Database } from "bun:sqlite";
6
- export declare const CREATE_HOOK_EVENTS_TABLE = "\n CREATE TABLE IF NOT EXISTS hook_events (\n id TEXT PRIMARY KEY,\n timestamp TEXT NOT NULL,\n session_id TEXT NOT NULL,\n hook_name TEXT NOT NULL,\n event_type TEXT NOT NULL CHECK (event_type IN ('PreToolUse', 'PostToolUse', 'Stop', 'Notification', 'SessionStart', 'SessionEnd', 'UserPromptSubmit')),\n tool_name TEXT,\n tool_input TEXT,\n result TEXT CHECK (result IN ('continue', 'block', NULL)),\n error TEXT,\n duration_ms INTEGER,\n project_dir TEXT,\n metadata TEXT\n )\n";
6
+ export declare const CREATE_HOOK_EVENTS_TABLE = "\n CREATE TABLE IF NOT EXISTS hook_events (\n id TEXT PRIMARY KEY,\n timestamp TEXT NOT NULL,\n session_id TEXT NOT NULL,\n hook_name TEXT NOT NULL,\n event_type TEXT NOT NULL CHECK (event_type IN ('PreToolUse', 'PostToolUse', 'Stop', 'Notification', 'SessionStart', 'SessionEnd', 'UserPromptSubmit', 'SubagentStart')),\n tool_name TEXT,\n tool_input TEXT,\n result TEXT CHECK (result IN ('continue', 'block', NULL)),\n error TEXT,\n duration_ms INTEGER,\n project_dir TEXT,\n metadata TEXT\n )\n";
7
7
  export declare const CREATE_INDEXES: string[];
8
8
  export interface HookEventRow {
9
9
  id: string;
10
10
  timestamp: string;
11
11
  session_id: string;
12
12
  hook_name: string;
13
- event_type: "PreToolUse" | "PostToolUse" | "Stop" | "Notification" | "SessionStart" | "SessionEnd" | "UserPromptSubmit";
13
+ event_type: "PreToolUse" | "PostToolUse" | "Stop" | "Notification" | "SessionStart" | "SessionEnd" | "UserPromptSubmit" | "SubagentStart";
14
14
  tool_name: string | null;
15
15
  tool_input: string | null;
16
16
  result: "continue" | "block" | null;
package/dist/index.d.ts CHANGED
@@ -9,7 +9,7 @@
9
9
  */
10
10
  export { HOOKS, HOOK_EVENTS, CATEGORIES, getHook, getHookEvents, getHooksByCategory, searchHooks, type HookMeta, type HookEvent, type Category, } from "./lib/registry.js";
11
11
  import type { HookEvent as HookEventType } from "./lib/registry.js";
12
- export { installHook, installHooks, getInstalledHooks, getRegisteredHooks, getRegisteredHooksForTarget, removeHook, hookExists, buildCodewithTomlFragment, getHookPath, getSettingsPath, isEventSupported, type InstallResult, type InstallOptions, type Scope, type ConcreteTarget, type Target, type CodewithInstallMode, } from "./lib/installer.js";
12
+ export { installHook, installHooks, getInstalledHooks, getRegisteredHooks, getRegisteredHooksForTarget, removeHook, uninstallHook, hookExists, buildCodewithTomlFragment, getHookPath, getSettingsPath, isEventSupported, type InstallResult, type InstallOptions, type Scope, type ConcreteTarget, type Target, type CodewithInstallMode, type UninstallResult, } from "./lib/installer.js";
13
13
  export interface HookAgentInfo {
14
14
  agent_id: string;
15
15
  agent_type: "claude" | "gemini" | "codewith" | "custom";
@@ -53,7 +53,11 @@ export declare function removeProjectHook(name: string): boolean;
53
53
  export interface RunHookOptions {
54
54
  /** Agent profile ID to inject into hook input */
55
55
  profile?: string;
56
- /** Timeout in milliseconds (default: 10000) */
56
+ /**
57
+ * Timeout in milliseconds. Wins over the hook manifest's timeout_ms when
58
+ * set to a positive value; a non-positive value is ignored (the manifest
59
+ * timeout or no timeout applies).
60
+ */
57
61
  timeout?: number;
58
62
  }
59
63
  export interface RunHookResult {
@@ -72,7 +76,7 @@ export { HOOKS_STORAGE_ENV, HOOKS_STORAGE_FALLBACK_ENV, HOOKS_STORAGE_BACKEND_EN
72
76
  export type { StorageBackend, StorageEnv, StorageStatus, SyncMeta, SyncResult } from "./storage.js";
73
77
  export { getHooksDataDir, getCustomHooksDir, getLockPath, getConfigPath, readConfig, writeConfig, resolveApiUrl, resolveApiKey, } from "./config.js";
74
78
  export type { HooksConfig } from "./config.js";
75
- export { getHookRecord, listHookRecords, upsertHookRecord, removeHookRecord, readLock, writeLock, setPinnedHook, getPinnedHook, removePinnedHook, verifyScriptHash, checkScriptHash, retrustHook, sha256Of, sha256File, } from "./lib/store.js";
79
+ export { getHookRecord, listHookRecords, upsertHookRecord, removeHookRecord, readLock, writeLock, setPinnedHook, getPinnedHook, removePinnedHook, pinInstalledHook, removeHookFromStore, verifyScriptHash, checkScriptHash, retrustHook, sha256Of, sha256File, } from "./lib/store.js";
76
80
  export type { HookRecord, LockEntry, LockFile, TrustCheck } from "./lib/store.js";
77
81
  export { parseManifest, readCustomManifest, listCustomHooks, writeCustomHook, resolveScript, } from "./lib/manifest.js";
78
82
  export type { HookManifest, ParsedManifest } from "./lib/manifest.js";
@@ -80,8 +84,8 @@ export { resolveHook, resolveHookDir, resolveHookMeta, resolveScriptPath, } from
80
84
  export type { ResolvedHook, HookSource } from "./lib/resolve.js";
81
85
  export { installCustomSource, isCustomSource, } from "./lib/custom-install.js";
82
86
  export type { CustomInstallResult, CustomSourceKind } from "./lib/custom-install.js";
83
- export { planSync, syncHooks, } from "./lib/sync.js";
84
- export type { SyncDiff, SyncPlan, ArtifactResponse } from "./lib/sync.js";
87
+ export { planSync, syncHooks, fetchPinnedHook, } from "./lib/sync.js";
88
+ export type { SyncDiff, SyncPlan, ArtifactResponse, PinnedHookInstall } from "./lib/sync.js";
85
89
  export { handleServeRequest, startServeServer, DEFAULT_SERVE_PORT, } from "./serve.js";
86
90
  export type { CatalogEntry, ArtifactPayload } from "./serve.js";
87
91
  export { provisionCloudflareResources, } from "./cf/provision.js";