@hasna/instructions 0.5.3 → 0.5.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.
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Configs-app store-home resolution via the @hasna/paths resolver (XDG / macOS
3
+ * home layout). The "configs" app is the @hasna/instructions package surface
4
+ * that ships the `configs` / `configs-mcp` aliases and owns the configs store
5
+ * (SQLite store, backups, station-profile cache). Every shipped local-storage
6
+ * path derives from the effective store home.
7
+ *
8
+ * The legacy `~/.hasna/instructions` default (with the `HASNA_CONFIGS_HOME`
9
+ * exact-app override) stays the effective store home until the store has
10
+ * actually been migrated to the XDG config home or the operator sets the
11
+ * config-kind override `HASNA_CONFIG_HOME` — an existing local store never
12
+ * becomes invisible on upgrade.
13
+ */
14
+ export declare const HASNA_CONFIGS_HOME_ENV = "HASNA_CONFIGS_HOME";
15
+ /** Pre-XDG default store home: ~/.hasna/instructions (computed at call time; HOME may be redirected). */
16
+ export declare function legacyStoreHome(env?: NodeJS.ProcessEnv): string;
17
+ /**
18
+ * The @hasna/paths-resolved config home for the configs app (XDG layout):
19
+ * ~/.config/hasna/configs on Linux; ~/Library/Application
20
+ * Support/Hasna/configs on macOS.
21
+ */
22
+ export declare function resolverStoreHome(env?: NodeJS.ProcessEnv): string;
23
+ /**
24
+ * Whether the resolver (XDG) home should be adopted as the store home. The
25
+ * resolver home is adopted only when the operator has set `HASNA_CONFIG_HOME`
26
+ * (the config-kind override — a deliberate opt-in to the XDG layout) or the
27
+ * store has already been physically migrated there (`instructions.db` exists at
28
+ * the resolver home). A machine that only redirects another kind must NOT have
29
+ * its configs store moved, and a live store at the legacy home must never
30
+ * become invisible on upgrade.
31
+ */
32
+ export declare function adoptResolverStoreHome(resolved: string, env?: NodeJS.ProcessEnv): boolean;
33
+ /** The exact-app override root: `HASNA_CONFIGS_HOME`. Empty values are treated as unset. */
34
+ export declare function exactStoreHome(env?: NodeJS.ProcessEnv): string | undefined;
35
+ /**
36
+ * Effective configs store home: the exact-app override (`HASNA_CONFIGS_HOME`)
37
+ * wins unconditionally; otherwise the @hasna/paths config home once adopted
38
+ * (`HASNA_CONFIG_HOME` set or the store already migrated there); otherwise the
39
+ * legacy `~/.hasna/instructions` default, so an existing store never becomes
40
+ * invisible on upgrade.
41
+ */
42
+ export declare function getConfigsStoreHome(env?: NodeJS.ProcessEnv): string;
43
+ /** The store's SQLite database path under the effective store home. */
44
+ export declare function getConfigsStoreDbPath(env?: NodeJS.ProcessEnv): string;
45
+ /**
46
+ * The local database path surfaced by server status/health surfaces (e.g. the
47
+ * MCP server's `db_path` field). The exact `HASNA_INSTRUCTIONS_DB_PATH`
48
+ * override wins; otherwise the resolver-derived store db path (legacy
49
+ * `~/.hasna/instructions/instructions.db` until the XDG config home is
50
+ * adopted, matching `db/database.ts`). A server status must never hardcode the
51
+ * legacy literal — the store can live at the resolver home.
52
+ */
53
+ export declare function getReportedDbPath(env?: NodeJS.ProcessEnv): string;
54
+ //# sourceMappingURL=app-home.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-home.d.ts","sourceRoot":"","sources":["../../src/lib/app-home.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,sBAAsB,uBAAuB,CAAC;AAM3D,yGAAyG;AACzG,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAE5E;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAE9E;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,OAAO,CAIT;AAED,4FAA4F;AAC5F,wBAAgB,cAAc,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,GAAG,SAAS,CAGvF;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAKhF;AAED,uEAAuE;AACvE,wBAAgB,qBAAqB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAElF;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAI9E"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=app-home.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-home.test.d.ts","sourceRoot":"","sources":["../../src/lib/app-home.test.ts"],"names":[],"mappings":""}
@@ -1,17 +1,21 @@
1
1
  /**
2
2
  * Legacy environment variable that overrides the raw store root.
3
- * Kept for compatibility: the canonical default is `~/.hasna/instructions`,
3
+ * Kept for compatibility: the canonical default is the effective configs store
4
+ * home (legacy `~/.hasna/instructions` until the XDG config home is adopted),
4
5
  * and `HASNA_CONFIGS_HOME` remains a supported override.
5
6
  */
6
7
  export declare const RAW_STORE_ROOT_ENV = "HASNA_CONFIGS_HOME";
