@hasna/skills 0.1.71 → 0.1.72

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,85 @@
1
+ /**
2
+ * Skills app-home resolution through the @hasna/paths resolver.
3
+ *
4
+ * Skills keeps its global config (`config.json`), auth (`auth.json`), the
5
+ * default SQLite database (`server.db`), the corpus cache (`skills/`), and the
6
+ * portable-skill tree (`installed/`, `custom/`) under one data root.
7
+ * Historically that root was `~/.hasna/skills`. This module resolves the root
8
+ * through `@hasna/paths` (XDG / macOS home layout) with a gated legacy
9
+ * adoption: the legacy `~/.hasna/skills` stays the effective data root until
10
+ * the store is physically migrated to the XDG data home (`server.db` or
11
+ * `config.json` present there) or the operator sets the data-kind override
12
+ * `HASNA_DATA_HOME`. An existing live store never becomes invisible on
13
+ * upgrade. The exact-app overrides win unconditionally, in this order:
14
+ * `HASNA_SKILLS_DIR` (the shipped override), then the wave-convention aliases
15
+ * `HASNA_SKILLS_HOME` and `SKILLS_HOME`.
16
+ *
17
+ * Nothing moves on disk in this phase — the package just resolves the new
18
+ * paths.
19
+ */
20
+ /** Env var that relocates the skills data directory (the shipped override). */
21
+ export declare const DATA_DIR_ENV = "HASNA_SKILLS_DIR";
22
+ /** Wave-convention exact-app home aliases, honoured after HASNA_SKILLS_DIR. */
23
+ export declare const HASNA_SKILLS_HOME_ENV = "HASNA_SKILLS_HOME";
24
+ export declare const SKILLS_HOME_ENV = "SKILLS_HOME";
25
+ /** Filename of the default SQLite database inside the skills data directory. */
26
+ export declare const DEFAULT_SQLITE_FILENAME = "server.db";
27
+ /** Filename of the global config file inside the skills data directory. */
28
+ export declare const GLOBAL_CONFIG_FILENAME = "config.json";
29
+ /**
30
+ * The effective user home, mirroring the pre-existing skills resolution
31
+ * (`HOME` || `USERPROFILE` || `os.homedir()`). Read at call time so a runtime
32
+ * `HOME` reassignment (e.g. a test temp home) is honoured — `os.homedir()`
33
+ * snapshots `HOME` at process start and, under Bun, ignores later changes.
34
+ */
35
+ export declare function effectiveHome(): string;
36
+ /** The legacy (pre-XDG) data root: `~/.hasna/skills`. */
37
+ export declare function legacyDataRoot(): string;
38
+ /**
39
+ * The @hasna/paths-resolved (XDG / macOS home layout) data root for skills:
40
+ * `~/.local/share/hasna/skills` on Linux, `~/Library/Application
41
+ * Support/Hasna/skills` on macOS. The home override mirrors the pre-existing
42
+ * `$HOME`-first resolution so the resolver follows the same home the legacy
43
+ * path does.
44
+ */
45
+ export declare function resolverDataRoot(home?: string): string;
46
+ /**
47
+ * Whether the resolver (XDG) data root should be adopted as the effective
48
+ * data root. The resolver root is adopted only when the operator has set
49
+ * `HASNA_DATA_HOME` (the data-kind override — a deliberate opt-in to the XDG
50
+ * layout) or the store has already been physically migrated there (`server.db`
51
+ * — the default SQLite store — or `config.json` exists). A machine that only
52
+ * redirects another kind (e.g. cache to tmpfs) must NOT have its data home
53
+ * moved, and a live store at the legacy home must never become invisible on
54
+ * upgrade.
55
+ */
56
+ export declare function adoptResolverDataRoot(resolved: string, env?: NodeJS.ProcessEnv): boolean;
57
+ /**
58
+ * The exact-app override root, when set: the shipped `HASNA_SKILLS_DIR` wins,
59
+ * then the wave-convention aliases `HASNA_SKILLS_HOME` and `SKILLS_HOME`.
60
+ * First non-blank override wins; a blank or whitespace-only primary must not
61
+ * shadow a valid secondary (nullish `??` does not fall through on `""`).
62
+ */
63
+ export declare function exactDataRoot(): string | undefined;
64
+ /** Whether an exact-app override root is set (used to skip legacy migration). */
65
+ export declare function hasExactOverride(env?: NodeJS.ProcessEnv): boolean;
66
+ /**
67
+ * Whether the operator named a data root at all — an exact-app override or the
68
+ * data-kind `HASNA_DATA_HOME`. Used to decide when the legacy `~/.skills` /
69
+ * `~/.skillsrc` migration must be skipped: copying a stray legacy tree into an
70
+ * operator-chosen directory would be a surprising write.
71
+ */
72
+ export declare function hasOperatorOverride(env?: NodeJS.ProcessEnv): boolean;
73
+ /**
74
+ * The effective data root: an exact-app override (`HASNA_SKILLS_DIR`, then
75
+ * `HASNA_SKILLS_HOME` / `SKILLS_HOME`) wins unconditionally; otherwise the
76
+ * resolver (XDG) data root once adopted; otherwise the legacy `~/.hasna/skills`
77
+ * default. Write-free: callers that need the directory to exist create it.
78
+ */
79
+ export declare function getDataRoot(): string;
80
+ /**
81
+ * The skills app data root for an explicit home root, mirroring getDataRoot()
82
+ * with the home injected. Used by the sync-home snapshot mapping to enumerate
83
+ * the skills corpus under a staged home mirror (`homesRoot`) or the real home.
84
+ */
85
+ export declare function skillsDataRootForHome(home: string): string;
@@ -8,6 +8,13 @@
8
8
  *
