@hasna/hooks 0.5.0 → 0.6.0

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.
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Cloudflare resource provisioning for the hooks registry (`hooks cf deploy`).
3
+ *
4
+ * Provisions D1 database + R2 bucket through the Cloudflare API. Worker upload
5
+ * requires wrangler (workerd target); this module prints the exact wrangler
6
+ * commands instead of shipping a token-bearing upload path.
7
+ */
8
+ export interface ProvisionOptions {
9
+ token: string;
10
+ accountId: string;
11
+ databaseName: string;
12
+ bucketName: string;
13
+ dryRun: boolean;
14
+ fetchFn?: typeof fetch;
15
+ }
16
+ export interface ProvisionResult {
17
+ d1DatabaseId: string | null;
18
+ d1Created: boolean;
19
+ d1Exists: boolean;
20
+ r2BucketExists: boolean;
21
+ r2Created: boolean;
22
+ commands: string[];
23
+ }
24
+ export declare function provisionCloudflareResources(options: ProvisionOptions): Promise<ProvisionResult>;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Runtime configuration for @hasna/hooks.
3
+ *
4
+ * Presence of an API URL selects the remote registry; absence means the local
5
+ * store is authoritative. There is deliberately no mode concept.
6
+ */
7
+ export declare function getHooksDataDir(): string;
8
+ export declare function getCustomHooksDir(): string;
9
+ export declare function getLockPath(): string;
10
+ export declare function getConfigPath(): string;
11
+ export interface HooksConfig {
12
+ api_url?: string;
13
+ api_key_ref?: string;
14
+ }
15
+ export declare function readConfig(): HooksConfig;
16
+ export declare function writeConfig(config: HooksConfig): string;
17
+ export declare function resolveApiUrl(): string | undefined;
18
+ export declare function resolveApiKey(flagKey?: string): string | undefined;
@@ -8,4 +8,4 @@
8
8
  * Tracks completion via a `_meta` table row keyed "legacy_import_done".
9
9
  */
10
10
  import type { Database } from "bun:sqlite";
11
- export declare function runLegacyImport(db: Database): void;
11
+ export declare function runLegacyImport(db: Database, homeDir?: string): void;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Migration 004 — hooks tracking table.
3
+ * Records installed/pinned hooks with their trusted script hashes
4
+ * (mirrors the codewith trusted_hash model).
5
+ */
6
+ import type { Database } from "bun:sqlite";
7
+ export declare const CREATE_HOOKS_TABLE = "\n CREATE TABLE IF NOT EXISTS hooks (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n version TEXT NOT NULL,\n sha256 TEXT NOT NULL,\n source_type TEXT NOT NULL,\n source_ref TEXT,\n installed_at TEXT NOT NULL,\n enabled INTEGER NOT NULL DEFAULT 1,\n last_verified_at TEXT\n )\n";
8
+ export declare const CREATE_HOOKS_INDEXES: string[];
9
+ export declare function up(db: Database): void;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * PostgreSQL migrations for open-hooks remote storage and sync.
2
+ * PostgreSQL migrations for the open-hooks PostgreSQL storage backend and sync.
3
3
  *
4
4
  * Equivalent to the SQLite schema in schema.ts, migrations/, and index.ts,
5
5
  * translated for PostgreSQL.
@@ -2,7 +2,15 @@ import { PgAdapterAsync } from "./remote-storage.js";
2
2
  export declare const STORAGE_TABLES: readonly ["hook_events", "schema_migrations", "_meta", "feedback"];
3
3
  export declare const HOOKS_STORAGE_TABLES: readonly ["hook_events", "schema_migrations", "_meta", "feedback"];
4
4
  type StorageTable = (typeof STORAGE_TABLES)[number];
5
- export type StorageMode = "local" | "hybrid" | "remote";
5
+ /**
6
+ * The storage backend is a two-value data-backend switch, NOT a deployment mode.
7
+ *
8
+ * `local | hybrid | remote` (and the wider fleet's `self_hosted | cloud`) described *where*
9
+ * something ran, which is not a property of the data layer. They are retired: local collapses
10
+ * to `sqlite`, and every server-backed placement collapses to `postgresql`.
11
+ */
12
+ export declare const STORAGE_BACKENDS: readonly ["sqlite", "postgresql"];
13
+ export type StorageBackend = (typeof STORAGE_BACKENDS)[number];
6
14
  export interface StorageEnv {
7
15
  name: string;
8
16
  }
@@ -19,13 +27,19 @@ export interface SyncMeta {
19
27
  }
20
28
  export declare const HOOKS_STORAGE_ENV = "HASNA_HOOKS_DATABASE_URL";
21
29
  export declare const HOOKS_STORAGE_FALLBACK_ENV = "HOOKS_DATABASE_URL";
22
- export declare const HOOKS_STORAGE_MODE_ENV = "HASNA_HOOKS_STORAGE_MODE";
23
- export declare const HOOKS_STORAGE_MODE_FALLBACK_ENV = "HOOKS_STORAGE_MODE";
30
+ export declare const HOOKS_STORAGE_BACKEND_ENV = "HASNA_HOOKS_STORAGE_BACKEND";
31
+ export declare const HOOKS_STORAGE_BACKEND_FALLBACK_ENV = "HOOKS_STORAGE_BACKEND";
24
32
  export declare const STORAGE_DATABASE_ENV: readonly ["HASNA_HOOKS_DATABASE_URL", "HOOKS_DATABASE_URL"];
