@hasna/instructions 0.5.3 → 0.5.4

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,45 @@
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
+ //# 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"}
@@ -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,122 @@ 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
+ var HASNA_CONFIGS_HOME_ENV = "HASNA_CONFIGS_HOME";
199
+ var init_app_home = __esm(() => {
200
+ init_dist();
201
+ });
202
+
203
+ // src/lib/raw-store-root.ts
204
+ import { resolve as resolve2 } from "path";
205
+ function getRawStoreRoot(env = process.env) {
206
+ return resolve2(getConfigsStoreHome(env));
105
207
  }
106
- var RAW_STORE_ROOT_ENV = "HASNA_CONFIGS_HOME";
107
- var init_raw_store_root = () => {};
208
+ var init_raw_store_root = __esm(() => {
209
+ init_app_home();
210
+ });
108
211
 
109
212
  // src/db/database.ts
110
213
  import { Database } from "bun:sqlite";
111
- import { existsSync as existsSync2, mkdirSync, rmSync } from "fs";
112
- import { join as join3 } from "path";
214
+ import { existsSync as existsSync3, mkdirSync, rmSync } from "fs";
215
+ import { join as join4 } from "path";
113
216
  import { randomUUID } from "crypto";
114
217
  function getDbPath() {
115
218
  if (process.env["HASNA_INSTRUCTIONS_DB_PATH"]) {
@@ -117,7 +220,7 @@ function getDbPath() {
117
220
  }
118
221
  const dir = getRawStoreRoot();
119
222
  mkdirSync(dir, { recursive: true });
120
- return join3(dir, "instructions.db");
223
+ return join4(dir, "instructions.db");
121
224
  }
122
225
  function uuid() {
123
226
  return randomUUID();
@@ -158,7 +261,7 @@ function resetLocalDatabase() {
158
261
  if (dbPath === ":memory:")
159
262
  return;
160
263
  for (const p of [dbPath, `${dbPath}-wal`, `${dbPath}-shm`]) {
161
- if (existsSync2(p))
264
+ if (existsSync3(p))
162
265
  rmSync(p);
163
266
  }
164
267
  }
@@ -595,9 +698,9 @@ var init_template = __esm(() => {
595
698
  });
596
699
 
597
700
  // 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";
701
+ import { arch as currentArch, homedir as homedir3, hostname as currentHostname, type as currentOsType } from "os";
702
+ import { existsSync as existsSync4 } from "fs";
703
+ import { join as join5 } from "path";
601
704
  function normalizeOsFamily(os) {
602
705
  const value = (os ?? "").trim().toLowerCase();
603
706
  if (value === "darwin" || value === "macos" || value === "mac" || value === "osx")
@@ -609,11 +712,11 @@ function normalizeOsFamily(os) {
609
712
  return value || "unknown";
610
713
  }
611
714
  function detectMachineContext(overrides = {}) {
612
- const homeDir = overrides.home_dir ?? process.env["CONFIGS_HOME"] ?? process.env["HOME"] ?? homedir2();
715
+ const homeDir2 = overrides.home_dir ?? process.env["CONFIGS_HOME"] ?? process.env["HOME"] ?? homedir3();
613
716
  const os = overrides.os ?? currentOsType();
614
717
  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");
718
+ const bunBinDir = overrides.bun_bin_dir ?? join5(homeDir2, ".bun", "bin");
719
+ const defaultBunPath = osFamily === "macos" && existsSync4(BREW_BUN_PATH) ? BREW_BUN_PATH : join5(bunBinDir, "bun");
617
720
  return {
618
721
  id: "current-machine",
619
722
  hostname: overrides.hostname ?? currentHostname(),
@@ -622,11 +725,11 @@ function detectMachineContext(overrides = {}) {
622
725
  last_applied_at: null,
623
726
  created_at: "",
624
727
  os_family: osFamily,
625
- home_dir: homeDir,
626
- workspace_root: overrides.workspace_root ?? join4(homeDir, osFamily === "macos" ? "Workspace" : "workspace"),
728
+ home_dir: homeDir2,
729
+ workspace_root: overrides.workspace_root ?? join5(homeDir2, osFamily === "macos" ? "Workspace" : "workspace"),
627
730
  bun_bin_dir: bunBinDir,
628
731
  bun_path: overrides.bun_path ?? defaultBunPath,
629
- path_prefix: overrides.path_prefix ?? (osFamily === "macos" ? `${join4("/opt", "homebrew", "bin")}:${bunBinDir}` : bunBinDir)
732
+ path_prefix: overrides.path_prefix ?? (osFamily === "macos" ? `${join5("/opt", "homebrew", "bin")}:${bunBinDir}` : bunBinDir)
630
733
  };
631
734
  }
632
735
  function machineContextToVariables(machine) {
@@ -5139,7 +5242,7 @@ var init_session_render_contract = __esm(() => {
5139
5242
  });
5140
5243
 
5141
5244
  // src/lib/project-context.ts
5142
- import { basename, dirname as dirname2, isAbsolute, join as join5, parse, relative, resolve as resolve2 } from "path";
5245
+ import { basename, dirname as dirname2, isAbsolute, join as join6, parse, relative, resolve as resolve3 } from "path";
5143
5246
  function revisionKey(value) {
5144
5247
  const sequence = value.match(/^(?:rev-)?([0-9]+)$/);
5145
5248
  if (sequence)
@@ -5701,13 +5804,13 @@ var init_asset_plan = __esm(() => {
5701
5804
 
5702
5805
  // src/lib/cursor-authority.ts
5703
5806
  import { createHash } from "crypto";
5704
- import { homedir as homedir3 } from "os";
5705
- import { join as join6, resolve as resolve3 } from "path";
5807
+ import { homedir as homedir4 } from "os";
5808
+ import { join as join7, resolve as resolve4 } from "path";
5706
5809
  function sha256(content) {
5707
5810
  return createHash("sha256").update(content).digest("hex");
5708
5811
  }
5709
- function homeDir() {
5710
- return process.env["HOME"] || homedir3();
5812
+ function homeDir2() {
5813
+ return process.env["HOME"] || homedir4();
5711
5814
  }
5712
5815
  function markerPayload(content, markerLine, markerIndex) {
5713
5816
  const index = markerIndex ?? content.indexOf(markerLine);
@@ -5716,7 +5819,7 @@ function markerPayload(content, markerLine, markerIndex) {
5716
5819
  return content.slice(0, index) + content.slice(index + markerLine.length).replace(/^\n/, "");
5717
5820
  }
5718
5821
  function isCursorGlobalAuthorityPath(path) {
5719
- return resolve3(path) === resolve3(join6(homeDir(), CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH));
5822
+ return resolve4(path) === resolve4(join7(homeDir2(), CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH));
5720
5823
  }
5721
5824
  function stampCursorGlobalAuthorityMarker(content) {
5722
5825
  const existing = content.match(CURSOR_GLOBAL_AUTHORITY_MARKER_PATTERN);
@@ -6924,8 +7027,8 @@ var init_config_store = __esm(() => {
6924
7027
  });
6925
7028
 
6926
7029
  // 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";
7030
+ import { existsSync as existsSync5, readFileSync as readFileSync2, statSync } from "fs";
7031
+ import { dirname as dirname3, join as join8, parse as parse2, relative as relative2, sep } from "path";
6929
7032
  function toSegments(absolutePath2) {
6930
7033
  return absolutePath2.replaceAll("\\", "/").split("/").filter(Boolean);
6931
7034
  }
@@ -6944,7 +7047,7 @@ function pathIsSessionRenderManagedDir(absolutePath2) {
6944
7047
  function readManifestRelativePaths(manifestPath) {
6945
7048
  let stats;
6946
7049
  try {
6947
- if (!existsSync4(manifestPath))
7050
+ if (!existsSync5(manifestPath))
6948
7051
  return null;
6949
7052
  stats = statSync(manifestPath);
6950
7053
  } catch {
@@ -6973,7 +7076,7 @@ function sessionRenderManifestClaimsPath(absolutePath2) {
6973
7076
  const root = parse2(absolutePath2).root;
6974
7077
  let home = dirname3(absolutePath2);
6975
7078
  for (let depth = 0;depth < MANIFEST_ANCESTOR_LIMIT; depth += 1) {
6976
- const manifestPath = join7(home, ...SESSION_RENDER_MANIFEST_RELATIVE_PATH.split("/"));
7079
+ const manifestPath = join8(home, ...SESSION_RENDER_MANIFEST_RELATIVE_PATH.split("/"));
6977
7080
  const relativePaths = readManifestRelativePaths(manifestPath);
6978
7081
  if (relativePaths) {
6979
7082
  const claimed = relative2(home, absolutePath2).split(sep).join("/");
@@ -7008,17 +7111,17 @@ __export(exports_apply, {
7008
7111
  applyConfigs: () => applyConfigs,
7009
7112
  applyConfig: () => applyConfig
7010
7113
  });
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";
7114
+ import { existsSync as existsSync6, mkdirSync as mkdirSync2, readFileSync as readFileSync3, realpathSync, writeFileSync } from "fs";
7115
+ import { basename as basename3, dirname as dirname4, join as join9, resolve as resolve5 } from "path";
7116
+ import { homedir as homedir5 } from "os";
7014
7117
  function getConfigHome() {
7015
- return process.env["CONFIGS_HOME"] || process.env["HOME"] || homedir4();
7118
+ return process.env["CONFIGS_HOME"] || process.env["HOME"] || homedir5();
7016
7119
  }
7017
7120
  function expandPath(p) {
7018
7121
  if (p.startsWith("~/")) {
7019
- return resolve4(getConfigHome(), p.slice(2));
7122
+ return resolve5(getConfigHome(), p.slice(2));
7020
7123
  }
7021
- return resolve4(p);
7124
+ return resolve5(p);
7022
7125
  }
7023
7126
  function normalizeTargetPath(p) {
7024
7127
  const expanded = expandPath(p);
@@ -7028,9 +7131,9 @@ function normalizeTargetPath(p) {
7028
7131
  let current = expanded;
7029
7132
  const missingSegments = [];
7030
7133
  while (true) {
7031
- if (existsSync5(current)) {
7134
+ if (existsSync6(current)) {
7032
7135
  try {
7033
- return resolve4(realpathSync(current), ...missingSegments);
7136
+ return resolve5(realpathSync(current), ...missingSegments);
7034
7137
  } catch {
7035
7138
  return expanded;
7036
7139
  }
@@ -7059,11 +7162,11 @@ async function writeConfigResult(config, targetPath, content, opts, meta = {}) {
7059
7162
  }
7060
7163
  const path = expandPath(renderedTargetPath);
7061
7164
  const renderedForTarget = isCursorGlobalAuthorityPath(path) ? stampCursorGlobalAuthorityMarker(renderedContent) : renderedContent;
7062
- const previousContent = existsSync5(path) ? readFileSync3(path, "utf-8") : null;
7165
+ const previousContent = existsSync6(path) ? readFileSync3(path, "utf-8") : null;
7063
7166
  const changed = previousContent !== renderedForTarget;
7064
7167
  if (!opts.dryRun) {
7065
7168
  const dir = dirname4(path);
7066
- if (!existsSync5(dir)) {
7169
+ if (!existsSync6(dir)) {
7067
7170
  mkdirSync2(dir, { recursive: true });
7068
7171
  }
7069
7172
  if (previousContent !== null && changed) {
@@ -7097,7 +7200,7 @@ function wouldDestroyACredential(targetPath, renderedContent, format) {
7097
7200
  let current;
7098
7201
  try {
7099
7202
  const path = expandPath(targetPath);
7100
- if (!existsSync5(path))
7203
+ if (!existsSync6(path))
7101
7204
  return [];
7102
7205
  current = readFileSync3(path, "utf-8");
7103
7206
  } catch {
@@ -7423,7 +7526,7 @@ function sessionRendererOwnsCanonicalTarget(normalized, opts) {
7423
7526
  getConfigHome(),
7424
7527
  opts.vars?.["HOME_DIR"]
7425
7528
  ].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("/"))))))
7529
+ if ([...homes].some((home) => SESSION_RENDER_OWNED_CONFIG_TARGETS.some((relativePath) => normalized === normalizeTargetPath(join9(home, ...relativePath.split("/"))))))
7427
7530
  return true;
7428
7531
  return sessionRenderOwnsPath(normalized);
7429
7532
  }
@@ -7456,8 +7559,8 @@ __export(exports_sync, {
7456
7559
  KNOWN_CONFIGS: () => KNOWN_CONFIGS,
7457
7560
  CLAUDE_PROMPT_OUTPUTS: () => CLAUDE_PROMPT_OUTPUTS
7458
7561
  });
7459
- import { existsSync as existsSync6, readdirSync, readFileSync as readFileSync4 } from "fs";
7460
- import { basename as basename4, extname as extname2, join as join9 } from "path";
7562
+ import { existsSync as existsSync7, readdirSync, readFileSync as readFileSync4 } from "fs";
7563
+ import { basename as basename4, extname as extname2, join as join10 } from "path";
7461
7564
  function claudeRuleOutputs(fileName) {
7462
7565
  const stem = basename4(fileName, extname2(fileName));
7463
7566
  return [
@@ -7496,7 +7599,7 @@ function isGeneratedOutputTarget2(config, owners) {
7496
7599
  return !!ownerIds && !ownerIds.has(config.id);
7497
7600
  }
7498
7601
  function hasClaudePromptSource() {
7499
- return existsSync6(expandPath("~/.claude/CLAUDE.md"));
7602
+ return existsSync7(expandPath("~/.claude/CLAUDE.md"));
7500
7603
  }
7501
7604
  function hasClaudeRuleSourceForCursorTarget(targetPath) {
7502
7605
  const absoluteTargetPath = expandPath(targetPath);
@@ -7504,7 +7607,7 @@ function hasClaudeRuleSourceForCursorTarget(targetPath) {
7504
7607
  if (!absoluteTargetPath.startsWith(`${absolutePrefix}/`) || !absoluteTargetPath.endsWith(".mdc"))
7505
7608
  return false;
7506
7609
  const stem = basename4(absoluteTargetPath, ".mdc");
7507
- return existsSync6(expandPath(`~/.claude/rules/${stem}.md`)) || existsSync6(expandPath(`~/.claude/rules/${stem}.mdc`));
7610
+ return existsSync7(expandPath(`~/.claude/rules/${stem}.md`)) || existsSync7(expandPath(`~/.claude/rules/${stem}.mdc`));
7508
7611
  }
7509
7612
  function isKnownGeneratedTargetPath(targetPath) {
7510
7613
  const normalizedTargetPath = normalizeTargetPath(targetPath);
@@ -7521,8 +7624,8 @@ async function syncProject(opts) {
7521
7624
  const allConfigs = await store.listConfigs();
7522
7625
  const machine = detectMachineContext();
7523
7626
  for (const pf of PROJECT_CONFIG_FILES) {
7524
- const abs = join9(absDir, pf.file);
7525
- if (!existsSync6(abs))
7627
+ const abs = join10(absDir, pf.file);
7628
+ if (!existsSync7(abs))
7526
7629
  continue;
7527
7630
  try {
7528
7631
  const rawContent = readFileSync4(abs, "utf-8");
@@ -7554,19 +7657,19 @@ async function syncProject(opts) {
7554
7657
  }
7555
7658
  }
7556
7659
  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" }
7660
+ { dir: join10(absDir, ".claude", "rules"), agent: "claude", namePrefix: "rules" },
7661
+ { dir: join10(absDir, ".agents", "rules"), agent: "antigravity", namePrefix: "antigravity-rules" },
7662
+ { dir: join10(absDir, ".cursor", "rules"), agent: "cursor", namePrefix: "cursor-rules" },
7663
+ { dir: join10(absDir, ".github", "instructions"), agent: "copilot", namePrefix: "copilot-instructions" },
7664
+ { dir: join10(absDir, ".devin", "rules"), agent: "devin", namePrefix: "devin-rules" },
7665
+ { dir: join10(absDir, ".windsurf", "rules"), agent: "windsurf-legacy", namePrefix: "windsurf-rules" },
7666
+ { dir: join10(absDir, ".clinerules"), agent: "cline", namePrefix: "cline-rules" }
7564
7667
  ]) {
7565
- if (!existsSync6(ruleDir.dir))
7668
+ if (!existsSync7(ruleDir.dir))
7566
7669
  continue;
7567
7670
  const mdFiles = readdirSync(ruleDir.dir).filter((f) => f.endsWith(".md") || f.endsWith(".mdc"));
7568
7671
  for (const f of mdFiles) {
7569
- const abs = join9(ruleDir.dir, f);
7672
+ const abs = join10(ruleDir.dir, f);
7570
7673
  const raw = readFileSync4(abs, "utf-8");
7571
7674
  const redacted = redactContent(raw, "markdown");
7572
7675
  const machineAware = templateizeMachineContent(redacted.content, machine);
@@ -7606,14 +7709,14 @@ async function syncKnown(opts = {}) {
7606
7709
  for (const known of targets) {
7607
7710
  if (known.rulesDir) {
7608
7711
  const absDir = expandPath(known.rulesDir);
7609
- if (!existsSync6(absDir)) {
7712
+ if (!existsSync7(absDir)) {
7610
7713
  result.skipped.push(known.rulesDir);
7611
7714
  continue;
7612
7715
  }
7613
7716
  const extensions = known.rulesExtensions ?? [".md", ".mdc"];
7614
7717
  const ruleFiles = readdirSync(absDir).filter((f) => extensions.some((ext) => f.endsWith(ext)));
7615
7718
  for (const f of ruleFiles) {
7616
- const abs2 = join9(absDir, f);
7719
+ const abs2 = join10(absDir, f);
7617
7720
  const targetPath = abs2.replace(home, "~");
7618
7721
  if (existingOutputOwners.has(normalizeTargetPath(targetPath)) || isKnownGeneratedTargetPath(targetPath)) {
7619
7722
  result.skipped.push(`${targetPath} (generated output)`);
@@ -7647,7 +7750,7 @@ async function syncKnown(opts = {}) {
7647
7750
  continue;
7648
7751
  }
7649
7752
  const abs = expandPath(known.path);
7650
- if (!existsSync6(abs)) {
7753
+ if (!existsSync7(abs)) {
7651
7754
  result.skipped.push(known.path);
7652
7755
  continue;
7653
7756
  }
@@ -7753,7 +7856,7 @@ function storedPlaceholderIsLiteralOnDisk(storedLine, diskLine) {
7753
7856
  }
7754
7857
  function buildDiff(expectedContent, targetPath, storedFormat, showSecrets) {
7755
7858
  const path = expandPath(targetPath);
7756
- if (!existsSync6(path))
7859
+ if (!existsSync7(path))
7757
7860
  return `(file not found on disk: ${path})`;
7758
7861
  const diskContent = readFileSync4(path, "utf-8");
7759
7862
  if (diskContent === expectedContent)
@@ -7983,20 +8086,20 @@ var init_sync = __esm(() => {
7983
8086
  });
7984
8087
 
7985
8088
  // 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";
8089
+ import { existsSync as existsSync8, readdirSync as readdirSync2, readFileSync as readFileSync5, statSync as statSync2 } from "fs";
8090
+ import { join as join11, relative as relative3 } from "path";
8091
+ import { homedir as homedir6 } from "os";
7989
8092
  function shouldSkip(p) {
7990
8093
  return SKIP.some((s) => p.includes(s));
7991
8094
  }
7992
8095
  async function syncFromDir(dir, opts = {}) {
7993
8096
  const store = opts.store ?? resolveConfigStore();
7994
8097
  const absDir = expandPath(dir);
7995
- if (!existsSync7(absDir))
8098
+ if (!existsSync8(absDir))
7996
8099
  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());
8100
+ const files = opts.recursive !== false ? walkDir(absDir) : readdirSync2(absDir).map((f) => join11(absDir, f)).filter((f) => statSync2(f).isFile());
7998
8101
  const result = { added: 0, updated: 0, unchanged: 0, skipped: [] };
7999
- const home = homedir5();
8102
+ const home = homedir6();
8000
8103
  const allConfigs = await store.listConfigs();
8001
8104
  for (const file of files) {
8002
8105
  if (shouldSkip(file)) {
@@ -8031,7 +8134,7 @@ async function syncFromDir(dir, opts = {}) {
8031
8134
  }
8032
8135
  async function syncToDir(dir, opts = {}) {
8033
8136
  const store = opts.store ?? resolveConfigStore();
8034
- const home = homedir5();
8137
+ const home = homedir6();
8035
8138
  const absDir = expandPath(dir);
8036
8139
  const normalized = dir.startsWith("~/") ? dir : absDir.replace(home, "~");
8037
8140
  const configs = (await store.listConfigs()).filter((c) => c.target_path && (c.target_path.startsWith(normalized) || c.target_path.startsWith(absDir)));
@@ -8055,7 +8158,7 @@ async function syncToDir(dir, opts = {}) {
8055
8158
  }
8056
8159
  function walkDir(dir, files = []) {
8057
8160
  for (const entry of readdirSync2(dir, { withFileTypes: true })) {
8058
- const full = join10(dir, entry.name);
8161
+ const full = join11(dir, entry.name);
8059
8162
  if (shouldSkip(full))
8060
8163
  continue;
8061
8164
  if (entry.isDirectory())
@@ -8078,7 +8181,7 @@ var init_sync_dir = __esm(() => {
8078
8181
  var require_package = __commonJS((exports, module) => {
8079
8182
  module.exports = {
8080
8183
  name: "@hasna/instructions",
8081
- version: "0.5.3",
8184
+ version: "0.5.4",
8082
8185
  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
8186
  type: "module",
8084
8187
  main: "dist/index.js",
@@ -8119,7 +8222,7 @@ var require_package = __commonJS((exports, module) => {
8119
8222
  "dev:serve": "bun run src/server/index.ts",
8120
8223
  seed: "bun run scripts/seed.ts",
8121
8224
  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",
8225
+ 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
8226
  prepack: "bun run build"
8124
8227
  },
8125
8228
  keywords: [
@@ -8154,12 +8257,13 @@ var require_package = __commonJS((exports, module) => {
8154
8257
  author: "Andrei Hasna <andrei@hasna.com>",
8155
8258
  license: "Apache-2.0",
8156
8259
  dependencies: {
8157
- "@hasna/contracts": "0.14.0",
8260
+ "@hasna/contracts": "0.14.1",
8158
8261
  "@hasna/events": "^0.1.16",
8262
+ "@hasna/paths": "0.1.0",
8159
8263
  "@modelcontextprotocol/sdk": "^1.12.1",
8160
8264
  chalk: "^5.4.1",
8161
8265
  commander: "^13.1.0",
8162
- hono: "^4.7.4",
8266
+ hono: "4.13.3",
8163
8267
  ink: "^5.2.0",
8164
8268
  pg: "^8.13.3",
8165
8269
  react: "^18.3.1",
@@ -1715,7 +1715,7 @@ class ProfileNotFoundError extends Error {
1715
1715
  }
1716
1716
  }
1717
1717
 
1718
- // ../../node_modules/.bun/@hasna+contracts@0.14.0+e8014c875821e0be/node_modules/@hasna/contracts/dist/auth/index.js
1718
+ // ../contracts/dist/auth/index.js
1719
1719
  import { createHash, createHmac, randomBytes, timingSafeEqual } from "crypto";
1720
1720
  var MAX_TENANT_ID_LENGTH = 64;
1721
1721
  var TENANT_ID_PATTERN = new RegExp(`^[A-Za-z0-9][A-Za-z0-9._-]{0,${MAX_TENANT_ID_LENGTH - 1}}$`);