7
8
  /**
8
- * Canonical data root for the instructions app.
9
+ * Canonical data root for the instructions/configs app.
9
10
  *
10
- * Defaults to `~/.hasna/instructions` (was `~/.hasna/configs`, another app's
11
- * home). Every shipped local-storage path derives from this root: the SQLite
12
- * store (`db/database.ts`) and the CLI db-path / backup computations
13
- * (`cli/index.tsx`). `HASNA_CONFIGS_HOME` overrides the default and is
14
- * honored by every derived path.
11
+ * Every shipped local-storage path derives from this root: the SQLite store
12
+ * (`db/database.ts`) and the CLI db-path / backup computations
13
+ * (`cli/index.tsx`). The root is resolved through the @hasna/paths resolver
14
+ * (XDG / macOS home layout): the legacy `~/.hasna/instructions` default (with
15
+ * the `HASNA_CONFIGS_HOME` exact-app override) stays the effective root until
16
+ * the store has actually been migrated to the XDG config home or the operator
17
+ * sets the config-kind override `HASNA_CONFIG_HOME`. An existing local store
18
+ * never becomes invisible on upgrade.
15
19
  */
16
- export declare function getRawStoreRoot(): string;
20
+ export declare function getRawStoreRoot(env?: NodeJS.ProcessEnv): string;
17
21
  //# sourceMappingURL=raw-store-root.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"raw-store-root.d.ts","sourceRoot":"","sources":["../../src/lib/raw-store-root.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AAEvD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAIxC"}
