@hasna/instructions 0.4.36 → 0.4.42

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.
Files changed (57) hide show
  1. package/README.md +9 -8
  2. package/assets/skills/inbox/SKILL.md +86 -0
  3. package/dashboard/README.md +34 -70
  4. package/dist/cli/index.js +1673 -516
  5. package/dist/cli/raw-store-root.test.d.ts +2 -0
  6. package/dist/cli/raw-store-root.test.d.ts.map +1 -0
  7. package/dist/data/config-store.d.ts +4 -4
  8. package/dist/data/config-store.d.ts.map +1 -1
  9. package/dist/db/configs.d.ts.map +1 -1
  10. package/dist/db/database.d.ts.map +1 -1
  11. package/dist/generated/storage-kit/backend.d.ts +20 -0
  12. package/dist/generated/storage-kit/backend.d.ts.map +1 -0
  13. package/dist/generated/storage-kit/index.d.ts +2 -2
  14. package/dist/generated/storage-kit/index.d.ts.map +1 -1
  15. package/dist/generated/storage-kit/migrations.d.ts.map +1 -1
  16. package/dist/generated/storage-kit/own.d.ts +11 -0
  17. package/dist/generated/storage-kit/own.d.ts.map +1 -0
  18. package/dist/generated/storage-kit/pool.d.ts +7 -6
  19. package/dist/generated/storage-kit/pool.d.ts.map +1 -1
  20. package/dist/generated/storage-kit/tls.d.ts +30 -3
  21. package/dist/generated/storage-kit/tls.d.ts.map +1 -1
  22. package/dist/index.d.ts +4 -2
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +945 -372
  25. package/dist/lib/instruction-graph.d.ts.map +1 -1
  26. package/dist/lib/managed-skill-runtimes.d.ts +80 -0
  27. package/dist/lib/managed-skill-runtimes.d.ts.map +1 -0
  28. package/dist/lib/managed-skill-runtimes.test.d.ts +2 -0
  29. package/dist/lib/managed-skill-runtimes.test.d.ts.map +1 -0
  30. package/dist/lib/raw-store-root.d.ts +17 -0
  31. package/dist/lib/raw-store-root.d.ts.map +1 -0
  32. package/dist/lib/retired-storage-mode.d.ts +8 -0
  33. package/dist/lib/retired-storage-mode.d.ts.map +1 -0
  34. package/dist/lib/session-apply.d.ts.map +1 -1
  35. package/dist/lib/session-authority.d.ts +27 -0
  36. package/dist/lib/session-authority.d.ts.map +1 -0
  37. package/dist/lib/session-authority.test.d.ts +2 -0
  38. package/dist/lib/session-authority.test.d.ts.map +1 -0
  39. package/dist/lib/session-render.d.ts +7 -3
  40. package/dist/lib/session-render.d.ts.map +1 -1
  41. package/dist/mcp/index.js +177 -115
  42. package/dist/server/cloud-auth.test.d.ts +2 -0
  43. package/dist/server/cloud-auth.test.d.ts.map +1 -0
  44. package/dist/server/cloud.d.ts +7 -4
  45. package/dist/server/cloud.d.ts.map +1 -1
  46. package/dist/server/cloud.test.d.ts +2 -0
  47. package/dist/server/cloud.test.d.ts.map +1 -0
  48. package/dist/server/index.d.ts +1 -1
  49. package/dist/server/index.js +781 -325
  50. package/dist/status.d.ts +11 -1
  51. package/dist/status.d.ts.map +1 -1
  52. package/dist/storage/cloud-store.d.ts.map +1 -1
  53. package/dist/storage/cloud-store.test.d.ts +2 -0
  54. package/dist/storage/cloud-store.test.d.ts.map +1 -0
  55. package/package.json +10 -7
  56. package/dist/generated/storage-kit/mode.d.ts +0 -48
  57. package/dist/generated/storage-kit/mode.d.ts.map +0 -1
package/dist/mcp/index.js CHANGED
@@ -73,19 +73,51 @@ var init_types = __esm(() => {
73
73
  };
74
74
  });
75
75
 
76
+ // src/lib/retired-storage-mode.ts
77
+ function firstDefinedEnvKey(env, keys) {
78
+ for (const key of keys) {
79
+ if (Object.hasOwn(env, key) && env[key] !== undefined)
80
+ return key;
81
+ }
82
+ return null;
83
+ }
84
+ function assertNoLegacyStorageMode(env = process.env) {
85
+ const legacyKey = firstDefinedEnvKey(env, LEGACY_STORAGE_MODE_KEYS);
86
+ if (!legacyKey)
87
+ return;
88
+ throw new Error(`${legacyKey} was removed. Deployment modes no longer exist: delete the storage-mode variable. ` + `The client uses the local SQLite store, or the HTTP API selected by ` + `HASNA_INSTRUCTIONS_API_URL + HASNA_INSTRUCTIONS_API_KEY. ` + `On the server, set HASNA_INSTRUCTIONS_DATABASE_URL to select the postgresql backend, ` + `or leave it unset for sqlite.`);
89
+ }
90
+ var LEGACY_STORAGE_MODE_KEYS;
91
+ var init_retired_storage_mode = __esm(() => {
92
+ LEGACY_STORAGE_MODE_KEYS = [
93
+ "HASNA_INSTRUCTIONS_STORAGE_MODE",
94
+ "HASNA_INSTRUCTIONS_MODE",
95
+ "INSTRUCTIONS_STORAGE_MODE",
96
+ "INSTRUCTIONS_MODE"
97
+ ];
98
+ });
99
+
100
+ // src/lib/raw-store-root.ts
101
+ import { homedir } from "os";
102
+ import { join, resolve } from "path";
103
+ function getRawStoreRoot() {
104
+ return resolve(process.env[RAW_STORE_ROOT_ENV] || join(process.env["HOME"] || homedir(), ".hasna", "instructions"));
105
+ }
106
+ var RAW_STORE_ROOT_ENV = "HASNA_CONFIGS_HOME";
107
+ var init_raw_store_root = () => {};
108
+
76
109
  // src/db/database.ts