25
- export declare const STORAGE_MODE_ENV: readonly ["HASNA_HOOKS_STORAGE_MODE", "HOOKS_STORAGE_MODE"];
33
+ export declare const STORAGE_BACKEND_ENV: readonly ["HASNA_HOOKS_STORAGE_BACKEND", "HOOKS_STORAGE_BACKEND"];
34
+ /**
35
+ * Deployment-mode env vars that no longer exist. Reading one is an error rather than a no-op:
36
+ * an operator who set `HASNA_HOOKS_STORAGE_MODE=hybrid` believed they had configured something,
37
+ * and silently ignoring it is how a config change appears to work and does not.
38
+ */
39
+ export declare const RETIRED_STORAGE_MODE_ENV: readonly ["HASNA_HOOKS_STORAGE_MODE", "HOOKS_STORAGE_MODE"];
26
40
  export interface StorageStatus {
27
41
  configured: boolean;
28
- mode: StorageMode;
42
+ backend: StorageBackend;
29
43
  env: typeof STORAGE_DATABASE_ENV;
30
44
  activeEnv: string | null;
31
45
  service: "hooks";
@@ -35,7 +49,13 @@ export interface StorageStatus {
35
49
  export declare function getStorageDatabaseEnvName(): (typeof STORAGE_DATABASE_ENV)[number] | null;
36
50
  export declare function getStorageDatabaseEnv(): StorageEnv | null;
37
51
  export declare function getStorageDatabaseUrl(): string | null;
38
- export declare function getStorageMode(): StorageMode;
52
+ /**
53
+ * Which data backend hooks storage talks to. Explicit configuration wins; otherwise the
54
+ * presence of a database URL is the answer, exactly as before.
55
+ *
56
+ * Throws — never silently falls back — on an unknown value or a retired deployment-mode name.
57
+ */
58
+ export declare function getStorageBackend(): StorageBackend;
39
59
  export declare function getStoragePg(): Promise<PgAdapterAsync>;
40
60
  export declare function runStorageMigrations(remote: PgAdapterAsync): Promise<void>;
41
61
  export declare function storagePush(options?: {
package/dist/index.d.ts CHANGED
@@ -68,5 +68,21 @@ export interface RunHookResult {
68
68
  */
69
69
  export declare function runHook(name: string, input: HookInput, options?: RunHookOptions): Promise<RunHookResult>;
70
70
  export { createProfile, getProfile, listProfiles, updateProfile, deleteProfile, touchProfile, getProfilesDir, exportProfiles, importProfiles, type AgentProfile, type CreateProfileInput, } from "./lib/profiles.js";
71
- export { HOOKS_STORAGE_ENV, HOOKS_STORAGE_FALLBACK_ENV, HOOKS_STORAGE_MODE_ENV, HOOKS_STORAGE_MODE_FALLBACK_ENV, HOOKS_STORAGE_TABLES, STORAGE_DATABASE_ENV, STORAGE_MODE_ENV, STORAGE_TABLES, getStorageDatabaseEnv, getStorageDatabaseEnvName, getStorageDatabaseUrl, getStorageMode, getStoragePg, getStorageStatus, getSyncMetaAll, parseStorageTables, resolveTables, runStorageMigrations, storagePull, storagePush, storageSync, } from "./storage.js";
72
- export type { StorageEnv, StorageMode, StorageStatus, SyncMeta, SyncResult } from "./storage.js";
71
+ export { HOOKS_STORAGE_ENV, HOOKS_STORAGE_FALLBACK_ENV, HOOKS_STORAGE_BACKEND_ENV, HOOKS_STORAGE_BACKEND_FALLBACK_ENV, HOOKS_STORAGE_TABLES, RETIRED_STORAGE_MODE_ENV, STORAGE_BACKENDS, STORAGE_BACKEND_ENV, STORAGE_DATABASE_ENV, STORAGE_TABLES, getStorageBackend, getStorageDatabaseEnv, getStorageDatabaseEnvName, getStorageDatabaseUrl, getStoragePg, getStorageStatus, getSyncMetaAll, parseStorageTables, resolveTables, runStorageMigrations, storagePull, storagePush, storageSync, } from "./storage.js";
72
+ export type { StorageBackend, StorageEnv, StorageStatus, SyncMeta, SyncResult } from "./storage.js";
73
+ export { getHooksDataDir, getCustomHooksDir, getLockPath, getConfigPath, readConfig, writeConfig, resolveApiUrl, resolveApiKey, } from "./config.js";
74
+ 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";
76
+ export type { HookRecord, LockEntry, LockFile, TrustCheck } from "./lib/store.js";
77
+ export { parseManifest, readCustomManifest, listCustomHooks, writeCustomHook, resolveScript, } from "./lib/manifest.js";
78
+ export type { HookManifest, ParsedManifest } from "./lib/manifest.js";
79
+ export { resolveHook, resolveHookDir, resolveHookMeta, resolveScriptPath, } from "./lib/resolve.js";
80
+ export type { ResolvedHook, HookSource } from "./lib/resolve.js";
81
+ export { installCustomSource, isCustomSource, } from "./lib/custom-install.js";
82
+ 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";
85
+ export { handleServeRequest, startServeServer, DEFAULT_SERVE_PORT, } from "./serve.js";
86
+ export type { CatalogEntry, ArtifactPayload } from "./serve.js";
87
+ export { provisionCloudflareResources, } from "./cf/provision.js";
88
+ export type { ProvisionOptions, ProvisionResult } from "./cf/provision.js";