1
+ {"version":3,"file":"raw-store-root.d.ts","sourceRoot":"","sources":["../../src/lib/raw-store-root.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AAEvD;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAE5E"}
@@ -1 +1 @@
1
- {"version":3,"file":"station-profile.d.ts","sourceRoot":"","sources":["../../src/lib/station-profile.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"station-profile.d.ts","sourceRoot":"","sources":["../../src/lib/station-profile.ts"],"names":[],"mappings":"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"}
package/dist/mcp/index.js CHANGED
@@ -97,19 +97,131 @@ var init_retired_storage_mode = __esm(() => {
97
97
  ];
98
98
  });
99
99
 
100
- // src/lib/raw-store-root.ts
100
+ // ../../node_modules/.bun/@hasna+paths@0.1.0/node_modules/@hasna/paths/dist/index.js
101
101
  import { homedir } from "os";
102
- import { join as join2, resolve } from "path";
103
- function getRawStoreRoot() {
104
- return resolve(process.env[RAW_STORE_ROOT_ENV] || join2(process.env["HOME"] || homedir(), ".hasna", "instructions"));
102
+ import { join as join2 } from "path";
103
+ function assertApp(app) {
104
+ if (typeof app !== "string" || app.length === 0) {
105
+ throw new TypeError("paths: app must be a non-empty string");
106
+ }
107
+ if (!APP_SLUG_RE.test(app)) {
108
+ throw new TypeError(`paths: invalid app slug "${app}" \u2014 expected lowercase kebab-case ([a-z0-9]+(-[a-z0-9]+)*)`);
109
+ }
110
+ }
111
+ function envOf(options) {
112
+ return options.env ?? process.env;
113
+ }
114
+ function envValue(options, kind) {
115
+ const value = envOf(options)[KIND_ENV[kind]];
116
+ return typeof value === "string" && value.length > 0 ? value : undefined;
117
+ }
118
+ function isMacOS(platform) {
119
+ return platform === "darwin";
120
+ }
121
+ function baseDir(kind, options) {
122
+ const override = envValue(options, kind);
123
+ if (override)
124
+ return override;
125
+ const home = options.home ?? homedir();
126
+ const platform = options.platform ?? process.platform;
127
+ if (isMacOS(platform)) {
128
+ switch (kind) {
129
+ case "config":
130
+ case "data":
131
+ return join2(home, "Library", "Application Support", "Hasna");
132
+ case "cache":
133
+ return join2(home, "Library", "Caches", "Hasna");
134
+ case "state":
135
+ return join2(home, "Library", "Logs", "Hasna");
136
+ }
137
+ }
138
+ switch (kind) {
139
+ case "config":
140
+ return join2(home, ".config", "hasna");
141
+ case "data":
142
+ return join2(home, ".local", "share", "hasna");
143
+ case "state":
144
+ return join2(home, ".local", "state", "hasna");
145
+ case "cache":
146
+ return join2(home, ".cache", "hasna");
147
+ }
148
+ }
149
+ function resolvePath(kind, options) {
150
+ assertApp(options.app);
151
+ const appSegment = options.internal === true ? join2("internal", options.app) : options.app;
152
+ return join2(baseDir(kind, options), appSegment);
153
+ }
154
+ function configDir(options) {
155
+ return resolvePath("config", options);
156
+ }
157
+ var KIND_ENV, APP_SLUG_RE;
158
+ var init_dist = __esm(() => {
159
+ KIND_ENV = {
160
+ config: "HASNA_CONFIG_HOME",
161
+ data: "HASNA_DATA_HOME",
162
+ state: "HASNA_STATE_HOME",
163
+ cache: "HASNA_CACHE_HOME"
164
+ };
165
+ APP_SLUG_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
166
+ });
167
+
168
+ // src/lib/app-home.ts
169
+ import { existsSync as existsSync2 } from "fs";
170
+ import { homedir as homedir2 } from "os";
171
+ import { join as join3, resolve } from "path";
172
+ function homeDir(env = process.env) {
173
+ return env["HOME"] || env["USERPROFILE"] || homedir2();
174
+ }
175
+ function legacyStoreHome(env = process.env) {
176
+ return resolve(join3(homeDir(env), ".hasna", "instructions"));
177
+ }
178
+ function resolverStoreHome(env = process.env) {
179
+ return configDir({ app: "configs", env, home: env.HOME || env.USERPROFILE || homedir2() });
180
+ }
181
+ function adoptResolverStoreHome(resolved, env = process.env) {
182
+ const override = env.HASNA_CONFIG_HOME;
183
+ if (typeof override === "string" && override.trim().length > 0)
184
+ return true;
185
+ return existsSync2(join3(resolved, "instructions.db"));
186
+ }
187
+ function exactStoreHome(env = process.env) {
188
+ const v = env[HASNA_CONFIGS_HOME_ENV];
189
+ return v && v.trim() ? v.trim() : undefined;
190
+ }
191
+ function getConfigsStoreHome(env = process.env) {
192
+ const exact = exactStoreHome(env);
193
+ if (exact)
194
+ return resolve(exact);
195
+ const resolved = resolverStoreHome(env);
196
+ return adoptResolverStoreHome(resolved, env) ? resolve(resolved) : legacyStoreHome(env);
197
+ }
198
+ function getConfigsStoreDbPath(env = process.env) {
199
+ return join3(getConfigsStoreHome(env), "instructions.db");
200
+ }
201
+ function getReportedDbPath(env = process.env) {
202
+ const override = env["HASNA_INSTRUCTIONS_DB_PATH"];
203
+ if (typeof override === "string" && override.length > 0)
204
+ return override;
205
+ return getConfigsStoreDbPath(env);
206
+ }
207
+ var HASNA_CONFIGS_HOME_ENV = "HASNA_CONFIGS_HOME";
208
+ var init_app_home = __esm(() => {
209
+ init_dist();
210
+ });
211
+
212
+ // src/lib/raw-store-root.ts
213
+ import { resolve as resolve2 } from "path";
214
+ function getRawStoreRoot(env = process.env) {
215
+ return resolve2(getConfigsStoreHome(env));
105
216
  }
106
- var RAW_STORE_ROOT_ENV = "HASNA_CONFIGS_HOME";
107
- var init_raw_store_root = () => {};
217
+ var init_raw_store_root = __esm(() => {
218
+ init_app_home();
219
+ });
108
220
 
109
221
  // src/db/database.ts
110
222
  import { Database } from "bun:sqlite";
111
- import { existsSync as existsSync2, mkdirSync, rmSync } from "fs";
112
- import { join as join3 } from "path";
223
+ import { existsSync as existsSync3, mkdirSync, rmSync } from "fs";
224
+ import { join as join4 } from "path";
113
225
  import { randomUUID } from "crypto";
114
226
  function getDbPath() {
115
227
  if (process.env["HASNA_INSTRUCTIONS_DB_PATH"]) {
@@ -117,7 +229,7 @@ function getDbPath() {
117
229
  }
118
230
  const dir = getRawStoreRoot();
119
231
  mkdirSync(dir, { recursive: true });
120
- return join3(dir, "instructions.db");
232
+ return join4(dir, "instructions.db");
121
233
  }
122
234
  function uuid() {
123
235
  return randomUUID();
@@ -158,7 +270,7 @@ function resetLocalDatabase() {
158
270
  if (dbPath === ":memory:")
159
271
  return;
160
272
  for (const p of [dbPath, `${dbPath}-wal`, `${dbPath}-shm`]) {
161
- if (existsSync2(p))
273
+ if (existsSync3(p))
162
274
  rmSync(p);
163
275
  }
164
276
  }
@@ -595,9 +707,9 @@ var init_template = __esm(() => {
595
707
  });
596
708
 
597
709
  // src/lib/machine.ts
598
- import { arch as currentArch, homedir as homedir2, hostname as currentHostname, type as currentOsType } from "os";
599
- import { existsSync as existsSync3 } from "fs";
600
- import { join as join4 } from "path";
710
+ import { arch as currentArch, homedir as homedir3, hostname as currentHostname, type as currentOsType } from "os";
711
+ import { existsSync as existsSync4 } from "fs";
712
+ import { join as join5 } from "path";
601
713
  function normalizeOsFamily(os) {
602
714
  const value = (os ?? "").trim().toLowerCase();
603
715
  if (value === "darwin" || value === "macos" || value === "mac" || value === "osx")
@@ -609,11 +721,11 @@ function normalizeOsFamily(os) {
609
721
  return value || "unknown";
610
722
  }
611
723
  function detectMachineContext(overrides = {}) {
612
- const homeDir = overrides.home_dir ?? process.env["CONFIGS_HOME"] ?? process.env["HOME"] ?? homedir2();
724
+ const homeDir2 = overrides.home_dir ?? process.env["CONFIGS_HOME"] ?? process.env["HOME"] ?? homedir3();
613
725
  const os = overrides.os ?? currentOsType();
614
726
  const osFamily = normalizeOsFamily(os);
615
- const bunBinDir = overrides.bun_bin_dir ?? join4(homeDir, ".bun", "bin");
616
- const defaultBunPath = osFamily === "macos" && existsSync3(BREW_BUN_PATH) ? BREW_BUN_PATH : join4(bunBinDir, "bun");
727
+ const bunBinDir = overrides.bun_bin_dir ?? join5(homeDir2, ".bun", "bin");
728
+ const defaultBunPath = osFamily === "macos" && existsSync4(BREW_BUN_PATH) ? BREW_BUN_PATH : join5(bunBinDir, "bun");
617
729
  return {
618
730
  id: "current-machine",
619
731
  hostname: overrides.hostname ?? currentHostname(),
@@ -622,11 +734,11 @@ function detectMachineContext(overrides = {}) {
622
734
  last_applied_at: null,
623
735
  created_at: "",
624
736
  os_family: osFamily,
625
- home_dir: homeDir,
626
- workspace_root: overrides.workspace_root ?? join4(homeDir, osFamily === "macos" ? "Workspace" : "workspace"),
737
+ home_dir: homeDir2,
738
+ workspace_root: overrides.workspace_root ?? join5(homeDir2, osFamily === "macos" ? "Workspace" : "workspace"),
627
739
  bun_bin_dir: bunBinDir,
628
740
  bun_path: overrides.bun_path ?? defaultBunPath,
629
- path_prefix: overrides.path_prefix ?? (osFamily === "macos" ? `${join4("/opt", "homebrew", "bin")}:${bunBinDir}` : bunBinDir)
741
+ path_prefix: overrides.path_prefix ?? (osFamily === "macos" ? `${join5("/opt", "homebrew", "bin")}:${bunBinDir}` : bunBinDir)
630
742
  };
631
743
  }
632
744
  function machineContextToVariables(machine) {
@@ -5139,7 +5251,7 @@ var init_session_render_contract = __esm(() => {
5139
5251
  });
5140
5252
 
5141
5253
  // src/lib/project-context.ts
5142
- import { basename, dirname as dirname2, isAbsolute, join as join5, parse, relative, resolve as resolve2 } from "path";
5254
+ import { basename, dirname as dirname2, isAbsolute, join as join6, parse, relative, resolve as resolve3 } from "path";
5143
5255
  function revisionKey(value) {
5144
5256
  const sequence = value.match(/^(?:rev-)?([0-9]+)$/);
5145
5257
  if (sequence)
@@ -5701,13 +5813,13 @@ var init_asset_plan = __esm(() => {
5701
5813
 
5702
5814
  // src/lib/cursor-authority.ts
5703
5815
  import { createHash } from "crypto";
5704
- import { homedir as homedir3 } from "os";
5705
- import { join as join6, resolve as resolve3 } from "path";
5816
+ import { homedir as homedir4 } from "os";
5817
+ import { join as join7, resolve as resolve4 } from "path";
5706
5818
  function sha256(content) {
5707
5819
  return createHash("sha256").update(content).digest("hex");
5708
5820
  }
5709
- function homeDir() {
5710
- return process.env["HOME"] || homedir3();
5821
+ function homeDir2() {
5822
+ return process.env["HOME"] || homedir4();
5711
5823
  }
5712
5824
  function markerPayload(content, markerLine, markerIndex) {
5713
5825
  const index = markerIndex ?? content.indexOf(markerLine);
@@ -5716,7 +5828,7 @@ function markerPayload(content, markerLine, markerIndex) {
5716
5828
  return content.slice(0, index) + content.slice(index + markerLine.length).replace(/^\n/, "");
5717
5829
  }
5718
5830
  function isCursorGlobalAuthorityPath(path) {
5719
- return resolve3(path) === resolve3(join6(homeDir(), CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH));
5831
+ return resolve4(path) === resolve4(join7(homeDir2(), CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH));
5720
5832
  }
5721
5833
  function stampCursorGlobalAuthorityMarker(content) {
5722
5834
  const existing = content.match(CURSOR_GLOBAL_AUTHORITY_MARKER_PATTERN);
@@ -6924,8 +7036,8 @@ var init_config_store = __esm(() => {
6924
7036
  });
6925
7037
 
6926
7038
  // src/lib/session-render-ownership.ts
6927
- import { existsSync as existsSync4, readFileSync as readFileSync2, statSync } from "fs";
6928
- import { dirname as dirname3, join as join7, parse as parse2, relative as relative2, sep } from "path";
7039
+ import { existsSync as existsSync5, readFileSync as readFileSync2, statSync } from "fs";
7040
+ import { dirname as dirname3, join as join8, parse as parse2, relative as relative2, sep } from "path";
6929
7041
  function toSegments(absolutePath2) {
6930
7042
  return absolutePath2.replaceAll("\\", "/").split("/").filter(Boolean);
6931
7043
  }
@@ -6944,7 +7056,7 @@ function pathIsSessionRenderManagedDir(absolutePath2) {
6944
7056
  function readManifestRelativePaths(manifestPath) {
6945
7057
  let stats;
6946
7058
  try {
6947
- if (!existsSync4(manifestPath))
7059
+ if (!existsSync5(manifestPath))
6948
7060
  return null;
6949
7061
  stats = statSync(manifestPath);
6950
7062
  } catch {
@@ -6973,7 +7085,7 @@ function sessionRenderManifestClaimsPath(absolutePath2) {
6973
7085
  const root = parse2(absolutePath2).root;
6974
7086
  let home = dirname3(absolutePath2);
6975
7087
  for (let depth = 0;depth < MANIFEST_ANCESTOR_LIMIT; depth += 1) {
6976
- const manifestPath = join7(home, ...SESSION_RENDER_MANIFEST_RELATIVE_PATH.split("/"));
7088
+ const manifestPath = join8(home, ...SESSION_RENDER_MANIFEST_RELATIVE_PATH.split("/"));
6977
7089
  const relativePaths = readManifestRelativePaths(manifestPath);
6978
7090
  if (relativePaths) {
6979
7091
  const claimed = relative2(home, absolutePath2).split(sep).join("/");
@@ -7008,17 +7120,17 @@ __export(exports_apply, {
7008
7120
  applyConfigs: () => applyConfigs,
7009
7121
  applyConfig: () => applyConfig
7010
7122
  });
7011
- import { existsSync as existsSync5, mkdirSync as mkdirSync2, readFileSync as readFileSync3, realpathSync, writeFileSync } from "fs";
7012
- import { basename as basename3, dirname as dirname4, join as join8, resolve as resolve4 } from "path";
7013
- import { homedir as homedir4 } from "os";
7123
+ import { existsSync as existsSync6, mkdirSync as mkdirSync2, readFileSync as readFileSync3, realpathSync, writeFileSync } from "fs";
7124
+ import { basename as basename3, dirname as dirname4, join as join9, resolve as resolve5 } from "path";
7125
+ import { homedir as homedir5 } from "os";
7014
7126
  function getConfigHome() {
7015
- return process.env["CONFIGS_HOME"] || process.env["HOME"] || homedir4();
7127
+ return process.env["CONFIGS_HOME"] || process.env["HOME"] || homedir5();
7016
7128
  }
7017
7129
  function expandPath(p) {
7018
7130
  if (p.startsWith("~/")) {
7019
- return resolve4(getConfigHome(), p.slice(2));
7131
+ return resolve5(getConfigHome(), p.slice(2));
7020
7132
  }
7021
- return resolve4(p);
7133
+ return resolve5(p);
7022
7134
  }
7023
7135
  function normalizeTargetPath(p) {
7024
7136
  const expanded = expandPath(p);
@@ -7028,9 +7140,9 @@ function normalizeTargetPath(p) {
7028
7140
  let current = expanded;
7029
7141
  const missingSegments = [];
7030
7142
  while (true) {
7031
- if (existsSync5(current)) {
7143
+ if (existsSync6(current)) {
7032
7144
  try {
7033
- return resolve4(realpathSync(current), ...missingSegments);
7145
+ return resolve5(realpathSync(current), ...missingSegments);
7034
7146
  } catch {
7035
7147
  return expanded;
7036
7148
  }
@@ -7059,11 +7171,11 @@ async function writeConfigResult(config, targetPath, content, opts, meta = {}) {
7059
7171
  }
7060
7172
  const path = expandPath(renderedTargetPath);
7061
7173
  const renderedForTarget = isCursorGlobalAuthorityPath(path) ? stampCursorGlobalAuthorityMarker(renderedContent) : renderedContent;
7062
- const previousContent = existsSync5(path) ? readFileSync3(path, "utf-8") : null;
7174
+ const previousContent = existsSync6(path) ? readFileSync3(path, "utf-8") : null;
7063
7175
  const changed = previousContent !== renderedForTarget;
7064
7176
  if (!opts.dryRun) {
7065
7177
  const dir = dirname4(path);
7066
- if (!existsSync5(dir)) {
7178
+ if (!existsSync6(dir)) {
7067
7179
  mkdirSync2(dir, { recursive: true });
7068
7180
  }
7069
7181
  if (previousContent !== null && changed) {
@@ -7097,7 +7209,7 @@ function wouldDestroyACredential(targetPath, renderedContent, format) {
7097
7209
  let current;
7098
7210
  try {
7099
7211
  const path = expandPath(targetPath);
7100
- if (!existsSync5(path))
7212
+ if (!existsSync6(path))
7101
7213
  return [];
7102
7214
  current = readFileSync3(path, "utf-8");
7103
7215
  } catch {
@@ -7423,7 +7535,7 @@ function sessionRendererOwnsCanonicalTarget(normalized, opts) {
7423
7535
  getConfigHome(),
7424
7536
  opts.vars?.["HOME_DIR"]
7425
7537
  ].filter((home) => typeof home === "string" && home.length > 0));
7426
- if ([...homes].some((home) => SESSION_RENDER_OWNED_CONFIG_TARGETS.some((relativePath) => normalized === normalizeTargetPath(join8(home, ...relativePath.split("/"))))))
7538
+ if ([...homes].some((home) => SESSION_RENDER_OWNED_CONFIG_TARGETS.some((relativePath) => normalized === normalizeTargetPath(join9(home, ...relativePath.split("/"))))))
7427
7539
  return true;
7428
7540
  return sessionRenderOwnsPath(normalized);
7429
7541
  }
@@ -7456,8 +7568,8 @@ __export(exports_sync, {
7456
7568
  KNOWN_CONFIGS: () => KNOWN_CONFIGS,
7457
7569
  CLAUDE_PROMPT_OUTPUTS: () => CLAUDE_PROMPT_OUTPUTS
7458
7570
  });
7459
- import { existsSync as existsSync6, readdirSync, readFileSync as readFileSync4 } from "fs";
7460
- import { basename as basename4, extname as extname2, join as join9 } from "path";
7571
+ import { existsSync as existsSync7, readdirSync, readFileSync as readFileSync4 } from "fs";
7572
+ import { basename as basename4, extname as extname2, join as join10 } from "path";
7461
7573
  function claudeRuleOutputs(fileName) {
7462
7574
  const stem = basename4(fileName, extname2(fileName));
7463
7575
  return [
@@ -7496,7 +7608,7 @@ function isGeneratedOutputTarget2(config, owners) {
7496
7608
  return !!ownerIds && !ownerIds.has(config.id);
7497
7609
  }
7498
7610
  function hasClaudePromptSource() {
7499
- return existsSync6(expandPath("~/.claude/CLAUDE.md"));
7611
+ return existsSync7(expandPath("~/.claude/CLAUDE.md"));
7500
7612
  }
7501
7613
  function hasClaudeRuleSourceForCursorTarget(targetPath) {
7502
7614
  const absoluteTargetPath = expandPath(targetPath);
@@ -7504,7 +7616,7 @@ function hasClaudeRuleSourceForCursorTarget(targetPath) {
7504
7616
  if (!absoluteTargetPath.startsWith(`${absolutePrefix}/`) || !absoluteTargetPath.endsWith(".mdc"))
7505
7617
  return false;
7506
7618
  const stem = basename4(absoluteTargetPath, ".mdc");
7507
- return existsSync6(expandPath(`~/.claude/rules/${stem}.md`)) || existsSync6(expandPath(`~/.claude/rules/${stem}.mdc`));
7619
+ return existsSync7(expandPath(`~/.claude/rules/${stem}.md`)) || existsSync7(expandPath(`~/.claude/rules/${stem}.mdc`));
7508
7620
  }
7509
7621
  function isKnownGeneratedTargetPath(targetPath) {
7510
7622
  const normalizedTargetPath = normalizeTargetPath(targetPath);
@@ -7521,8 +7633,8 @@ async function syncProject(opts) {
7521
7633
  const allConfigs = await store.listConfigs();
7522
7634
  const machine = detectMachineContext();
7523
7635
  for (const pf of PROJECT_CONFIG_FILES) {
7524
- const abs = join9(absDir, pf.file);
7525
- if (!existsSync6(abs))
7636
+ const abs = join10(absDir, pf.file);
7637
+ if (!existsSync7(abs))
7526
7638
  continue;
7527
7639
  try {
7528
7640
  const rawContent = readFileSync4(abs, "utf-8");
@@ -7554,19 +7666,19 @@ async function syncProject(opts) {
7554
7666
  }
7555
7667
  }
7556
7668
  for (const ruleDir of [
7557
- { dir: join9(absDir, ".claude", "rules"), agent: "claude", namePrefix: "rules" },
7558
- { dir: join9(absDir, ".agents", "rules"), agent: "antigravity", namePrefix: "antigravity-rules" },
7559
- { dir: join9(absDir, ".cursor", "rules"), agent: "cursor", namePrefix: "cursor-rules" },
7560
- { dir: join9(absDir, ".github", "instructions"), agent: "copilot", namePrefix: "copilot-instructions" },
7561
- { dir: join9(absDir, ".devin", "rules"), agent: "devin", namePrefix: "devin-rules" },
7562
- { dir: join9(absDir, ".windsurf", "rules"), agent: "windsurf-legacy", namePrefix: "windsurf-rules" },
7563
- { dir: join9(absDir, ".clinerules"), agent: "cline", namePrefix: "cline-rules" }
7669
+ { dir: join10(absDir, ".claude", "rules"), agent: "claude", namePrefix: "rules" },
7670
+ { dir: join10(absDir, ".agents", "rules"), agent: "antigravity", namePrefix: "antigravity-rules" },
7671
+ { dir: join10(absDir, ".cursor", "rules"), agent: "cursor", namePrefix: "cursor-rules" },
7672
+ { dir: join10(absDir, ".github", "instructions"), agent: "copilot", namePrefix: "copilot-instructions" },
7673
+ { dir: join10(absDir, ".devin", "rules"), agent: "devin", namePrefix: "devin-rules" },
7674
+ { dir: join10(absDir, ".windsurf", "rules"), agent: "windsurf-legacy", namePrefix: "windsurf-rules" },
7675
+ { dir: join10(absDir, ".clinerules"), agent: "cline", namePrefix: "cline-rules" }
7564
7676
  ]) {
7565
- if (!existsSync6(ruleDir.dir))
7677
+ if (!existsSync7(ruleDir.dir))
7566
7678
  continue;
7567
7679
  const mdFiles = readdirSync(ruleDir.dir).filter((f) => f.endsWith(".md") || f.endsWith(".mdc"));
7568
7680
  for (const f of mdFiles) {
7569
- const abs = join9(ruleDir.dir, f);
7681
+ const abs = join10(ruleDir.dir, f);
7570
7682
  const raw = readFileSync4(abs, "utf-8");
7571
7683
  const redacted = redactContent(raw, "markdown");
7572
7684
  const machineAware = templateizeMachineContent(redacted.content, machine);
@@ -7606,14 +7718,14 @@ async function syncKnown(opts = {}) {
7606
7718
  for (const known of targets) {
7607
7719
  if (known.rulesDir) {
7608
7720
  const absDir = expandPath(known.rulesDir);
7609
- if (!existsSync6(absDir)) {
7721
+ if (!existsSync7(absDir)) {
7610
7722
  result.skipped.push(known.rulesDir);
7611
7723
  continue;
7612
7724
  }
7613
7725
  const extensions = known.rulesExtensions ?? [".md", ".mdc"];
7614
7726
  const ruleFiles = readdirSync(absDir).filter((f) => extensions.some((ext) => f.endsWith(ext)));
7615
7727
  for (const f of ruleFiles) {
7616
- const abs2 = join9(absDir, f);
7728
+ const abs2 = join10(absDir, f);
7617
7729
  const targetPath = abs2.replace(home, "~");
7618
7730
  if (existingOutputOwners.has(normalizeTargetPath(targetPath)) || isKnownGeneratedTargetPath(targetPath)) {
7619
7731
  result.skipped.push(`${targetPath} (generated output)`);
@@ -7647,7 +7759,7 @@ async function syncKnown(opts = {}) {
7647
7759
  continue;
7648
7760
  }
7649
7761
  const abs = expandPath(known.path);
7650
- if (!existsSync6(abs)) {
7762
+ if (!existsSync7(abs)) {
7651
7763
  result.skipped.push(known.path);
7652
7764
  continue;
7653
7765
  }
@@ -7753,7 +7865,7 @@ function storedPlaceholderIsLiteralOnDisk(storedLine, diskLine) {
7753
7865
  }
7754
7866
  function buildDiff(expectedContent, targetPath, storedFormat, showSecrets) {
7755
7867
  const path = expandPath(targetPath);
7756
- if (!existsSync6(path))
7868
+ if (!existsSync7(path))
7757
7869
  return `(file not found on disk: ${path})`;
7758
7870
  const diskContent = readFileSync4(path, "utf-8");
7759
7871
  if (diskContent === expectedContent)
@@ -7983,20 +8095,20 @@ var init_sync = __esm(() => {
7983
8095
  });
7984
8096
 
7985
8097
  // src/lib/sync-dir.ts
7986
- import { existsSync as existsSync7, readdirSync as readdirSync2, readFileSync as readFileSync5, statSync as statSync2 } from "fs";
7987
- import { join as join10, relative as relative3 } from "path";
7988
- import { homedir as homedir5 } from "os";
8098
+ import { existsSync as existsSync8, readdirSync as readdirSync2, readFileSync as readFileSync5, statSync as statSync2 } from "fs";
8099
+ import { join as join11, relative as relative3 } from "path";
8100
+ import { homedir as homedir6 } from "os";
7989
8101
  function shouldSkip(p) {
7990
8102
  return SKIP.some((s) => p.includes(s));
7991
8103
  }
7992
8104
  async function syncFromDir(dir, opts = {}) {
7993
8105
  const store = opts.store ?? resolveConfigStore();
7994
8106
  const absDir = expandPath(dir);
7995
- if (!existsSync7(absDir))
8107
+ if (!existsSync8(absDir))
7996
8108
  return { added: 0, updated: 0, unchanged: 0, skipped: [`Not found: ${absDir}`] };
7997
- const files = opts.recursive !== false ? walkDir(absDir) : readdirSync2(absDir).map((f) => join10(absDir, f)).filter((f) => statSync2(f).isFile());
8109
+ const files = opts.recursive !== false ? walkDir(absDir) : readdirSync2(absDir).map((f) => join11(absDir, f)).filter((f) => statSync2(f).isFile());
7998
8110
  const result = { added: 0, updated: 0, unchanged: 0, skipped: [] };
7999
- const home = homedir5();
8111
+ const home = homedir6();
8000
8112
  const allConfigs = await store.listConfigs();
8001
8113
  for (const file of files) {
8002
8114
  if (shouldSkip(file)) {
@@ -8031,7 +8143,7 @@ async function syncFromDir(dir, opts = {}) {
8031
8143
  }
8032
8144
  async function syncToDir(dir, opts = {}) {
8033
8145
  const store = opts.store ?? resolveConfigStore();
8034
- const home = homedir5();
8146
+ const home = homedir6();
8035
8147
  const absDir = expandPath(dir);
8036
8148
  const normalized = dir.startsWith("~/") ? dir : absDir.replace(home, "~");
8037
8149
  const configs = (await store.listConfigs()).filter((c) => c.target_path && (c.target_path.startsWith(normalized) || c.target_path.startsWith(absDir)));
@@ -8055,7 +8167,7 @@ async function syncToDir(dir, opts = {}) {
8055
8167
  }
8056
8168
  function walkDir(dir, files = []) {
8057
8169
  for (const entry of readdirSync2(dir, { withFileTypes: true })) {
8058
- const full = join10(dir, entry.name);
8170
+ const full = join11(dir, entry.name);
8059
8171
  if (shouldSkip(full))
8060
8172
  continue;
8061
8173
  if (entry.isDirectory())
@@ -8078,7 +8190,7 @@ var init_sync_dir = __esm(() => {
8078
8190
  var require_package = __commonJS((exports, module) => {
8079
8191
  module.exports = {
8080
8192
  name: "@hasna/instructions",
8081
- version: "0.5.3",
8193
+ version: "0.5.5",
8082
8194
  description: "AI coding agent instruction & configuration manager \u2014 store, version, apply, and share all your AI coding configs. CLI + MCP + HTTP API (instructions-serve) + generated SDK + Dashboard.",
8083
8195
  type: "module",
8084
8196
  main: "dist/index.js",
@@ -8119,7 +8231,7 @@ var require_package = __commonJS((exports, module) => {
8119
8231
  "dev:serve": "bun run src/server/index.ts",
8120
8232
  seed: "bun run scripts/seed.ts",
8121
8233
  prepublishOnly: "bun run scripts/check-publish-hold.ts && bun run build",
8122
- postinstall: "mkdir -p $HOME/.hasna/instructions $HOME/.hasna/instructions/backups 2>/dev/null || true",
8234
+ postinstall: `node -e "const fs=require('node:fs'),path=require('node:path'),os=require('node:os');const home=process.env.HOME||process.env.USERPROFILE||os.homedir();const exact=process.env.HASNA_CONFIGS_HOME;const configHome=process.env.HASNA_CONFIG_HOME;const root=exact&&exact.trim()?path.resolve(exact.trim()):(configHome&&configHome.trim()?path.join(configHome.trim(),'configs'):path.join(home,'.hasna','instructions'));try{fs.mkdirSync(root,{recursive:true,mode:0o700});fs.mkdirSync(path.join(root,'backups'),{recursive:true,mode:0o700});}catch{}"`,
8123
8235
  prepack: "bun run build"
8124
8236
  },
8125
8237
  keywords: [
@@ -8154,12 +8266,13 @@ var require_package = __commonJS((exports, module) => {
8154
8266
  author: "Andrei Hasna <andrei@hasna.com>",
8155
8267
  license: "Apache-2.0",
8156
8268
  dependencies: {
8157
- "@hasna/contracts": "0.14.0",
8269
+ "@hasna/contracts": "0.14.1",
8158
8270
  "@hasna/events": "^0.1.16",
8271
+ "@hasna/paths": "0.1.0",
8159
8272
  "@modelcontextprotocol/sdk": "^1.12.1",
8160
8273
  chalk: "^5.4.1",
8161
8274
  commander: "^13.1.0",
8162
- hono: "^4.7.4",
8275
+ hono: "4.13.3",
8163
8276
  ink: "^5.2.0",
8164
8277
  pg: "^8.13.3",
8165
8278
  react: "^18.3.1",
@@ -8209,6 +8322,7 @@ function getPackageVersion() {
8209
8322
 
8210
8323
  // src/mcp/server.ts
8211
8324
  init_config_store();
8325
+ init_app_home();
8212
8326
  init_apply();
8213
8327
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
8214
8328
  import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
@@ -8472,7 +8586,7 @@ function buildServer() {
8472
8586
  drifted,
8473
8587
  drifted_configs: driftedSlugs.slice(0, 5),
8474
8588
  missing,
8475
- db_path: process.env["HASNA_INSTRUCTIONS_DB_PATH"] || "~/.hasna/instructions/instructions.db"
8589
+ db_path: getReportedDbPath()
8476
8590
  });
8477
8591
  }
8478
8592
  case "sync_known": {
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AA4EnE,wBAAgB,WAAW,IAAI,MAAM,CA+VpC"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AA6EnE,wBAAgB,WAAW,IAAI,MAAM,CA+VpC"}