77
110
  import { Database } from "bun:sqlite";
78
111
  import { existsSync, mkdirSync, rmSync } from "fs";
79
- import { join } from "path";
112
+ import { join as join2 } from "path";
80
113
  import { randomUUID } from "crypto";
81
114
  function getDbPath() {
82
115
  if (process.env["HASNA_INSTRUCTIONS_DB_PATH"]) {
83
116
  return process.env["HASNA_INSTRUCTIONS_DB_PATH"];
84
117
  }
85
- const home = process.env["HOME"] || process.env["USERPROFILE"] || "~";
86
- const dir = join(home, ".hasna", "instructions");
118
+ const dir = getRawStoreRoot();
87
119
  mkdirSync(dir, { recursive: true });
88
- return join(dir, "instructions.db");
120
+ return join2(dir, "instructions.db");
89
121
  }
90
122
  function uuid() {
91
123
  return randomUUID();
@@ -99,8 +131,9 @@ function slugify(name) {
99
131
  function getDatabase(path) {
100
132
  if (_db)
101
133
  return _db;
134
+ assertNoLegacyStorageMode();
102
135
  if (!path && process.env["HASNA_INSTRUCTIONS_API_URL"] && process.env["HASNA_INSTRUCTIONS_API_KEY"]) {
103
- throw new Error("instructions is in self_hosted (cloud) mode: this command is not wired to the cloud API yet. " + "Unset HASNA_INSTRUCTIONS_API_URL / HASNA_INSTRUCTIONS_API_KEY to use it against the local store.");
136
+ throw new Error("instructions is using the HTTP API transport (HASNA_INSTRUCTIONS_API_URL set): this command is not wired to the API yet. " + "Unset HASNA_INSTRUCTIONS_API_URL / HASNA_INSTRUCTIONS_API_KEY to use it against the local store.");
104
137
  }
105
138
  const dbPath = path || getDbPath();
106
139
  const db = new Database(dbPath);
@@ -181,6 +214,8 @@ function insertFeedback(input, db) {
181
214
  }
182
215
  var MIGRATIONS, _db = null;
183
216
  var init_database = __esm(() => {
217
+ init_retired_storage_mode();
218
+ init_raw_store_root();
184
219
  MIGRATIONS = [
185
220
  `
186
221
  CREATE TABLE IF NOT EXISTS configs (
@@ -265,6 +300,37 @@ var init_database = __esm(() => {
265
300
  ];
266
301
  });
267
302
 
303
+ // src/db/snapshots.ts
304
+ function createSnapshot(configId, content, version, db) {
305
+ const d = db || getDatabase();
306
+ const id = uuid();
307
+ const ts = now();
308
+ d.run("INSERT INTO config_snapshots (id, config_id, content, version, created_at) VALUES (?, ?, ?, ?, ?)", [id, configId, content, version, ts]);
309
+ return { id, config_id: configId, content, version, created_at: ts };
310
+ }
311
+ function listSnapshots(configId, db) {
312
+ const d = db || getDatabase();
313
+ return d.query("SELECT * FROM config_snapshots WHERE config_id = ? ORDER BY version DESC").all(configId);
314
+ }
315
+ function getSnapshot(id, db) {
316
+ const d = db || getDatabase();
317
+ return d.query("SELECT * FROM config_snapshots WHERE id = ?").get(id);
318
+ }
319
+ function getSnapshotByVersion(configId, version, db) {
320
+ const d = db || getDatabase();
321
+ return d.query("SELECT * FROM config_snapshots WHERE config_id = ? AND version = ?").get(configId, version);
322
+ }
323
+ function pruneSnapshots(configId, keep = 10, db) {
324
+ const d = db || getDatabase();
325
+ const result = d.run(`DELETE FROM config_snapshots WHERE config_id = ? AND id NOT IN (
326
+ SELECT id FROM config_snapshots WHERE config_id = ? ORDER BY version DESC LIMIT ?
327
+ )`, [configId, configId, keep]);
328
+ return result.changes;
329
+ }
330
+ var init_snapshots = __esm(() => {
331
+ init_database();
332
+ });
333
+
268
334
  // src/db/configs.ts
269
335
  function rowToConfig(row) {
270
336
  let outputs = [];
@@ -303,25 +369,28 @@ function createConfig(input, db) {
303
369
  const slug = uniqueSlug(input.name, d);
304
370
  const tags = JSON.stringify(input.tags || []);
305
371
  const outputs = JSON.stringify(input.outputs || []);
306
- d.run(`INSERT INTO configs (id, name, slug, kind, category, agent, target_path, outputs, format, content, description, tags, is_template, version, created_at, updated_at, synced_at)
307
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, ?, ?, NULL)`, [
308
- id,
309
- input.name,
310
- slug,
311
- input.kind ?? "file",
312
- input.category,
313
- input.agent ?? "global",
314
- input.target_path ?? null,
315
- outputs,
316
- input.format ?? "text",
317
- input.content,
318
- input.description ?? null,
319
- tags,
320
- input.is_template ? 1 : 0,
321
- ts,
322
- ts
323
- ]);
324
- return getConfig(id, d);
372
+ return d.transaction(() => {
373
+ d.run(`INSERT INTO configs (id, name, slug, kind, category, agent, target_path, outputs, format, content, description, tags, is_template, version, created_at, updated_at, synced_at)
374
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, ?, ?, NULL)`, [
375
+ id,
376
+ input.name,
377
+ slug,
378
+ input.kind ?? "file",
379
+ input.category,
380
+ input.agent ?? "global",
381
+ input.target_path ?? null,
382
+ outputs,
383
+ input.format ?? "text",
384
+ input.content,
385
+ input.description ?? null,
386
+ tags,
387
+ input.is_template ? 1 : 0,
388
+ ts,
389
+ ts
390
+ ]);
391
+ createSnapshot(id, input.content, 1, d);
392
+ return getConfig(id, d);
393
+ })();
325
394
  }
326
395
  function getConfig(idOrSlug, db) {
327
396
  const d = db || getDatabase();
@@ -426,9 +495,13 @@ function updateConfig(idOrSlug, input, db) {
426
495
  updates.push("synced_at = ?");
427
496
  params.push(input.synced_at);
428
497
  }
429
- params.push(existing.id);
430
- d.run(`UPDATE configs SET ${updates.join(", ")} WHERE id = ?`, params);
431
- return getConfigById(existing.id, d);
498
+ return d.transaction(() => {
499
+ params.push(existing.id);
500
+ d.run(`UPDATE configs SET ${updates.join(", ")} WHERE id = ?`, params);
501
+ const updated = getConfigById(existing.id, d);
502
+ createSnapshot(updated.id, updated.content, updated.version, d);
503
+ return updated;
504
+ })();
432
505
  }
433
506
  function deleteConfig(idOrSlug, db) {
434
507
  const d = db || getDatabase();
@@ -448,6 +521,7 @@ function getConfigStats(db) {
448
521
  var init_configs = __esm(() => {
449
522
  init_types();
450
523
  init_database();
524
+ init_snapshots();
451
525
  });
452
526
 
453
527
  // src/lib/template.ts
@@ -521,9 +595,9 @@ var init_template = __esm(() => {
521
595
  });
522
596
 
523
597
  // src/lib/machine.ts
524
- import { arch as currentArch, homedir, hostname as currentHostname, type as currentOsType } from "os";
598
+ import { arch as currentArch, homedir as homedir2, hostname as currentHostname, type as currentOsType } from "os";
525
599
  import { existsSync as existsSync2 } from "fs";
526
- import { join as join2 } from "path";
600
+ import { join as join3 } from "path";
527
601
  function normalizeOsFamily(os) {
528
602
  const value = (os ?? "").trim().toLowerCase();
529
603
  if (value === "darwin" || value === "macos" || value === "mac" || value === "osx")
@@ -535,11 +609,11 @@ function normalizeOsFamily(os) {
535
609
  return value || "unknown";
536
610
  }
537
611
  function detectMachineContext(overrides = {}) {
538
- const homeDir = overrides.home_dir ?? process.env["CONFIGS_HOME"] ?? process.env["HOME"] ?? homedir();
612
+ const homeDir = overrides.home_dir ?? process.env["CONFIGS_HOME"] ?? process.env["HOME"] ?? homedir2();
539
613
  const os = overrides.os ?? currentOsType();
540
614
  const osFamily = normalizeOsFamily(os);
541
- const bunBinDir = overrides.bun_bin_dir ?? join2(homeDir, ".bun", "bin");
542
- const defaultBunPath = osFamily === "macos" && existsSync2(BREW_BUN_PATH) ? BREW_BUN_PATH : join2(bunBinDir, "bun");
615
+ const bunBinDir = overrides.bun_bin_dir ?? join3(homeDir, ".bun", "bin");
616
+ const defaultBunPath = osFamily === "macos" && existsSync2(BREW_BUN_PATH) ? BREW_BUN_PATH : join3(bunBinDir, "bun");
543
617
  return {
544
618
  id: "current-machine",
545
619
  hostname: overrides.hostname ?? currentHostname(),
@@ -549,10 +623,10 @@ function detectMachineContext(overrides = {}) {
549
623
  created_at: "",
550
624
  os_family: osFamily,
551
625
  home_dir: homeDir,
552
- workspace_root: overrides.workspace_root ?? join2(homeDir, osFamily === "macos" ? "Workspace" : "workspace"),
626
+ workspace_root: overrides.workspace_root ?? join3(homeDir, osFamily === "macos" ? "Workspace" : "workspace"),
553
627
  bun_bin_dir: bunBinDir,
554
628
  bun_path: overrides.bun_path ?? defaultBunPath,
555
- path_prefix: overrides.path_prefix ?? (osFamily === "macos" ? `${join2("/opt", "homebrew", "bin")}:${bunBinDir}` : bunBinDir)
629
+ path_prefix: overrides.path_prefix ?? (osFamily === "macos" ? `${join3("/opt", "homebrew", "bin")}:${bunBinDir}` : bunBinDir)
556
630
  };
557
631
  }
558
632
  function machineContextToVariables(machine) {
@@ -860,7 +934,7 @@ Policy reference: \`${CODEWITH_SHARED_TODOS_STORAGE_POLICY_REFERENCE}\`
860
934
  `;
861
935
  });
862
936
 
863
- // node_modules/zod/v3/helpers/util.js
937
+ // ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/util.js
864
938
  var util, objectUtil, ZodParsedType, getParsedType = (data) => {
865
939
  const t = typeof data;
866
940
  switch (t) {
@@ -991,7 +1065,7 @@ var init_util = __esm(() => {
991
1065
  ]);
992
1066
  });
993
1067
 
994
- // node_modules/zod/v3/ZodError.js
1068
+ // ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/ZodError.js
995
1069
  var ZodIssueCode, quotelessJson = (obj) => {
996
1070
  const json = JSON.stringify(obj, null, 2);
997
1071
  return json.replace(/"([^"]+)":/g, "$1:");
@@ -1112,7 +1186,7 @@ var init_ZodError = __esm(() => {
1112
1186
  };
1113
1187
  });
1114
1188
 
1115
- // node_modules/zod/v3/locales/en.js
1189
+ // ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/locales/en.js
1116
1190
  var errorMap = (issue, _ctx) => {
1117
1191
  let message;
1118
1192
  switch (issue.code) {
@@ -1219,7 +1293,7 @@ var init_en = __esm(() => {
1219
1293
  en_default = errorMap;
1220
1294
  });
1221
1295
 
1222
- // node_modules/zod/v3/errors.js
1296
+ // ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/errors.js
1223
1297
  function setErrorMap(map) {
1224
1298
  overrideErrorMap = map;
1225
1299
  }
@@ -1232,7 +1306,7 @@ var init_errors = __esm(() => {
1232
1306
  overrideErrorMap = en_default;
1233
1307
  });
1234
1308
 
1235
- // node_modules/zod/v3/helpers/parseUtil.js
1309
+ // ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
1236
1310
  function addIssueToContext(ctx, issueData) {
1237
1311
  const overrideMap = getErrorMap();
1238
1312
  const issue = makeIssue({
@@ -1337,10 +1411,10 @@ var init_parseUtil = __esm(() => {
1337
1411
  });
1338
1412
  });
1339
1413
 
1340
- // node_modules/zod/v3/helpers/typeAliases.js
1414
+ // ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/typeAliases.js
1341
1415
  var init_typeAliases = () => {};
1342
1416
 
1343
- // node_modules/zod/v3/helpers/errorUtil.js
1417
+ // ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.js
1344
1418
  var errorUtil;
1345
1419
  var init_errorUtil = __esm(() => {
1346
1420
  (function(errorUtil2) {
@@ -1349,7 +1423,7 @@ var init_errorUtil = __esm(() => {
1349
1423
  })(errorUtil || (errorUtil = {}));
1350
1424
  });
1351
1425
 
1352
- // node_modules/zod/v3/types.js
1426
+ // ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/types.js
1353
1427
  class ParseInputLazyPath {
1354
1428
  constructor(parent, value, path, key) {
1355
1429
  this._cachedPath = [];
@@ -4700,7 +4774,7 @@ var init_types2 = __esm(() => {
4700
4774
  NEVER = INVALID;
4701
4775
  });
4702
4776
 
4703
- // node_modules/zod/v3/external.js
4777
+ // ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/external.js
4704
4778
  var exports_external = {};
4705
4779
  __export(exports_external, {
4706
4780
  void: () => voidType,
@@ -4820,7 +4894,7 @@ var init_external = __esm(() => {
4820
4894
  init_ZodError();
4821
4895
  });
4822
4896
 
4823
- // node_modules/zod/index.js
4897
+ // ../../node_modules/.bun/zod@3.25.76/node_modules/zod/index.js
4824
4898
  var init_zod = __esm(() => {
4825
4899
  init_external();
4826
4900
  init_external();
@@ -5023,7 +5097,7 @@ var init_redact = __esm(() => {
5023
5097
  VALUE_PATTERNS = [
5024
5098
  { re: /npm_[A-Za-z0-9]{36,}/, reason: "npm token" },
5025
5099
  { re: /gh[pousr]_[A-Za-z0-9_]{36,}/, reason: "GitHub token" },
5026
- { re: /sk-ant-[A-Za-z0-9\-_]{40,}/, reason: "Anthropic API key" },
5100
+ { re: /sk[-]ant-[A-Za-z0-9\-_]{40,}/, reason: "Anthropic API key" },
5027
5101
  { re: /sk-[A-Za-z0-9]{48,}/, reason: "OpenAI API key" },
5028
5102
  { re: /xoxb-[0-9]+-[A-Za-z0-9\-]+/, reason: "Slack bot token" },
5029
5103
  { re: /AIza[0-9A-Za-z\-_]{35}/, reason: "Google API key" },
@@ -5041,7 +5115,7 @@ var init_session_render_contract = __esm(() => {
5041
5115
  });
5042
5116
 
5043
5117
  // src/lib/project-context.ts
5044
- import { basename, dirname, isAbsolute, join as join3, parse, relative, resolve } from "path";
5118
+ import { basename, dirname, isAbsolute, join as join4, parse, relative, resolve as resolve2 } from "path";
5045
5119
  function revisionKey(value) {
5046
5120
  const sequence = value.match(/^(?:rev-)?([0-9]+)$/);
5047
5121
  if (sequence)
@@ -5603,16 +5677,16 @@ var init_asset_plan = __esm(() => {
5603
5677
 
5604
5678
  // src/lib/cursor-authority.ts
5605
5679
  import { createHash } from "crypto";
5606
- import { homedir as homedir2 } from "os";
5607
- import { join as join4, resolve as resolve2 } from "path";
5680
+ import { homedir as homedir3 } from "os";
5681
+ import { join as join5, resolve as resolve3 } from "path";
5608
5682
  function sha256(content) {
5609
5683
  return createHash("sha256").update(content).digest("hex");
5610
5684
  }
5611
5685
  function homeDir() {
5612
- return process.env["HOME"] || homedir2();
5686
+ return process.env["HOME"] || homedir3();
5613
5687
  }
5614
5688
  function isCursorGlobalAuthorityPath(path) {
5615
- return resolve2(path) === resolve2(join4(homeDir(), CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH));
5689
+ return resolve3(path) === resolve3(join5(homeDir(), CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH));
5616
5690
  }
5617
5691
  function stampCursorGlobalAuthorityMarker(content) {
5618
5692
  if (CURSOR_GLOBAL_AUTHORITY_MARKER_PATTERN.test(content))
@@ -5634,6 +5708,12 @@ var init_cursor_authority = __esm(() => {
5634
5708
  CURSOR_GLOBAL_AUTHORITY_FRONTMATTER_PATTERN = /^---\n[\s\S]*?\n---(?:\n|$)/;
5635
5709
  });
5636
5710
 
5711
+ // src/lib/session-authority.ts
5712
+ var CLAUDE_LEGACY_AUTHORITY_MAX_BYTES;
5713
+ var init_session_authority = __esm(() => {
5714
+ CLAUDE_LEGACY_AUTHORITY_MAX_BYTES = 256 * 1024;
5715
+ });
5716
+
5637
5717
  // src/lib/session-render.ts
5638
5718
  var ANTIGRAVITY_RULE_FILE_CHAR_LIMIT = 12000, SESSION_RENDERER_OWNER_ID = "instructions-session-renderer", SESSION_RENDER_PROFILE_ENTRYPOINTS, SESSION_RENDER_OWNED_CONFIG_TARGETS, IDENTITY_EXPORT_AUTHORITY, CODEWITH_PROTECTED_REPLACEMENT_TARGETS, CODEWITH_FLATTENED_ADAPTER, CODEWITH_NATIVE_ADAPTER, SESSION_TOOL_ADAPTERS, SESSION_RENDER_MANAGED_DIRS, SESSION_RENDER_SHARED_MANAGED_DIRS, SESSION_RENDER_EXCLUSIVE_MANAGED_PATHS, CANONICAL_IDENTITY_EXPORT_PACKAGES;
5639
5719
  var init_session_render = __esm(() => {
@@ -5644,8 +5724,11 @@ var init_session_render = __esm(() => {
5644
5724
  init_transforms();
5645
5725
  init_asset_plan();
5646
5726
  init_cursor_authority();
5727
+ init_session_authority();
5647
5728
  init_session_render_contract();
5648
5729
  init_session_render_contract();
5730
+ init_raw_store_root();
5731
+ init_raw_store_root();
5649
5732
  SESSION_RENDER_PROFILE_ENTRYPOINTS = [
5650
5733
  ".claude/CLAUDE.md",
5651
5734
  ".codex/AGENTS.md",
@@ -5947,7 +6030,12 @@ var init_instruction_graph = __esm(() => {
5947
6030
  init_asset_plan();
5948
6031
  COMMON_FALLBACKS = ["fail", "flatten", "promote-always", "omit"];
5949
6032
  DEFAULT_PROVIDER_CAPABILITIES = Object.freeze({
5950
- claude: capability("claude", ">=1.0.0", "native-import", "CLAUDE.md @ imports", { native_imports: true, asset_surface: "code" }),
6033
+ claude: capability("claude", ">=1.0.0", "native-import", "CLAUDE.md @ imports plus path-gated rules", {
6034
+ activation_modes: ["always", "glob"],
6035
+ native_imports: true,
6036
+ conditional_artifacts: true,
6037
+ asset_surface: "code"
6038
+ }),
5951
6039
  codex: capability("codex", ">=0.1.0", "flattened", "AGENTS.md", { asset_surface: "cli" }),
5952
6040
  cursor: capability("cursor", ">=1.0.0", "cursor-rule", ".cursor/rules/*.mdc", { activation_modes: ["always", "glob"], conditional_artifacts: true, asset_surface: "ide" }),
5953
6041
  opencode: capability("opencode", ">=1.0.0", "managed-fragment", "opencode.json instructions", { provider_variant: "v1-instructions", session_surface: "opencode-config-instructions" }),
@@ -6218,37 +6306,6 @@ var init_profiles = __esm(() => {
6218
6306
  init_asset_plan();
6219
6307
  });
6220
6308
 
6221
- // src/db/snapshots.ts
6222
- function createSnapshot(configId, content, version, db) {
6223
- const d = db || getDatabase();
6224
- const id = uuid();
6225
- const ts = now();
6226
- d.run("INSERT INTO config_snapshots (id, config_id, content, version, created_at) VALUES (?, ?, ?, ?, ?)", [id, configId, content, version, ts]);
6227
- return { id, config_id: configId, content, version, created_at: ts };
6228
- }
6229
- function listSnapshots(configId, db) {
6230
- const d = db || getDatabase();
6231
- return d.query("SELECT * FROM config_snapshots WHERE config_id = ? ORDER BY version DESC").all(configId);
6232
- }
6233
- function getSnapshot(id, db) {
6234
- const d = db || getDatabase();
6235
- return d.query("SELECT * FROM config_snapshots WHERE id = ?").get(id);
6236
- }
6237
- function getSnapshotByVersion(configId, version, db) {
6238
- const d = db || getDatabase();
6239
- return d.query("SELECT * FROM config_snapshots WHERE config_id = ? AND version = ?").get(configId, version);
6240
- }
6241
- function pruneSnapshots(configId, keep = 10, db) {
6242
- const d = db || getDatabase();
6243
- const result = d.run(`DELETE FROM config_snapshots WHERE config_id = ? AND id NOT IN (
6244
- SELECT id FROM config_snapshots WHERE config_id = ? ORDER BY version DESC LIMIT ?
6245
- )`, [configId, configId, keep]);
6246
- return result.changes;
6247
- }
6248
- var init_snapshots = __esm(() => {
6249
- init_database();
6250
- });
6251
-
6252
6309
  // src/db/machines.ts
6253
6310
  import { arch, hostname, type } from "os";
6254
6311
  function currentHostname2() {
@@ -6320,12 +6377,13 @@ function parseBoundedOrLegacyPage(value, legacyItems, options, label) {
6320
6377
  return { ...page, source_bounded: false };
6321
6378
  }
6322
6379
  function resolveCloudConfig(env = process.env) {
6380
+ assertNoLegacyStorageMode(env);
6323
6381
  const apiUrl = env[API_URL_ENV]?.trim();
6324
6382
  const apiKey = env[API_KEY_ENV]?.trim();
6325
6383
  if (!apiUrl && !apiKey)
6326
6384
  return null;
6327
6385
  if (!apiUrl || !apiKey) {
6328
- throw new Error(`API mode requires BOTH ${API_URL_ENV} and ${API_KEY_ENV}; only ` + `${apiUrl ? API_URL_ENV : API_KEY_ENV} is set. Set both to use the cloud API, ` + `or unset both to use the local store.`);
6386
+ throw new Error(`API mode requires BOTH ${API_URL_ENV} and ${API_KEY_ENV}; only ` + `${apiUrl ? API_URL_ENV : API_KEY_ENV} is set. Set both to use the HTTP API, ` + `or unset both to use the local store.`);
6329
6387
  }
6330
6388
  return { apiUrl, apiKey };
6331
6389
  }
@@ -6812,6 +6870,7 @@ var init_config_store = __esm(() => {
6812
6870
  init_types();
6813
6871
  init_bounded_read();
6814
6872
  init_instruction_graph();
6873
+ init_retired_storage_mode();
6815
6874
  CloudHttpError = class CloudHttpError extends Error {
6816
6875
  status;
6817
6876
  body;
@@ -6826,7 +6885,7 @@ var init_config_store = __esm(() => {
6826
6885
 
6827
6886
  // src/lib/session-render-ownership.ts
6828
6887
  import { existsSync as existsSync3, readFileSync, statSync } from "fs";
6829
- import { dirname as dirname2, join as join5, parse as parse2, relative as relative2, sep } from "path";
6888
+ import { dirname as dirname2, join as join6, parse as parse2, relative as relative2, sep } from "path";
6830
6889
  function toSegments(absolutePath2) {
6831
6890
  return absolutePath2.replaceAll("\\", "/").split("/").filter(Boolean);
6832
6891
  }
@@ -6874,7 +6933,7 @@ function sessionRenderManifestClaimsPath(absolutePath2) {
6874
6933
  const root = parse2(absolutePath2).root;
6875
6934
  let home = dirname2(absolutePath2);
6876
6935
  for (let depth = 0;depth < MANIFEST_ANCESTOR_LIMIT; depth += 1) {
6877
- const manifestPath = join5(home, ...SESSION_RENDER_MANIFEST_RELATIVE_PATH.split("/"));
6936
+ const manifestPath = join6(home, ...SESSION_RENDER_MANIFEST_RELATIVE_PATH.split("/"));
6878
6937
  const relativePaths = readManifestRelativePaths(manifestPath);
6879
6938
  if (relativePaths) {
6880
6939
  const claimed = relative2(home, absolutePath2).split(sep).join("/");
@@ -6910,16 +6969,16 @@ __export(exports_apply, {
6910
6969
  applyConfig: () => applyConfig
6911
6970
  });
6912
6971
  import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync as readFileSync2, realpathSync, writeFileSync } from "fs";
6913
- import { basename as basename3, dirname as dirname3, join as join6, resolve as resolve3 } from "path";
6914
- import { homedir as homedir3 } from "os";
6972
+ import { basename as basename3, dirname as dirname3, join as join7, resolve as resolve4 } from "path";
6973
+ import { homedir as homedir4 } from "os";
6915
6974
  function getConfigHome() {
6916
- return process.env["CONFIGS_HOME"] || process.env["HOME"] || homedir3();
6975
+ return process.env["CONFIGS_HOME"] || process.env["HOME"] || homedir4();
6917
6976
  }
6918
6977
  function expandPath(p) {
6919
6978
  if (p.startsWith("~/")) {
6920
- return resolve3(getConfigHome(), p.slice(2));
6979
+ return resolve4(getConfigHome(), p.slice(2));
6921
6980
  }
6922
- return resolve3(p);
6981
+ return resolve4(p);
6923
6982
  }
6924
6983
  function normalizeTargetPath(p) {
6925
6984
  const expanded = expandPath(p);
@@ -6931,7 +6990,7 @@ function normalizeTargetPath(p) {
6931
6990
  while (true) {
6932
6991
  if (existsSync4(current)) {
6933
6992
  try {
6934
- return resolve3(realpathSync(current), ...missingSegments);
6993
+ return resolve4(realpathSync(current), ...missingSegments);
6935
6994
  } catch {
6936
6995
  return expanded;
6937
6996
  }
@@ -7324,7 +7383,7 @@ function sessionRendererOwnsCanonicalTarget(normalized, opts) {
7324
7383
  getConfigHome(),
7325
7384
  opts.vars?.["HOME_DIR"]
7326
7385
  ].filter((home) => typeof home === "string" && home.length > 0));
7327
- if ([...homes].some((home) => SESSION_RENDER_OWNED_CONFIG_TARGETS.some((relativePath) => normalized === normalizeTargetPath(join6(home, ...relativePath.split("/"))))))
7386
+ if ([...homes].some((home) => SESSION_RENDER_OWNED_CONFIG_TARGETS.some((relativePath) => normalized === normalizeTargetPath(join7(home, ...relativePath.split("/"))))))
7328
7387
  return true;
7329
7388
  return sessionRenderOwnsPath(normalized);
7330
7389
  }
@@ -7358,7 +7417,7 @@ __export(exports_sync, {
7358
7417
  CLAUDE_PROMPT_OUTPUTS: () => CLAUDE_PROMPT_OUTPUTS
7359
7418
  });
7360
7419
  import { existsSync as existsSync5, readdirSync, readFileSync as readFileSync3 } from "fs";
7361
- import { basename as basename4, extname as extname2, join as join7 } from "path";
7420
+ import { basename as basename4, extname as extname2, join as join8 } from "path";
7362
7421
  function claudeRuleOutputs(fileName) {
7363
7422
  const stem = basename4(fileName, extname2(fileName));
7364
7423
  return [
@@ -7422,7 +7481,7 @@ async function syncProject(opts) {
7422
7481
  const allConfigs = await store.listConfigs();
7423
7482
  const machine = detectMachineContext();
7424
7483
  for (const pf of PROJECT_CONFIG_FILES) {
7425
- const abs = join7(absDir, pf.file);
7484
+ const abs = join8(absDir, pf.file);
7426
7485
  if (!existsSync5(abs))
7427
7486
  continue;
7428
7487
  try {
@@ -7455,19 +7514,19 @@ async function syncProject(opts) {
7455
7514
  }
7456
7515
  }
7457
7516
  for (const ruleDir of [
7458
- { dir: join7(absDir, ".claude", "rules"), agent: "claude", namePrefix: "rules" },
7459
- { dir: join7(absDir, ".agents", "rules"), agent: "antigravity", namePrefix: "antigravity-rules" },
7460
- { dir: join7(absDir, ".cursor", "rules"), agent: "cursor", namePrefix: "cursor-rules" },
7461
- { dir: join7(absDir, ".github", "instructions"), agent: "copilot", namePrefix: "copilot-instructions" },
7462
- { dir: join7(absDir, ".devin", "rules"), agent: "devin", namePrefix: "devin-rules" },
7463
- { dir: join7(absDir, ".windsurf", "rules"), agent: "windsurf-legacy", namePrefix: "windsurf-rules" },
7464
- { dir: join7(absDir, ".clinerules"), agent: "cline", namePrefix: "cline-rules" }
7517
+ { dir: join8(absDir, ".claude", "rules"), agent: "claude", namePrefix: "rules" },
7518
+ { dir: join8(absDir, ".agents", "rules"), agent: "antigravity", namePrefix: "antigravity-rules" },
7519
+ { dir: join8(absDir, ".cursor", "rules"), agent: "cursor", namePrefix: "cursor-rules" },
7520
+ { dir: join8(absDir, ".github", "instructions"), agent: "copilot", namePrefix: "copilot-instructions" },
7521
+ { dir: join8(absDir, ".devin", "rules"), agent: "devin", namePrefix: "devin-rules" },
7522
+ { dir: join8(absDir, ".windsurf", "rules"), agent: "windsurf-legacy", namePrefix: "windsurf-rules" },
7523
+ { dir: join8(absDir, ".clinerules"), agent: "cline", namePrefix: "cline-rules" }
7465
7524
  ]) {
7466
7525
  if (!existsSync5(ruleDir.dir))
7467
7526
  continue;
7468
7527
  const mdFiles = readdirSync(ruleDir.dir).filter((f) => f.endsWith(".md") || f.endsWith(".mdc"));
7469
7528
  for (const f of mdFiles) {
7470
- const abs = join7(ruleDir.dir, f);
7529
+ const abs = join8(ruleDir.dir, f);
7471
7530
  const raw = readFileSync3(abs, "utf-8");
7472
7531
  const redacted = redactContent(raw, "markdown");
7473
7532
  const machineAware = templateizeMachineContent(redacted.content, machine);
@@ -7514,7 +7573,7 @@ async function syncKnown(opts = {}) {
7514
7573
  const extensions = known.rulesExtensions ?? [".md", ".mdc"];
7515
7574
  const ruleFiles = readdirSync(absDir).filter((f) => extensions.some((ext) => f.endsWith(ext)));
7516
7575
  for (const f of ruleFiles) {
7517
- const abs2 = join7(absDir, f);
7576
+ const abs2 = join8(absDir, f);
7518
7577
  const targetPath = abs2.replace(home, "~");
7519
7578
  if (existingOutputOwners.has(normalizeTargetPath(targetPath)) || isKnownGeneratedTargetPath(targetPath)) {
7520
7579
  result.skipped.push(`${targetPath} (generated output)`);
@@ -7885,8 +7944,8 @@ var init_sync = __esm(() => {
7885
7944
 
7886
7945
  // src/lib/sync-dir.ts
7887
7946
  import { existsSync as existsSync6, readdirSync as readdirSync2, readFileSync as readFileSync4, statSync as statSync2 } from "fs";
7888
- import { join as join8, relative as relative3 } from "path";
7889
- import { homedir as homedir4 } from "os";
7947
+ import { join as join9, relative as relative3 } from "path";
7948
+ import { homedir as homedir5 } from "os";
7890
7949
  function shouldSkip(p) {
7891
7950
  return SKIP.some((s) => p.includes(s));
7892
7951
  }
@@ -7895,9 +7954,9 @@ async function syncFromDir(dir, opts = {}) {
7895
7954
  const absDir = expandPath(dir);
7896
7955
  if (!existsSync6(absDir))
7897
7956
  return { added: 0, updated: 0, unchanged: 0, skipped: [`Not found: ${absDir}`] };
7898
- const files = opts.recursive !== false ? walkDir(absDir) : readdirSync2(absDir).map((f) => join8(absDir, f)).filter((f) => statSync2(f).isFile());
7957
+ const files = opts.recursive !== false ? walkDir(absDir) : readdirSync2(absDir).map((f) => join9(absDir, f)).filter((f) => statSync2(f).isFile());
7899
7958
  const result = { added: 0, updated: 0, unchanged: 0, skipped: [] };
7900
- const home = homedir4();
7959
+ const home = homedir5();
7901
7960
  const allConfigs = await store.listConfigs();
7902
7961
  for (const file of files) {
7903
7962
  if (shouldSkip(file)) {
@@ -7931,7 +7990,7 @@ async function syncFromDir(dir, opts = {}) {
7931
7990
  }
7932
7991
  async function syncToDir(dir, opts = {}) {
7933
7992
  const store = opts.store ?? resolveConfigStore();
7934
- const home = homedir4();
7993
+ const home = homedir5();
7935
7994
  const absDir = expandPath(dir);
7936
7995
  const normalized = dir.startsWith("~/") ? dir : absDir.replace(home, "~");
7937
7996
  const configs = (await store.listConfigs()).filter((c) => c.target_path && (c.target_path.startsWith(normalized) || c.target_path.startsWith(absDir)));
@@ -7955,7 +8014,7 @@ async function syncToDir(dir, opts = {}) {
7955
8014
  }
7956
8015
  function walkDir(dir, files = []) {
7957
8016
  for (const entry of readdirSync2(dir, { withFileTypes: true })) {
7958
- const full = join8(dir, entry.name);
8017
+ const full = join9(dir, entry.name);
7959
8018
  if (shouldSkip(full))
7960
8019
  continue;
7961
8020
  if (entry.isDirectory())
@@ -7977,7 +8036,7 @@ var init_sync_dir = __esm(() => {
7977
8036
  var require_package = __commonJS((exports, module) => {
7978
8037
  module.exports = {
7979
8038
  name: "@hasna/instructions",
7980
- version: "0.4.36",
8039
+ version: "0.4.42",
7981
8040
  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.",
7982
8041
  type: "module",
7983
8042
  main: "dist/index.js",
@@ -7997,6 +8056,7 @@ var require_package = __commonJS((exports, module) => {
7997
8056
  },
7998
8057
  files: [
7999
8058
  "dist",
8059
+ "assets/skills/inbox/SKILL.md",
8000
8060
  "dashboard/dist",
8001
8061
  "LICENSE",
8002
8062
  "README.md"
@@ -8010,14 +8070,15 @@ var require_package = __commonJS((exports, module) => {
8010
8070
  "generate:sdk": "bun run scripts/generate-sdk.ts",
8011
8071
  "kit:check": "bunx @hasna/contracts vendor-kit --check",
8012
8072
  typecheck: "tsc --noEmit",
8013
- test: "bun test",
8014
- "check:package-secrets": "bun run src/cli/index.tsx package-manager-scan --fail-on-findings --home .",
8073
+ test: "env -u HASNA_INSTRUCTIONS_API_URL -u HASNA_INSTRUCTIONS_API_KEY bun test",
8074
+ "check:package-secrets": "bun run src/cli/index.tsx package-manager-scan --fail-on-findings .",
8015
8075
  "dev:cli": "bun run src/cli/index.tsx",
8016
8076
  "dev:mcp": "bun run src/mcp/index.ts",
8017
8077
  "dev:serve": "bun run src/server/index.ts",
8018
8078
  seed: "bun run scripts/seed.ts",
8019
8079
  prepublishOnly: "bun run scripts/check-publish-hold.ts && bun run build",
8020
- postinstall: "mkdir -p $HOME/.hasna/instructions $HOME/.hasna/instructions/backups 2>/dev/null || true"
8080
+ postinstall: "mkdir -p $HOME/.hasna/instructions $HOME/.hasna/instructions/backups 2>/dev/null || true",
8081
+ prepack: "bun run build"
8021
8082
  },
8022
8083
  keywords: [
8023
8084
  "instructions",
@@ -8051,8 +8112,8 @@ var require_package = __commonJS((exports, module) => {
8051
8112
  author: "Andrei Hasna <andrei@hasna.com>",
8052
8113
  license: "Apache-2.0",
8053
8114
  dependencies: {
8054
- "@hasna/contracts": "0.4.2",
8055
- "@hasna/events": "^0.1.6",
8115
+ "@hasna/contracts": "0.13.3",
8116
+ "@hasna/events": "^0.1.16",
8056
8117
  "@modelcontextprotocol/sdk": "^1.12.1",
8057
8118
  chalk: "^5.4.1",
8058
8119
  commander: "^13.1.0",
@@ -8066,6 +8127,7 @@ var require_package = __commonJS((exports, module) => {
8066
8127
  "@types/bun": "^1.2.4",
8067
8128
  "@types/pg": "^8.11.11",
8068
8129
  "@types/react": "^18.3.18",
8130
+ "bun-types": "1.3.14",
8069
8131
  typescript: "^5.7.3"
8070
8132
  }
8071
8133
  };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cloud-auth.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloud-auth.test.d.ts","sourceRoot":"","sources":["../../src/server/cloud-auth.test.ts"],"names":[],"mappings":""}