9
9
  * Values from the project config override global config.
10
10
  */
11
+ /**
12
+ * Environment variable that relocates the skills data directory.
13
+ *
14
+ * Owned by the @hasna/paths-based app-home resolver (app-home.ts), re-exported
15
+ * here so every existing reader keeps agreeing on the name.
16
+ */
17
+ export { DATA_DIR_ENV } from "./app-home.js";
11
18
  /**
12
19
  * There is no deployment "mode" key.
13
20
  *
@@ -35,14 +42,6 @@ export interface SkillsConfig {
35
42
  extensionsDir?: string;
36
43
  }
37
44
  export type ConfigScope = "global" | "project";
38
- /**
39
- * Environment variable that relocates the skills data directory.
40
- *
41
- * Exported so that every reader agrees on the name: previously the literal was
42
- * duplicated in portable-skills.ts and honoured there but *not* in getDataDir(),
43
- * which is what made the override only half work (see getDataDir below).
44
- */
45
- export declare const DATA_DIR_ENV = "HASNA_SKILLS_DIR";
46
45
  /**
47
46
  * Subfolder of the data directory holding the installed skill corpus.
48
47
  *
@@ -92,8 +91,8 @@ export declare function getDataDir(): string;
92
91
  *
93
92
  * getDataDir() itself writes: it mkdirs the app folder, merges legacy ~/.skills
94
93
  * content and copies the legacy config file. A dry run must resolve the SAME
95
- * directory a real run would use without performing any of that — mirror the path
96
- * logic only, reading $HASNA_SKILLS_DIR and $HOME exactly the way getDataDir does.
94
+ * directory a real run would use without performing any of that — the app-home
95
+ * resolver (getDataRoot) is already write-free, so this mirrors it directly.
97
96
  */
98
97
  export declare function getDataDirReadOnly(): string;
99
98
  /**
@@ -20,6 +20,8 @@ export interface HydrationCandidate {
20
20
  mtimeMs: number;
21
21
  /** The manifest's recorded sha256 for (agent, home-relative path), if any. */
22
22
  manifestHash: string | null;
23
+ /** True when the candidate's bytes hash to the manifest record (verified match). */
24
+ verified: boolean;
23
25
  }
24
26
  export interface HydrationWinnerFile {
25
27
  withinIdent: string;
@@ -11,7 +11,7 @@ export declare const STATION_SNAPSHOT_PRODUCER: {
11
11
  name: string;
12
12
  version: string;
13
13
  };
14
- export type StationSnapshotErrorCode = "INVALID_STATION" | "SYMLINKS_REFUSED" | "CONFLICT" | "DESTINATION_ESCAPE" | "MANIFEST_UNREADABLE";
14
+ export type StationSnapshotErrorCode = "INVALID_STATION" | "SYMLINKS_REFUSED" | "CONFLICT" | "DESTINATION_ESCAPE" | "MANIFEST_UNREADABLE" | "MANIFEST_HASH_MISMATCH";
15
15
  export declare class StationSnapshotError extends Error {
16
16
  readonly code: StationSnapshotErrorCode;
17
17
  /** Per-item lines for the CONFLICT class (printed before the summary). */