@hasna/instructions 0.4.35 → 0.4.39

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 (35) hide show
  1. package/README.md +4 -2
  2. package/assets/skills/inbox/SKILL.md +86 -0
  3. package/dashboard/README.md +34 -70
  4. package/dist/cli/index.js +1136 -526
  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/db/configs.d.ts.map +1 -1
  8. package/dist/generated/storage-kit/index.d.ts +1 -1
  9. package/dist/index.d.ts +3 -1
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +1276 -754
  12. package/dist/lib/apply.d.ts.map +1 -1
  13. package/dist/lib/cursor-authority.d.ts +36 -3
  14. package/dist/lib/cursor-authority.d.ts.map +1 -1
  15. package/dist/lib/managed-skill-runtimes.d.ts +80 -0
  16. package/dist/lib/managed-skill-runtimes.d.ts.map +1 -0
  17. package/dist/lib/managed-skill-runtimes.test.d.ts +2 -0
  18. package/dist/lib/managed-skill-runtimes.test.d.ts.map +1 -0
  19. package/dist/lib/raw-store-root.d.ts +17 -0
  20. package/dist/lib/raw-store-root.d.ts.map +1 -0
  21. package/dist/lib/session-apply.d.ts.map +1 -1
  22. package/dist/lib/session-authority.d.ts +27 -0
  23. package/dist/lib/session-authority.d.ts.map +1 -0
  24. package/dist/lib/session-authority.test.d.ts +2 -0
  25. package/dist/lib/session-authority.test.d.ts.map +1 -0
  26. package/dist/lib/session-render.d.ts +5 -3
  27. package/dist/lib/session-render.d.ts.map +1 -1
  28. package/dist/mcp/index.js +290 -233
  29. package/dist/server/index.js +425 -231
  30. package/dist/status.d.ts +11 -1
  31. package/dist/status.d.ts.map +1 -1
  32. package/dist/storage/cloud-store.d.ts.map +1 -1
  33. package/dist/storage/cloud-store.test.d.ts +2 -0
  34. package/dist/storage/cloud-store.test.d.ts.map +1 -0
  35. package/package.json +9 -7
package/dist/cli/index.js CHANGED
@@ -20,12 +20,14 @@ var __toESM = (mod, isNodeMode, target) => {
20
20
  }
21
21
  target = mod != null ? __create(__getProtoOf(mod)) : {};
22
22
  const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
23
- for (let key of __getOwnPropNames(mod))
24
- if (!__hasOwnProp.call(to, key))
25
- __defProp(to, key, {
26
- get: __accessProp.bind(mod, key),
27
- enumerable: true
28
- });
23
+ if (mod && typeof mod === "object" || typeof mod === "function") {
24
+ for (let key of __getOwnPropNames(mod))
25
+ if (!__hasOwnProp.call(to, key))
26
+ __defProp(to, key, {
27
+ get: __accessProp.bind(mod, key),
28
+ enumerable: true
29
+ });
30
+ }
29
31
  if (canCache)
30
32
  cache.set(mod, to);
31
33
  return to;
@@ -48,7 +50,7 @@ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
48
50
  var __require = import.meta.require;
49
51
 
50
52
  // ../../node_modules/.bun/commander@13.1.0/node_modules/commander/lib/error.js
51
- var require_error = __commonJS((exports) => {
53
+ var require_error = __commonJS(function(exports) {
52
54
  class CommanderError extends Error {
53
55
  constructor(exitCode, code, message) {
54
56
  super(message);
@@ -72,7 +74,7 @@ var require_error = __commonJS((exports) => {
72
74
  });
73
75
 
74
76
  // ../../node_modules/.bun/commander@13.1.0/node_modules/commander/lib/argument.js
75
- var require_argument = __commonJS((exports) => {
77
+ var require_argument = __commonJS(function(exports) {
76
78
  var { InvalidArgumentError } = require_error();
77
79
 
78
80
  class Argument {
@@ -151,7 +153,7 @@ var require_argument = __commonJS((exports) => {
151
153
  });
152
154
 
153
155
  // ../../node_modules/.bun/commander@13.1.0/node_modules/commander/lib/help.js
154
- var require_help = __commonJS((exports) => {
156
+ var require_help = __commonJS(function(exports) {
155
157
  var { humanReadableArgName } = require_argument();
156
158
 
157
159
  class Help {
@@ -501,7 +503,7 @@ ${itemIndentStr}`);
501
503
  });
502
504
 
503
505
  // ../../node_modules/.bun/commander@13.1.0/node_modules/commander/lib/option.js
504
- var require_option = __commonJS((exports) => {
506
+ var require_option = __commonJS(function(exports) {
505
507
  var { InvalidArgumentError } = require_error();
506
508
 
507
509
  class Option {
@@ -679,7 +681,7 @@ var require_option = __commonJS((exports) => {
679
681
  });
680
682
 
681
683
  // ../../node_modules/.bun/commander@13.1.0/node_modules/commander/lib/suggestSimilar.js
682
- var require_suggestSimilar = __commonJS((exports) => {
684
+ var require_suggestSimilar = __commonJS(function(exports) {
683
685
  var maxDistance = 3;
684
686
  function editDistance(a, b) {
685
687
  if (Math.abs(a.length - b.length) > maxDistance)
@@ -752,7 +754,7 @@ var require_suggestSimilar = __commonJS((exports) => {
752
754
  });
753
755
 
754
756
  // ../../node_modules/.bun/commander@13.1.0/node_modules/commander/lib/command.js
755
- var require_command = __commonJS((exports) => {
757
+ var require_command = __commonJS(function(exports) {
756
758
  var EventEmitter = __require("events").EventEmitter;
757
759
  var childProcess = __require("child_process");
758
760
  var path = __require("path");
@@ -993,7 +995,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
993
995
  this._exitCallback = (err) => {
994
996
  if (err.code !== "commander.executeSubCommandAsync") {
995
997
  throw err;
996
- } else {}
998
+ }
997
999
  };
998
1000
  }
999
1001
  return this;
@@ -2062,7 +2064,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2062
2064
  });
2063
2065
 
2064
2066
  // ../../node_modules/.bun/commander@13.1.0/node_modules/commander/index.js
2065
- var require_commander = __commonJS((exports) => {
2067
+ var require_commander = __commonJS(function(exports) {
2066
2068
  var { Argument } = require_argument();
2067
2069
  var { Command } = require_command();
2068
2070
  var { CommanderError, InvalidArgumentError } = require_error();
@@ -2160,19 +2162,27 @@ var init_retired_storage_mode = __esm(() => {
2160
2162
  ];
2161
2163
  });
2162
2164
 
2165
+ // src/lib/raw-store-root.ts
2166
+ import { homedir as homedir2 } from "os";
2167
+ import { join as join2, resolve } from "path";
2168
+ function getRawStoreRoot() {
2169
+ return resolve(process.env[RAW_STORE_ROOT_ENV] || join2(process.env["HOME"] || homedir2(), ".hasna", "instructions"));
2170
+ }
2171
+ var RAW_STORE_ROOT_ENV = "HASNA_CONFIGS_HOME";
2172
+ var init_raw_store_root = () => {};
2173
+
2163
2174
  // src/db/database.ts
2164
2175
  import { Database } from "bun:sqlite";
2165
2176
  import { existsSync as existsSync2, mkdirSync, rmSync } from "fs";
2166
- import { join as join2 } from "path";
2177
+ import { join as join3 } from "path";
2167
2178
  import { randomUUID as randomUUID3 } from "crypto";
2168
2179
  function getDbPath() {
2169
2180
  if (process.env["HASNA_INSTRUCTIONS_DB_PATH"]) {
2170
2181
  return process.env["HASNA_INSTRUCTIONS_DB_PATH"];
2171
2182
  }
2172
- const home = process.env["HOME"] || process.env["USERPROFILE"] || "~";
2173
- const dir = join2(home, ".hasna", "instructions");
2183
+ const dir = getRawStoreRoot();
2174
2184
  mkdirSync(dir, { recursive: true });
2175
- return join2(dir, "instructions.db");
2185
+ return join3(dir, "instructions.db");
2176
2186
  }
2177
2187
  function uuid() {
2178
2188
  return randomUUID3();
@@ -2270,6 +2280,7 @@ function insertFeedback(input, db) {
2270
2280
  var MIGRATIONS, _db = null;
2271
2281
  var init_database = __esm(() => {
2272
2282
  init_retired_storage_mode();
2283
+ init_raw_store_root();
2273
2284
  MIGRATIONS = [
2274
2285
  `
2275
2286
  CREATE TABLE IF NOT EXISTS configs (
@@ -2354,6 +2365,37 @@ var init_database = __esm(() => {
2354
2365
  ];
2355
2366
  });
2356
2367
 
2368
+ // src/db/snapshots.ts
2369
+ function createSnapshot(configId, content, version, db) {
2370
+ const d = db || getDatabase();
2371
+ const id = uuid();
2372
+ const ts = now2();
2373
+ d.run("INSERT INTO config_snapshots (id, config_id, content, version, created_at) VALUES (?, ?, ?, ?, ?)", [id, configId, content, version, ts]);
2374
+ return { id, config_id: configId, content, version, created_at: ts };
2375
+ }
2376
+ function listSnapshots(configId, db) {
2377
+ const d = db || getDatabase();
2378
+ return d.query("SELECT * FROM config_snapshots WHERE config_id = ? ORDER BY version DESC").all(configId);
2379
+ }
2380
+ function getSnapshot(id, db) {
2381
+ const d = db || getDatabase();
2382
+ return d.query("SELECT * FROM config_snapshots WHERE id = ?").get(id);
2383
+ }
2384
+ function getSnapshotByVersion(configId, version, db) {
2385
+ const d = db || getDatabase();
2386
+ return d.query("SELECT * FROM config_snapshots WHERE config_id = ? AND version = ?").get(configId, version);
2387
+ }
2388
+ function pruneSnapshots(configId, keep = 10, db) {
2389
+ const d = db || getDatabase();
2390
+ const result = d.run(`DELETE FROM config_snapshots WHERE config_id = ? AND id NOT IN (
2391
+ SELECT id FROM config_snapshots WHERE config_id = ? ORDER BY version DESC LIMIT ?
2392
+ )`, [configId, configId, keep]);
2393
+ return result.changes;
2394
+ }
2395
+ var init_snapshots = __esm(() => {
2396
+ init_database();
2397
+ });
2398
+
2357
2399
  // src/db/configs.ts
2358
2400
  function rowToConfig(row) {
2359
2401
  let outputs = [];
@@ -2392,25 +2434,28 @@ function createConfig(input, db) {
2392
2434
  const slug = uniqueSlug(input.name, d);
2393
2435
  const tags = JSON.stringify(input.tags || []);
2394
2436
  const outputs = JSON.stringify(input.outputs || []);
2395
- 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)
2396
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, ?, ?, NULL)`, [
2397
- id,
2398
- input.name,
2399
- slug,
2400
- input.kind ?? "file",
2401
- input.category,
2402
- input.agent ?? "global",
2403
- input.target_path ?? null,
2404
- outputs,
2405
- input.format ?? "text",
2406
- input.content,
2407
- input.description ?? null,
2408
- tags,
2409
- input.is_template ? 1 : 0,
2410
- ts,
2411
- ts
2412
- ]);
2413
- return getConfig(id, d);
2437
+ return d.transaction(() => {
2438
+ 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)
2439
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, ?, ?, NULL)`, [
2440
+ id,
2441
+ input.name,
2442
+ slug,
2443
+ input.kind ?? "file",
2444
+ input.category,
2445
+ input.agent ?? "global",
2446
+ input.target_path ?? null,
2447
+ outputs,
2448
+ input.format ?? "text",
2449
+ input.content,
2450
+ input.description ?? null,
2451
+ tags,
2452
+ input.is_template ? 1 : 0,
2453
+ ts,
2454
+ ts
2455
+ ]);
2456
+ createSnapshot(id, input.content, 1, d);
2457
+ return getConfig(id, d);
2458
+ })();
2414
2459
  }
2415
2460
  function getConfig(idOrSlug, db) {
2416
2461
  const d = db || getDatabase();
@@ -2515,9 +2560,13 @@ function updateConfig(idOrSlug, input, db) {
2515
2560
  updates.push("synced_at = ?");
2516
2561
  params.push(input.synced_at);
2517
2562
  }
2518
- params.push(existing.id);
2519
- d.run(`UPDATE configs SET ${updates.join(", ")} WHERE id = ?`, params);
2520
- return getConfigById(existing.id, d);
2563
+ return d.transaction(() => {
2564
+ params.push(existing.id);
2565
+ d.run(`UPDATE configs SET ${updates.join(", ")} WHERE id = ?`, params);
2566
+ const updated = getConfigById(existing.id, d);
2567
+ createSnapshot(updated.id, updated.content, updated.version, d);
2568
+ return updated;
2569
+ })();
2521
2570
  }
2522
2571
  function deleteConfig(idOrSlug, db) {
2523
2572
  const d = db || getDatabase();
@@ -2537,16 +2586,17 @@ function getConfigStats(db) {
2537
2586
  var init_configs = __esm(() => {
2538
2587
  init_types();
2539
2588
  init_database();
2589
+ init_snapshots();
2540
2590
  });
2541
2591
 
2542
2592
  // src/lib/template.ts
2543
2593
  var exports_template = {};
2544
2594
  __export(exports_template, {
2545
- renderTemplatePreview: () => renderTemplatePreview,
2546
- renderTemplate: () => renderTemplate,
2547
- parseTemplateVars: () => parseTemplateVars,
2595
+ extractTemplateVars: () => extractTemplateVars,
2548
2596
  isTemplate: () => isTemplate,
2549
- extractTemplateVars: () => extractTemplateVars
2597
+ parseTemplateVars: () => parseTemplateVars,
2598
+ renderTemplate: () => renderTemplate,
2599
+ renderTemplatePreview: () => renderTemplatePreview
2550
2600
  });
2551
2601
  function parseTemplateVars(content) {
2552
2602
  const names = new Set;
@@ -2610,9 +2660,9 @@ var init_template = __esm(() => {
2610
2660
  });
2611
2661
 
2612
2662
  // src/lib/machine.ts
2613
- import { arch as currentArch, homedir as homedir2, hostname as currentHostname, type as currentOsType } from "os";
2663
+ import { arch as currentArch, homedir as homedir3, hostname as currentHostname, type as currentOsType } from "os";
2614
2664
  import { existsSync as existsSync3 } from "fs";
2615
- import { join as join3 } from "path";
2665
+ import { join as join4 } from "path";
2616
2666
  function normalizeOsFamily(os) {
2617
2667
  const value = (os ?? "").trim().toLowerCase();
2618
2668
  if (value === "darwin" || value === "macos" || value === "mac" || value === "osx")
@@ -2624,11 +2674,11 @@ function normalizeOsFamily(os) {
2624
2674
  return value || "unknown";
2625
2675
  }
2626
2676
  function detectMachineContext(overrides = {}) {
2627
- const homeDir = overrides.home_dir ?? process.env["CONFIGS_HOME"] ?? process.env["HOME"] ?? homedir2();
2677
+ const homeDir = overrides.home_dir ?? process.env["CONFIGS_HOME"] ?? process.env["HOME"] ?? homedir3();
2628
2678
  const os = overrides.os ?? currentOsType();
2629
2679
  const osFamily = normalizeOsFamily(os);
2630
- const bunBinDir = overrides.bun_bin_dir ?? join3(homeDir, ".bun", "bin");
2631
- const defaultBunPath = osFamily === "macos" && existsSync3(BREW_BUN_PATH) ? BREW_BUN_PATH : join3(bunBinDir, "bun");
2680
+ const bunBinDir = overrides.bun_bin_dir ?? join4(homeDir, ".bun", "bin");
2681
+ const defaultBunPath = osFamily === "macos" && existsSync3(BREW_BUN_PATH) ? BREW_BUN_PATH : join4(bunBinDir, "bun");
2632
2682
  return {
2633
2683
  id: "current-machine",
2634
2684
  hostname: overrides.hostname ?? currentHostname(),
@@ -2638,10 +2688,10 @@ function detectMachineContext(overrides = {}) {
2638
2688
  created_at: "",
2639
2689
  os_family: osFamily,
2640
2690
  home_dir: homeDir,
2641
- workspace_root: overrides.workspace_root ?? join3(homeDir, osFamily === "macos" ? "Workspace" : "workspace"),
2691
+ workspace_root: overrides.workspace_root ?? join4(homeDir, osFamily === "macos" ? "Workspace" : "workspace"),
2642
2692
  bun_bin_dir: bunBinDir,
2643
2693
  bun_path: overrides.bun_path ?? defaultBunPath,
2644
- path_prefix: overrides.path_prefix ?? (osFamily === "macos" ? `${join3("/opt", "homebrew", "bin")}:${bunBinDir}` : bunBinDir)
2694
+ path_prefix: overrides.path_prefix ?? (osFamily === "macos" ? `${join4("/opt", "homebrew", "bin")}:${bunBinDir}` : bunBinDir)
2645
2695
  };
2646
2696
  }
2647
2697
  function machineContextToVariables(machine) {
@@ -6906,113 +6956,113 @@ var init_types2 = __esm(() => {
6906
6956
  // ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/external.js
6907
6957
  var exports_external = {};
6908
6958
  __export(exports_external, {
6909
- void: () => voidType,
6910
- util: () => util,
6911
- unknown: () => unknownType,
6912
- union: () => unionType,
6913
- undefined: () => undefinedType,
6914
- tuple: () => tupleType,
6915
- transformer: () => effectsType,
6916
- symbol: () => symbolType,
6917
- string: () => stringType,
6918
- strictObject: () => strictObjectType,
6919
- setErrorMap: () => setErrorMap,
6920
- set: () => setType,
6921
- record: () => recordType,
6922
- quotelessJson: () => quotelessJson,
6923
- promise: () => promiseType,
6924
- preprocess: () => preprocessType,
6925
- pipeline: () => pipelineType,
6926
- ostring: () => ostring,
6927
- optional: () => optionalType,
6928
- onumber: () => onumber,
6929
- oboolean: () => oboolean,
6930
- objectUtil: () => objectUtil,
6931
- object: () => objectType,
6932
- number: () => numberType,
6933
- nullable: () => nullableType,
6934
- null: () => nullType,
6935
- never: () => neverType,
6936
- nativeEnum: () => nativeEnumType,
6937
- nan: () => nanType,
6938
- map: () => mapType,
6939
- makeIssue: () => makeIssue,
6940
- literal: () => literalType,
6941
- lazy: () => lazyType,
6942
- late: () => late,
6943
- isValid: () => isValid,
6944
- isDirty: () => isDirty,
6945
- isAsync: () => isAsync,
6946
- isAborted: () => isAborted,
6947
- intersection: () => intersectionType,
6948
- instanceof: () => instanceOfType,
6949
- getParsedType: () => getParsedType,
6950
- getErrorMap: () => getErrorMap,
6951
- function: () => functionType,
6952
- enum: () => enumType,
6953
- effect: () => effectsType,
6954
- discriminatedUnion: () => discriminatedUnionType,
6955
- defaultErrorMap: () => en_default,
6956
- datetimeRegex: () => datetimeRegex,
6957
- date: () => dateType,
6958
- custom: () => custom,
6959
- coerce: () => coerce,
6960
- boolean: () => booleanType,
6961
- bigint: () => bigIntType,
6962
- array: () => arrayType,
6963
- any: () => anyType,
6964
- addIssueToContext: () => addIssueToContext,
6965
- ZodVoid: () => ZodVoid,
6966
- ZodUnknown: () => ZodUnknown,
6967
- ZodUnion: () => ZodUnion,
6968
- ZodUndefined: () => ZodUndefined,
6969
- ZodType: () => ZodType,
6970
- ZodTuple: () => ZodTuple,
6971
- ZodTransformer: () => ZodEffects,
6972
- ZodSymbol: () => ZodSymbol,
6973
- ZodString: () => ZodString,
6974
- ZodSet: () => ZodSet,
6975
- ZodSchema: () => ZodType,
6976
- ZodRecord: () => ZodRecord,
6977
- ZodReadonly: () => ZodReadonly,
6978
- ZodPromise: () => ZodPromise,
6979
- ZodPipeline: () => ZodPipeline,
6980
- ZodParsedType: () => ZodParsedType,
6981
- ZodOptional: () => ZodOptional,
6982
- ZodObject: () => ZodObject,
6983
- ZodNumber: () => ZodNumber,
6984
- ZodNullable: () => ZodNullable,
6985
- ZodNull: () => ZodNull,
6986
- ZodNever: () => ZodNever,
6987
- ZodNativeEnum: () => ZodNativeEnum,
6988
- ZodNaN: () => ZodNaN,
6989
- ZodMap: () => ZodMap,
6990
- ZodLiteral: () => ZodLiteral,
6991
- ZodLazy: () => ZodLazy,
6992
- ZodIssueCode: () => ZodIssueCode,
6993
- ZodIntersection: () => ZodIntersection,
6994
- ZodFunction: () => ZodFunction,
6995
- ZodFirstPartyTypeKind: () => ZodFirstPartyTypeKind,
6996
- ZodError: () => ZodError,
6997
- ZodEnum: () => ZodEnum,
6998
- ZodEffects: () => ZodEffects,
6999
- ZodDiscriminatedUnion: () => ZodDiscriminatedUnion,
7000
- ZodDefault: () => ZodDefault,
7001
- ZodDate: () => ZodDate,
7002
- ZodCatch: () => ZodCatch,
7003
- ZodBranded: () => ZodBranded,
7004
- ZodBoolean: () => ZodBoolean,
7005
- ZodBigInt: () => ZodBigInt,
7006
- ZodArray: () => ZodArray,
7007
- ZodAny: () => ZodAny,
7008
- Schema: () => ZodType,
7009
- ParseStatus: () => ParseStatus,
7010
- OK: () => OK,
7011
- NEVER: () => NEVER,
7012
- INVALID: () => INVALID,
7013
- EMPTY_PATH: () => EMPTY_PATH,
6959
+ BRAND: () => BRAND,
7014
6960
  DIRTY: () => DIRTY,
7015
- BRAND: () => BRAND
6961
+ EMPTY_PATH: () => EMPTY_PATH,
6962
+ INVALID: () => INVALID,
6963
+ NEVER: () => NEVER,
6964
+ OK: () => OK,
6965
+ ParseStatus: () => ParseStatus,
6966
+ Schema: () => ZodType,
6967
+ ZodAny: () => ZodAny,
6968
+ ZodArray: () => ZodArray,
6969
+ ZodBigInt: () => ZodBigInt,
6970
+ ZodBoolean: () => ZodBoolean,
6971
+ ZodBranded: () => ZodBranded,
6972
+ ZodCatch: () => ZodCatch,
6973
+ ZodDate: () => ZodDate,
6974
+ ZodDefault: () => ZodDefault,
6975
+ ZodDiscriminatedUnion: () => ZodDiscriminatedUnion,
6976
+ ZodEffects: () => ZodEffects,
6977
+ ZodEnum: () => ZodEnum,
6978
+ ZodError: () => ZodError,
6979
+ ZodFirstPartyTypeKind: () => ZodFirstPartyTypeKind,
6980
+ ZodFunction: () => ZodFunction,
6981
+ ZodIntersection: () => ZodIntersection,
6982
+ ZodIssueCode: () => ZodIssueCode,
6983
+ ZodLazy: () => ZodLazy,
6984
+ ZodLiteral: () => ZodLiteral,
6985
+ ZodMap: () => ZodMap,
6986
+ ZodNaN: () => ZodNaN,
6987
+ ZodNativeEnum: () => ZodNativeEnum,
6988
+ ZodNever: () => ZodNever,
6989
+ ZodNull: () => ZodNull,
6990
+ ZodNullable: () => ZodNullable,
6991
+ ZodNumber: () => ZodNumber,
6992
+ ZodObject: () => ZodObject,
6993
+ ZodOptional: () => ZodOptional,
6994
+ ZodParsedType: () => ZodParsedType,
6995
+ ZodPipeline: () => ZodPipeline,
6996
+ ZodPromise: () => ZodPromise,
6997
+ ZodReadonly: () => ZodReadonly,
6998
+ ZodRecord: () => ZodRecord,
6999
+ ZodSchema: () => ZodType,
7000
+ ZodSet: () => ZodSet,
7001
+ ZodString: () => ZodString,
7002
+ ZodSymbol: () => ZodSymbol,
7003
+ ZodTransformer: () => ZodEffects,
7004
+ ZodTuple: () => ZodTuple,
7005
+ ZodType: () => ZodType,
7006
+ ZodUndefined: () => ZodUndefined,
7007
+ ZodUnion: () => ZodUnion,
7008
+ ZodUnknown: () => ZodUnknown,
7009
+ ZodVoid: () => ZodVoid,
7010
+ addIssueToContext: () => addIssueToContext,
7011
+ any: () => anyType,
7012
+ array: () => arrayType,
7013
+ bigint: () => bigIntType,
7014
+ boolean: () => booleanType,
7015
+ coerce: () => coerce,
7016
+ custom: () => custom,
7017
+ date: () => dateType,
7018
+ datetimeRegex: () => datetimeRegex,
7019
+ defaultErrorMap: () => en_default,
7020
+ discriminatedUnion: () => discriminatedUnionType,
7021
+ effect: () => effectsType,
7022
+ enum: () => enumType,
7023
+ function: () => functionType,
7024
+ getErrorMap: () => getErrorMap,
7025
+ getParsedType: () => getParsedType,
7026
+ instanceof: () => instanceOfType,
7027
+ intersection: () => intersectionType,
7028
+ isAborted: () => isAborted,
7029
+ isAsync: () => isAsync,
7030
+ isDirty: () => isDirty,
7031
+ isValid: () => isValid,
7032
+ late: () => late,
7033
+ lazy: () => lazyType,
7034
+ literal: () => literalType,
7035
+ makeIssue: () => makeIssue,
7036
+ map: () => mapType,
7037
+ nan: () => nanType,
7038
+ nativeEnum: () => nativeEnumType,
7039
+ never: () => neverType,
7040
+ null: () => nullType,
7041
+ nullable: () => nullableType,
7042
+ number: () => numberType,
7043
+ object: () => objectType,
7044
+ objectUtil: () => objectUtil,
7045
+ oboolean: () => oboolean,
7046
+ onumber: () => onumber,
7047
+ optional: () => optionalType,
7048
+ ostring: () => ostring,
7049
+ pipeline: () => pipelineType,
7050
+ preprocess: () => preprocessType,
7051
+ promise: () => promiseType,
7052
+ quotelessJson: () => quotelessJson,
7053
+ record: () => recordType,
7054
+ set: () => setType,
7055
+ setErrorMap: () => setErrorMap,
7056
+ strictObject: () => strictObjectType,
7057
+ string: () => stringType,
7058
+ symbol: () => symbolType,
7059
+ transformer: () => effectsType,
7060
+ tuple: () => tupleType,
7061
+ undefined: () => undefinedType,
7062
+ union: () => unionType,
7063
+ unknown: () => unknownType,
7064
+ util: () => util,
7065
+ void: () => voidType
7016
7066
  });
7017
7067
  var init_external = __esm(() => {
7018
7068
  init_errors();
@@ -7265,7 +7315,7 @@ import {
7265
7315
  statSync,
7266
7316
  writeFileSync
7267
7317
  } from "fs";
7268
- import { basename, dirname, isAbsolute, join as join4, parse, relative, resolve } from "path";
7318
+ import { basename, dirname, isAbsolute, join as join5, parse, relative, resolve as resolve2 } from "path";
7269
7319
  function managedObservationMaxBytes(relativePath) {
7270
7320
  return SESSION_MANAGED_OUTPUT_PATHS.includes(relativePath) ? SESSION_MANAGED_OUTPUT_MAX_BYTES : FOREIGN_INPUT_MAX_BYTES;
7271
7321
  }
@@ -7436,7 +7486,7 @@ function composeProjectContextSessionRender(input) {
7436
7486
  if (currentMarkers.block.id !== cache.project_id || currentMarkers.block.revision !== cache.revision || currentMarkers.block.hash !== cache.hash) {
7437
7487
  throw new ProjectContextError("MANAGED_BLOCK_CONFLICT", "project-context provider markers differ from the durable cache");
7438
7488
  }
7439
- const plannedIndexes = input.files.filter((file) => file.role === "index" && resolve(file.path) === paths.target);
7489
+ const plannedIndexes = input.files.filter((file) => file.role === "index" && resolve2(file.path) === paths.target);
7440
7490
  if (plannedIndexes.length !== 1) {
7441
7491
  throw new ProjectContextError("PROJECT_CONTEXT_MANIFEST_INVALID", "session renderer does not own the selected project-context provider target");
7442
7492
  }
@@ -7494,7 +7544,7 @@ function withProjectContextSessionGuard(guard, action, options = {}) {
7494
7544
  verify();
7495
7545
  return action(null);
7496
7546
  }
7497
- const lockPath = resolve(validated.workspace_root, ...PROJECT_CONTEXT_LOCK_PATH.split("/"));
7547
+ const lockPath = resolve2(validated.workspace_root, ...PROJECT_CONTEXT_LOCK_PATH.split("/"));
7498
7548
  const lock = acquireWorkspaceLock(validated.workspace_root, lockPath);
7499
7549
  try {
7500
7550
  verify();
@@ -7520,7 +7570,7 @@ function validateProjectContextSessionGuard(guard) {
7520
7570
  if (!isRecord(observed) || typeof observed.path !== "string") {
7521
7571
  throw new ProjectContextError("PROJECT_CONTEXT_SESSION_STALE", "session project-context guard contains malformed hash metadata");
7522
7572
  }
7523
- const path = resolve(observed.path);
7573
+ const path = resolve2(observed.path);
7524
7574
  if (!allowedPaths.has(path) || observedPaths.has(path)) {
7525
7575
  throw new ProjectContextError("PROJECT_CONTEXT_SESSION_STALE", "session project-context guard contains an unexpected or duplicate path");
7526
7576
  }
@@ -7542,7 +7592,7 @@ function validateProjectContextSessionGuard(guard) {
7542
7592
  function applyProjectContext(options) {
7543
7593
  const workspaceRoot = assertSafeWorkspaceRoot(options.workspace_root);
7544
7594
  const now3 = options.now ?? new Date;
7545
- const lockPath = resolve(workspaceRoot, ...PROJECT_CONTEXT_LOCK_PATH.split("/"));
7595
+ const lockPath = resolve2(workspaceRoot, ...PROJECT_CONTEXT_LOCK_PATH.split("/"));
7546
7596
  const lock = options.dry_run ? null : acquireWorkspaceLock(workspaceRoot, lockPath, options.test_hooks?.after_lock_open, options.test_hooks?.before_stale_lock_remove, options.test_hooks?.process_start_identity);
7547
7597
  try {
7548
7598
  const resolved = resolveBundleForApply(options, workspaceRoot, now3);
@@ -7689,7 +7739,7 @@ function resolveBundleForApply(options, workspaceRoot, now3) {
7689
7739
  if (!options.expected_project_id) {
7690
7740
  throw new ProjectContextError("PROJECT_CONTEXT_CACHE_ID_REQUIRED", "expected_project_id is required for stale-cache fallback");
7691
7741
  }
7692
- const cachePath = resolve(workspaceRoot, ...PROJECT_CONTEXT_CACHE_PATH.split("/"));
7742
+ const cachePath = resolve2(workspaceRoot, ...PROJECT_CONTEXT_CACHE_PATH.split("/"));
7693
7743
  const cache = readProjectContextCache(cachePath, workspaceRoot);
7694
7744
  if (!cache)
7695
7745
  throw new ProjectContextError("PROJECT_CONTEXT_CACHE_MISSING", "no last-known-good project context cache exists");
@@ -8045,7 +8095,7 @@ function buildManifest(plan, now3) {
8045
8095
  function buildSessionCompatibilityManifest(plan, now3) {
8046
8096
  const paths = runtimePaths(plan.workspace_root, plan.runtime);
8047
8097
  const tool = manifestTool(plan.runtime);
8048
- const targetHome = plan.runtime === "codewith" ? resolve(plan.workspace_root, ".codewith") : plan.workspace_root;
8098
+ const targetHome = plan.runtime === "codewith" ? resolve2(plan.workspace_root, ".codewith") : plan.workspace_root;
8049
8099
  const targetRelativePath = sessionTargetRelativePath(plan.runtime);
8050
8100
  const existing = existsSync4(paths.sessionManifest) ? readSessionManifestRecord(paths.sessionManifest, plan.workspace_root) : {
8051
8101
  schema: SESSION_RENDER_SCHEMA,
@@ -8067,7 +8117,7 @@ function buildSessionCompatibilityManifest(plan, now3) {
8067
8117
  throw new ProjectContextError("PROJECT_CONTEXT_MANIFEST_INVALID", "provider session manifest is malformed or incompatible");
8068
8118
  }
8069
8119
  const existingTargetHome = safeLegacyMetadataString(existing["targetHome"], null);
8070
- if (existingTargetHome !== null && resolve(existingTargetHome) !== targetHome) {
8120
+ if (existingTargetHome !== null && resolve2(existingTargetHome) !== targetHome) {
8071
8121
  throw new ProjectContextError("PROJECT_CONTEXT_MANIFEST_INVALID", "provider session manifest targets a different workspace");
8072
8122
  }
8073
8123
  const sources = sanitizeLegacySources(existing["sources"]).filter((source) => source["id"] !== "project-context-bundle");
@@ -8353,9 +8403,9 @@ function writeMetadataSnapshot(plan, now3) {
8353
8403
  const previous = readProjectContextManifest(plan.manifest_path, plan.workspace_root);
8354
8404
  if (!previous || previous.projectContext.revision === plan.bundle.revision && previous.projectContext.hash === plan.bundle.hash)
8355
8405
  return null;
8356
- const snapshotDir = resolve(plan.workspace_root, ...PROJECT_CONTEXT_SNAPSHOT_DIR.split("/"));
8406
+ const snapshotDir = resolve2(plan.workspace_root, ...PROJECT_CONTEXT_SNAPSHOT_DIR.split("/"));
8357
8407
  ensureSafeDirectory(snapshotDir, plan.workspace_root, 448);
8358
- const snapshotPath = resolve(snapshotDir, `${safeFilename(previous.projectContext.revision)}-${previous.projectContext.hash.slice(-12)}.json`);
8408
+ const snapshotPath = resolve2(snapshotDir, `${safeFilename(previous.projectContext.revision)}-${previous.projectContext.hash.slice(-12)}.json`);
8359
8409
  const snapshot = {
8360
8410
  schema: "hasna.configs.session-render-snapshot/v1",
8361
8411
  kind: "project-context-metadata",
@@ -8371,8 +8421,8 @@ function writeMetadataSnapshot(plan, now3) {
8371
8421
  return snapshotPath;
8372
8422
  }
8373
8423
  function metadataSnapshotMatchesManifest(plan, manifest) {
8374
- const snapshotDir = resolve(plan.workspace_root, ...PROJECT_CONTEXT_SNAPSHOT_DIR.split("/"));
8375
- const snapshotPath = resolve(snapshotDir, `${safeFilename(manifest.projectContext.revision)}-${manifest.projectContext.hash.slice(-12)}.json`);
8424
+ const snapshotDir = resolve2(plan.workspace_root, ...PROJECT_CONTEXT_SNAPSHOT_DIR.split("/"));
8425
+ const snapshotPath = resolve2(snapshotDir, `${safeFilename(manifest.projectContext.revision)}-${manifest.projectContext.hash.slice(-12)}.json`);
8376
8426
  if (!existsSync4(snapshotPath))
8377
8427
  return false;
8378
8428
  const record = readJsonRecord(snapshotPath, plan.workspace_root);
@@ -8421,10 +8471,10 @@ function writeProjectContextRollbackSnapshot(plan, now3, outputs) {
8421
8471
  sha256: nextHash
8422
8472
  };
8423
8473
  });
8424
- const snapshotDir = resolve(plan.workspace_root, ...SESSION_RENDER_SNAPSHOT_RELATIVE_DIR.split("/"));
8474
+ const snapshotDir = resolve2(plan.workspace_root, ...SESSION_RENDER_SNAPSHOT_RELATIVE_DIR.split("/"));
8425
8475
  ensureSafeDirectory(snapshotDir, plan.workspace_root, 448);
8426
8476
  const timestamp = now3.toISOString().replace(/[:.]/g, "-");
8427
- const snapshotPath = resolve(snapshotDir, `${timestamp}-${randomUUID5()}.json`);
8477
+ const snapshotPath = resolve2(snapshotDir, `${timestamp}-${randomUUID5()}.json`);
8428
8478
  const snapshot = {
8429
8479
  schema: "hasna.configs.session-render-snapshot/v2",
8430
8480
  createdAt: now3.toISOString(),
@@ -8489,7 +8539,7 @@ function readSessionManifestRecord(path, workspaceRoot) {
8489
8539
  }
8490
8540
  }
8491
8541
  function atomicWriteFile(path, content, workspaceRoot, defaultMode, expectedHash, afterExchange, atomicExchangeUnavailable = false, beforeInstall, portableCreateOnly = false, maxObservedBytes, allowPortableReplacement = false) {
8492
- const dir = resolve(path, "..");
8542
+ const dir = resolve2(path, "..");
8493
8543
  ensureSafeDirectory(dir, workspaceRoot, 448);
8494
8544
  assertNoSymlinkSegments(workspaceRoot, path);
8495
8545
  const anchoredOps = portableCreateOnly ? null : resolveAnchoredFsOps();
@@ -8506,7 +8556,7 @@ function atomicWriteFile(path, content, workspaceRoot, defaultMode, expectedHash
8506
8556
  const previous = anchoredFileObservation(directory, targetName);
8507
8557
  const previousMode = previous?.mode ?? defaultMode;
8508
8558
  const tempName = `.project-context-${randomUUID5()}.tmp`;
8509
- const tempPath = join4(dir, tempName);
8559
+ const tempPath = join5(dir, tempName);
8510
8560
  let fd = null;
8511
8561
  let preserveTemp = false;
8512
8562
  let directoryChanged = false;
@@ -8637,7 +8687,7 @@ function atomicWritePortable(path, content, workspaceRoot, defaultMode, expected
8637
8687
  }
8638
8688
  const dir = dirname(path);
8639
8689
  const directoryIdentity = captureManagedDirectoryIdentity(dir, workspaceRoot);
8640
- const tempPath = join4(dir, `.project-context-${randomUUID5()}.tmp`);
8690
+ const tempPath = join5(dir, `.project-context-${randomUUID5()}.tmp`);
8641
8691
  let fd = null;
8642
8692
  let tempIdentity = null;
8643
8693
  try {
@@ -8694,7 +8744,7 @@ function atomicWritePortableReplacement(path, content, workspaceRoot, expectedHa
8694
8744
  }
8695
8745
  const dir = dirname(path);
8696
8746
  const directoryIdentity = captureManagedDirectoryIdentity(dir, workspaceRoot);
8697
- const tempPath = join4(dir, `.project-context-${randomUUID5()}.tmp`);
8747
+ const tempPath = join5(dir, `.project-context-${randomUUID5()}.tmp`);
8698
8748
  const desiredHash = sha2562(content);
8699
8749
  let fd = null;
8700
8750
  let tempIdentity = null;
@@ -8763,11 +8813,11 @@ function portableFileHash(path, workspaceRoot, maxObservedBytes) {
8763
8813
  return createHash2("sha256").update(readFileSync(path)).digest("hex");
8764
8814
  }
8765
8815
  function writeProjectContextCoordinatedFile(input) {
8766
- atomicWriteFile(resolve(input.path), input.content, assertSafeWorkspaceRoot(input.workspace_root), input.default_mode ?? 420, input.expected_hash, undefined, false, input.test_hooks?.before_install, input.force_portable_file_ops ?? false, input.max_observed_bytes, input.allow_portable_replacement ?? false);
8816
+ atomicWriteFile(resolve2(input.path), input.content, assertSafeWorkspaceRoot(input.workspace_root), input.default_mode ?? 420, input.expected_hash, undefined, false, input.test_hooks?.before_install, input.force_portable_file_ops ?? false, input.max_observed_bytes, input.allow_portable_replacement ?? false);
8767
8817
  }
8768
8818
  function removeProjectContextCoordinatedFile(input) {
8769
8819
  const workspaceRoot = assertSafeWorkspaceRoot(input.workspace_root);
8770
- const path = resolve(input.path);
8820
+ const path = resolve2(input.path);
8771
8821
  assertNoSymlinkSegments(workspaceRoot, path);
8772
8822
  const dir = dirname(path);
8773
8823
  const anchoredOps = input.force_portable_file_ops ? null : resolveAnchoredFsOps();
@@ -8793,7 +8843,7 @@ function removeProjectContextCoordinatedFile(input) {
8793
8843
  throw new ProjectContextHashRace(`managed path changed during deletion: ${relativePosix(workspaceRoot, path)}`);
8794
8844
  }
8795
8845
  displaced = true;
8796
- input.test_hooks?.after_displace?.(join4(dir, displacedName));
8846
+ input.test_hooks?.after_displace?.(join5(dir, displacedName));
8797
8847
  const moved = anchoredFileObservation(directory, displacedName);
8798
8848
  if (!moved || moved.dev !== observed.dev || moved.ino !== observed.ino || moved.hash !== input.expected_hash || anchoredFileObservation(directory, targetName) !== null) {
8799
8849
  throw new ProjectContextHashRace(`managed path changed during deletion validation: ${relativePosix(workspaceRoot, path)}`);
@@ -8839,7 +8889,7 @@ function removePortableCoordinatedFile(path, workspaceRoot, expectedHash, maxObs
8839
8889
  }
8840
8890
  const dir = dirname(path);
8841
8891
  const directoryIdentity = captureManagedDirectoryIdentity(dir, workspaceRoot);
8842
- const displacedPath = join4(dir, `.project-context-delete-${randomUUID5()}.tmp`);
8892
+ const displacedPath = join5(dir, `.project-context-delete-${randomUUID5()}.tmp`);
8843
8893
  let displaced = false;
8844
8894
  try {
8845
8895
  assertManagedDirectoryStable(dir, workspaceRoot, directoryIdentity);
@@ -8910,7 +8960,7 @@ function anchoredOpenExclusive(directory, name, mode) {
8910
8960
  const requestedMode = mode & 4095;
8911
8961
  let fd;
8912
8962
  try {
8913
- fd = openSync(join4(directory.path, name), constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, requestedMode);
8963
+ fd = openSync(join5(directory.path, name), constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, requestedMode);
8914
8964
  } catch {
8915
8965
  throw new ProjectContextHashRace(`could not create prepared managed file in ${relativePosix(directory.workspaceRoot, directory.path)}`);
8916
8966
  }
@@ -8953,7 +9003,7 @@ function anchoredFileObservation(directory, name) {
8953
9003
  const stat = fstatSync(fd);
8954
9004
  if (!stat.isFile())
8955
9005
  throw new ProjectContextHashRace("managed output is not a regular file");
8956
- const relativePath = relativePosix(directory.workspaceRoot, join4(directory.path, name));
9006
+ const relativePath = relativePosix(directory.workspaceRoot, join5(directory.path, name));
8957
9007
  const maxBytes = directory.maxObservedBytes === undefined ? managedObservationMaxBytes(relativePath) : directory.maxObservedBytes;
8958
9008
  if (maxBytes !== null && stat.size > maxBytes) {
8959
9009
  throw new ProjectContextHashRace(`managed output exceeds the safe read limit: ${relativePath}`);
@@ -8979,7 +9029,7 @@ function anchoredPreparedObservation(directory, name, path, stage) {
8979
9029
  return observed;
8980
9030
  }
8981
9031
  function captureManagedDirectoryIdentity(path, workspaceRoot) {
8982
- assertNoSymlinkSegments(workspaceRoot, join4(path, ".project-context-directory-guard"));
9032
+ assertNoSymlinkSegments(workspaceRoot, join5(path, ".project-context-directory-guard"));
8983
9033
  let stat;
8984
9034
  try {
8985
9035
  stat = lstatSync(path);
@@ -8992,7 +9042,7 @@ function captureManagedDirectoryIdentity(path, workspaceRoot) {
8992
9042
  return { dev: stat.dev, ino: stat.ino };
8993
9043
  }
8994
9044
  function assertManagedDirectoryStable(path, workspaceRoot, expected) {
8995
- assertNoSymlinkSegments(workspaceRoot, join4(path, ".project-context-directory-guard"));
9045
+ assertNoSymlinkSegments(workspaceRoot, join5(path, ".project-context-directory-guard"));
8996
9046
  let current;
8997
9047
  try {
8998
9048
  current = lstatSync(path);
@@ -9125,10 +9175,10 @@ function resolveAnchoredFsOps() {
9125
9175
  return null;
9126
9176
  }
9127
9177
  function acquireWorkspaceLock(workspaceRoot, lockPath, afterOpen, beforeStaleRemove, processStartIdentityLookup = processStartIdentity) {
9128
- const lockDirectory = resolve(lockPath, "..");
9178
+ const lockDirectory = resolve2(lockPath, "..");
9129
9179
  ensureSafeDirectory(lockDirectory, workspaceRoot, 448);
9130
9180
  assertNoSymlinkSegments(workspaceRoot, lockPath);
9131
- const tempPath = join4(lockDirectory, `.project-context-lock-${randomUUID5()}.tmp`);
9181
+ const tempPath = join5(lockDirectory, `.project-context-lock-${randomUUID5()}.tmp`);
9132
9182
  let fd = null;
9133
9183
  let openedIdentity = null;
9134
9184
  let openedContentHash = null;
@@ -9200,7 +9250,7 @@ function removeOwnedLockByInode(lockPath, identity, expectedHash) {
9200
9250
  if (expectedHash !== undefined && sha2562(readFileSync(lockPath, "utf8")) !== expectedHash)
9201
9251
  return;
9202
9252
  rmSync2(lockPath);
9203
- fsyncDirectory(resolve(lockPath, ".."));
9253
+ fsyncDirectory(resolve2(lockPath, ".."));
9204
9254
  } catch {}
9205
9255
  }
9206
9256
  function observeStaleWorkspaceLock(lockPath, workspaceRoot, processStartIdentityLookup = processStartIdentity) {
@@ -9279,7 +9329,7 @@ function tryTakeoverStaleWorkspaceLock(candidatePath, lockPath, workspaceRoot, c
9279
9329
  throw new ProjectContextError("PROJECT_CONTEXT_LOCK_LOST", "workspace lock changed during stale-lock takeover and could not be restored safely");
9280
9330
  }
9281
9331
  rmSync2(candidatePath);
9282
- fsyncDirectory(resolve(lockPath, ".."));
9332
+ fsyncDirectory(resolve2(lockPath, ".."));
9283
9333
  exchanged = false;
9284
9334
  return true;
9285
9335
  } catch (error) {
@@ -9358,8 +9408,8 @@ function releaseWorkspaceLock(lockPath, lock, workspaceRoot) {
9358
9408
  }
9359
9409
  return;
9360
9410
  }
9361
- const lockDirectory = resolve(lockPath, "..");
9362
- const releasePath = join4(lockDirectory, `.project-context-release-${randomUUID5()}.tmp`);
9411
+ const lockDirectory = resolve2(lockPath, "..");
9412
+ const releasePath = join5(lockDirectory, `.project-context-release-${randomUUID5()}.tmp`);
9363
9413
  let releaseFd = null;
9364
9414
  let releaseIdentity = null;
9365
9415
  let releaseHash = null;
@@ -9439,7 +9489,7 @@ function ensureSafeDirectory(path, workspaceRoot, mode) {
9439
9489
  const segments = rel.split(/[\\/]+/).filter(Boolean);
9440
9490
  let current = workspaceRoot;
9441
9491
  for (const segment of segments) {
9442
- current = join4(current, segment);
9492
+ current = join5(current, segment);
9443
9493
  if (existsSync4(current)) {
9444
9494
  if (lstatSync(current).isSymbolicLink())
9445
9495
  throw new ProjectContextError("PROJECT_CONTEXT_SYMLINK_REJECTED", `managed path uses a symlink: ${current}`);
@@ -9447,7 +9497,7 @@ function ensureSafeDirectory(path, workspaceRoot, mode) {
9447
9497
  throw new ProjectContextError("PROJECT_CONTEXT_PATH_INVALID", `managed path is not a directory: ${current}`);
9448
9498
  } else {
9449
9499
  mkdirSync2(current, { mode });
9450
- fsyncDirectory(resolve(current, ".."));
9500
+ fsyncDirectory(resolve2(current, ".."));
9451
9501
  }
9452
9502
  }
9453
9503
  }
@@ -9503,11 +9553,11 @@ function scanGeneratedContent(content) {
9503
9553
  function runtimePaths(workspaceRoot, runtime) {
9504
9554
  const relativeTarget = runtime === "claude" ? "CLAUDE.md" : runtime === "codewith" ? ".codewith/CODEWITH.md" : "AGENTS.md";
9505
9555
  return {
9506
- target: resolve(workspaceRoot, ...relativeTarget.split("/")),
9507
- fragment: resolve(workspaceRoot, ...PROJECT_CONTEXT_FRAGMENT_PATH.split("/")),
9508
- manifest: resolve(workspaceRoot, ...PROJECT_CONTEXT_MANIFEST_PATH.split("/")),
9509
- cache: resolve(workspaceRoot, ...PROJECT_CONTEXT_CACHE_PATH.split("/")),
9510
- sessionManifest: runtime === "codewith" ? resolve(workspaceRoot, ".codewith", ".hasna", "session-render-manifest.json") : resolve(workspaceRoot, ".hasna", "session-render-manifest.json")
9556
+ target: resolve2(workspaceRoot, ...relativeTarget.split("/")),
9557
+ fragment: resolve2(workspaceRoot, ...PROJECT_CONTEXT_FRAGMENT_PATH.split("/")),
9558
+ manifest: resolve2(workspaceRoot, ...PROJECT_CONTEXT_MANIFEST_PATH.split("/")),
9559
+ cache: resolve2(workspaceRoot, ...PROJECT_CONTEXT_CACHE_PATH.split("/")),
9560
+ sessionManifest: runtime === "codewith" ? resolve2(workspaceRoot, ".codewith", ".hasna", "session-render-manifest.json") : resolve2(workspaceRoot, ".hasna", "session-render-manifest.json")
9511
9561
  };
9512
9562
  }
9513
9563
  function projectContextSessionGuardPaths(paths, runtime) {
@@ -9517,7 +9567,7 @@ function projectContextSessionGuardPaths(paths, runtime) {
9517
9567
  paths.fragment,
9518
9568
  paths.target,
9519
9569
  paths.sessionManifest,
9520
- ...runtime === "codewith" ? [resolve(paths.target, "..", "CODEWITH.override.md")] : []
9570
+ ...runtime === "codewith" ? [resolve2(paths.target, "..", "CODEWITH.override.md")] : []
9521
9571
  ];
9522
9572
  }
9523
9573
  function sessionTargetRelativePath(runtime) {
@@ -9537,12 +9587,12 @@ function projectContextRuntimeForSessionTool(tool) {
9537
9587
  return null;
9538
9588
  }
9539
9589
  function projectContextWorkspaceForSession(input, runtime) {
9540
- const targetHome = resolve(input.target_home);
9590
+ const targetHome = resolve2(input.target_home);
9541
9591
  if (runtime === "codewith") {
9542
9592
  const workspaceRoot = basename(targetHome) === ".codewith" ? dirname(targetHome) : null;
9543
9593
  if (!workspaceRoot)
9544
9594
  return null;
9545
- if (input.project_root && resolve(input.project_root) !== workspaceRoot) {
9595
+ if (input.project_root && resolve2(input.project_root) !== workspaceRoot) {
9546
9596
  throw new ProjectContextError("PROJECT_CONTEXT_PATH_INVALID", "Codewith project_root must be the parent workspace of target_home");
9547
9597
  }
9548
9598
  if (!existsSync4(workspaceRoot) || !lstatSync(workspaceRoot).isDirectory())
@@ -9556,7 +9606,7 @@ function projectContextWorkspaceForSession(input, runtime) {
9556
9606
  function assertCodewithTargetIsConsumed(workspaceRoot, runtime) {
9557
9607
  if (runtime !== "codewith")
9558
9608
  return;
9559
- const override = resolve(workspaceRoot, ".codewith", "CODEWITH.override.md");
9609
+ const override = resolve2(workspaceRoot, ".codewith", "CODEWITH.override.md");
9560
9610
  if (!existsSync4(override))
9561
9611
  return;
9562
9612
  assertNoSymlinkSegments(workspaceRoot, override);
@@ -9567,7 +9617,7 @@ function assertCodewithTargetIsConsumed(workspaceRoot, runtime) {
9567
9617
  function assertSafeWorkspaceRoot(path) {
9568
9618
  if (!isAbsolute(path))
9569
9619
  throw new ProjectContextError("PROJECT_CONTEXT_PATH_INVALID", "workspace root must be absolute");
9570
- const normalized = resolve(path);
9620
+ const normalized = resolve2(path);
9571
9621
  if (normalized === parse(normalized).root)
9572
9622
  throw new ProjectContextError("PROJECT_CONTEXT_PATH_INVALID", "workspace root cannot be the filesystem root");
9573
9623
  if (!existsSync4(normalized) || !lstatSync(normalized).isDirectory())
@@ -9584,17 +9634,17 @@ function assertNoSymlinkSegments(root, target) {
9584
9634
  }
9585
9635
  let current = root;
9586
9636
  for (const segment of rel.split(/[\\/]+/).filter(Boolean)) {
9587
- current = join4(current, segment);
9637
+ current = join5(current, segment);
9588
9638
  if (existsSync4(current) && lstatSync(current).isSymbolicLink()) {
9589
9639
  throw new ProjectContextError("PROJECT_CONTEXT_SYMLINK_REJECTED", `managed path uses a symlink: ${current}`);
9590
9640
  }
9591
9641
  }
9592
9642
  }
9593
9643
  function assertNoSymlinkAncestors(path) {
9594
- const normalized = resolve(path);
9644
+ const normalized = resolve2(path);
9595
9645
  let current = parse(normalized).root;
9596
9646
  for (const segment of relative(current, normalized).split(/[\\/]+/).filter(Boolean)) {
9597
- current = join4(current, segment);
9647
+ current = join5(current, segment);
9598
9648
  if (!existsSync4(current))
9599
9649
  return;
9600
9650
  if (lstatSync(current).isSymbolicLink())
@@ -9630,10 +9680,10 @@ function fragmentMatchesBundle(path, bundle, workspaceRoot) {
9630
9680
  }
9631
9681
  function durableSourcePath(path, workspaceRoot) {
9632
9682
  if (!path || path.startsWith("/dev/fd/"))
9633
- return resolve(workspaceRoot, ...PROJECT_CONTEXT_CACHE_PATH.split("/"));
9634
- const normalized = isAbsolute(path) ? resolve(path) : resolve(workspaceRoot, path);
9683
+ return resolve2(workspaceRoot, ...PROJECT_CONTEXT_CACHE_PATH.split("/"));
9684
+ const normalized = isAbsolute(path) ? resolve2(path) : resolve2(workspaceRoot, path);
9635
9685
  if (normalized.startsWith("/dev/fd/"))
9636
- return resolve(workspaceRoot, ...PROJECT_CONTEXT_CACHE_PATH.split("/"));
9686
+ return resolve2(workspaceRoot, ...PROJECT_CONTEXT_CACHE_PATH.split("/"));
9637
9687
  return normalized;
9638
9688
  }
9639
9689
  function compareRevisions(incoming, previous) {
@@ -10193,7 +10243,7 @@ function compareProviderVersions(left, right) {
10193
10243
 
10194
10244
  // src/lib/asset-plan.ts
10195
10245
  import { createHash as createHash3 } from "crypto";
10196
- import { isAbsolute as isAbsolute2, posix, resolve as resolve2 } from "path";
10246
+ import { isAbsolute as isAbsolute2, posix, resolve as resolve3 } from "path";
10197
10247
  function assetCapability(provider, surface, kind, support, strategies, note, providerVersionRange = "*") {
10198
10248
  return Object.freeze({
10199
10249
  schema: ASSET_CAPABILITY_SCHEMA,
@@ -10400,8 +10450,8 @@ function resolveAssetDestination(item, roots) {
10400
10450
  if (!isAbsolute2(root))
10401
10451
  throw new Error(`Asset ${item.assetKey} destination root must be absolute.`);
10402
10452
  const relativePath = safeRelativePath(item.destination.relativePath);
10403
- const target = resolve2(root, ...relativePath.split("/"));
10404
- const normalizedRoot = resolve2(root);
10453
+ const target = resolve3(root, ...relativePath.split("/"));
10454
+ const normalizedRoot = resolve3(root);
10405
10455
  if (target === normalizedRoot)
10406
10456
  throw new Error(`Asset ${item.assetKey} destination cannot replace its root.`);
10407
10457
  if (!target.startsWith(`${normalizedRoot}/`))
@@ -10581,23 +10631,19 @@ var init_asset_plan = __esm(() => {
10581
10631
  // src/lib/cursor-authority.ts
10582
10632
  import { createHash as createHash4 } from "crypto";
10583
10633
  import { lstatSync as lstatSync2, readFileSync as readFileSync2 } from "fs";
10584
- import { homedir as homedir3 } from "os";
10585
- import { join as join5, resolve as resolve3 } from "path";
10634
+ import { homedir as homedir4 } from "os";
10635
+ import { join as join6, resolve as resolve4 } from "path";
10586
10636
  function sha2564(content) {
10587
10637
  return createHash4("sha256").update(content).digest("hex");
10588
10638
  }
10589
10639
  function homeDir() {
10590
- return process.env["HOME"] || homedir3();
10640
+ return process.env["HOME"] || homedir4();
10591
10641
  }
10592
- function markerPayload(content, markerLine) {
10593
- const withTrailingNewline = `${markerLine}
10594
- `;
10595
- if (content.startsWith(withTrailingNewline))
10596
- return content.slice(withTrailingNewline.length);
10597
- if (content.startsWith(markerLine))
10598
- return content.slice(markerLine.length).replace(/^\n/, "");
10599
- return content.replace(`${markerLine}
10600
- `, "").replace(markerLine, "");
10642
+ function markerPayload(content, markerLine, markerIndex) {
10643
+ const index = markerIndex ?? content.indexOf(markerLine);
10644
+ if (index < 0)
10645
+ return content;
10646
+ return content.slice(0, index) + content.slice(index + markerLine.length).replace(/^\n/, "");
10601
10647
  }
10602
10648
  function baseObservation(path) {
10603
10649
  return {
@@ -10607,12 +10653,12 @@ function baseObservation(path) {
10607
10653
  };
10608
10654
  }
10609
10655
  function observeCursorGlobalAuthority(options = {}) {
10610
- const authorityPath = resolve3(join5(options.home ?? homeDir(), CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH));
10656
+ const authorityPath = resolve4(join6(options.home ?? homeDir(), CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH));
10611
10657
  const readFile2 = options.readFile ?? ((path) => readFileSync2(path, "utf8"));
10612
10658
  return observeCursorGlobalAuthorityPath(authorityPath, readFile2);
10613
10659
  }
10614
10660
  function observeCursorGlobalAuthorityAtPath(authorityPath) {
10615
- return observeCursorGlobalAuthorityPath(resolve3(authorityPath), (path) => readFileSync2(path, "utf8"));
10661
+ return observeCursorGlobalAuthorityPath(resolve4(authorityPath), (path) => readFileSync2(path, "utf8"));
10616
10662
  }
10617
10663
  function observeCursorGlobalAuthorityPath(authorityPath, readFile2) {
10618
10664
  const base = baseObservation(authorityPath);
@@ -10724,7 +10770,7 @@ function observeCursorGlobalAuthorityPath(authorityPath, readFile2) {
10724
10770
  };
10725
10771
  }
10726
10772
  const markerLine = markerMatch[0];
10727
- const payloadSha256 = sha2564(markerPayload(content, markerLine));
10773
+ const payloadSha256 = sha2564(markerPayload(content, markerLine, markerMatch.index ?? -1));
10728
10774
  if (payloadSha256 !== markerSha256) {
10729
10775
  return {
10730
10776
  ...base,
@@ -10741,53 +10787,147 @@ function observeCursorGlobalAuthorityPath(authorityPath, readFile2) {
10741
10787
  }
10742
10788
  };
10743
10789
  }
10744
- return {
10745
- ...base,
10746
- fileType,
10747
- status: "unmanaged",
10748
- sha256: contentSha256,
10790
+ return {
10791
+ ...base,
10792
+ fileType,
10793
+ status: "managed",
10794
+ sha256: contentSha256,
10795
+ markers,
10796
+ markerSha256,
10797
+ provenance: {
10798
+ source: "filesystem",
10799
+ authority: "managed",
10800
+ observedPath: authorityPath,
10801
+ detection: "managed-marker"
10802
+ }
10803
+ };
10804
+ }
10805
+ function isCursorGlobalAuthorityPath(path) {
10806
+ return resolve4(path) === resolve4(join6(homeDir(), CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH));
10807
+ }
10808
+ function stampCursorGlobalAuthorityMarker(content) {
10809
+ if (CURSOR_GLOBAL_AUTHORITY_MARKER_PATTERN.test(content))
10810
+ return content;
10811
+ const digest = sha2564(content);
10812
+ const markerLine = `<!-- ${CURSOR_GLOBAL_AUTHORITY_MANAGED_MARKER} hash=sha256:${digest} -->`;
10813
+ const frontmatter = content.match(CURSOR_GLOBAL_AUTHORITY_FRONTMATTER_PATTERN)?.[0];
10814
+ if (frontmatter) {
10815
+ return `${frontmatter}${markerLine}
10816
+ ${content.slice(frontmatter.length)}`;
10817
+ }
10818
+ return `${markerLine}
10819
+ ${content}`;
10820
+ }
10821
+ function detectCursorAuthorityConflicts(observation = observeCursorGlobalAuthority()) {
10822
+ if (observation.status === "absent" || observation.status === "managed")
10823
+ return [];
10824
+ const detection = observation.provenance.detection;
10825
+ const invalid = observation.status === "invalid";
10826
+ return [{
10827
+ tool: "cursor",
10828
+ relativePath: CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH,
10829
+ path: observation.path,
10830
+ kind: invalid ? "invalid-unmanaged-authority" : "unknown-unmanaged-authority",
10831
+ sha256: observation.sha256,
10832
+ markers: observation.markers,
10833
+ provenance: {
10834
+ source: "filesystem",
10835
+ authority: "unmanaged",
10836
+ observedPath: observation.path,
10837
+ detection
10838
+ },
10839
+ reason: invalid ? `Cursor fixed global authority ${CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH} is not a verifiable regular managed file; refusing to render project rules.` : `Cursor fixed global authority ${CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH} is unmanaged; refusing to guess whether it conflicts with the managed project render.`
10840
+ }];
10841
+ }
10842
+ var CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH = ".cursor/rules/hasna-global.mdc", CURSOR_GLOBAL_AUTHORITY_MAX_BYTES, CURSOR_GLOBAL_AUTHORITY_MANAGED_MARKER = "Managed by @hasna/configs cursor global authority", CURSOR_GLOBAL_AUTHORITY_MARKER_PATTERN, CURSOR_GLOBAL_AUTHORITY_FRONTMATTER_PATTERN;
10843
+ var init_cursor_authority = __esm(() => {
10844
+ CURSOR_GLOBAL_AUTHORITY_MAX_BYTES = 256 * 1024;
10845
+ CURSOR_GLOBAL_AUTHORITY_MARKER_PATTERN = /^<!-- Managed by @hasna\/configs cursor global authority hash=(sha256:[a-f0-9]{64}) -->$/m;
10846
+ CURSOR_GLOBAL_AUTHORITY_FRONTMATTER_PATTERN = /^---\n[\s\S]*?\n---(?:\n|$)/;
10847
+ });
10848
+
10849
+ // src/lib/session-authority.ts
10850
+ import { createHash as createHash5 } from "crypto";
10851
+ import { lstatSync as lstatSync3, readFileSync as readFileSync3, statSync as statSync2 } from "fs";
10852
+ import { join as join7, resolve as resolve5 } from "path";
10853
+ function sha2565(content) {
10854
+ return createHash5("sha256").update(content).digest("hex");
10855
+ }
10856
+ function detectClaudeAuthorityConflicts(targetHome) {
10857
+ const authorityPath = resolve5(join7(targetHome, CLAUDE_LEGACY_AUTHORITY_RELATIVE_PATH));
10858
+ let stat;
10859
+ try {
10860
+ stat = lstatSync3(authorityPath);
10861
+ } catch {
10862
+ return [];
10863
+ }
10864
+ const provenanceBase = {
10865
+ tool: "claude",
10866
+ relativePath: CLAUDE_LEGACY_AUTHORITY_RELATIVE_PATH,
10867
+ path: authorityPath
10868
+ };
10869
+ if (stat.isSymbolicLink() || !stat.isFile()) {
10870
+ return [{
10871
+ ...provenanceBase,
10872
+ kind: "invalid-unmanaged-authority",
10873
+ sha256: null,
10874
+ markers: [],
10875
+ provenance: {
10876
+ source: "filesystem",
10877
+ authority: "unmanaged",
10878
+ observedPath: authorityPath,
10879
+ detection: "non-regular-file"
10880
+ },
10881
+ reason: "Claude target contains unmanaged AGENTS.md that is not a regular file; authority cannot be verified safely."
10882
+ }];
10883
+ }
10884
+ if (statSync2(authorityPath).size > CLAUDE_LEGACY_AUTHORITY_MAX_BYTES) {
10885
+ return [{
10886
+ ...provenanceBase,
10887
+ kind: "invalid-unmanaged-authority",
10888
+ sha256: null,
10889
+ markers: [],
10890
+ provenance: {
10891
+ source: "filesystem",
10892
+ authority: "unmanaged",
10893
+ observedPath: authorityPath,
10894
+ detection: "oversized-file"
10895
+ },
10896
+ reason: `Claude target contains unmanaged AGENTS.md larger than ${CLAUDE_LEGACY_AUTHORITY_MAX_BYTES} bytes; authority cannot be classified safely.`
10897
+ }];
10898
+ }
10899
+ const content = readFileSync3(authorityPath, "utf8");
10900
+ const markers = CLAUDE_LEGACY_MARKERS.filter((marker) => marker.pattern.test(content)).map((marker) => marker.id);
10901
+ const knownLegacy = markers.includes("no-worktrees-heading") && markers.includes("no-worktrees-directive");
10902
+ return [{
10903
+ ...provenanceBase,
10904
+ kind: knownLegacy ? "known-legacy-no-worktree" : "unknown-unmanaged-authority",
10905
+ sha256: sha2565(content),
10749
10906
  markers,
10750
- markerSha256,
10751
10907
  provenance: {
10752
10908
  source: "filesystem",
10753
10909
  authority: "unmanaged",
10754
10910
  observedPath: authorityPath,
10755
- detection: "unknown-content"
10756
- }
10757
- };
10758
- }
10759
- function detectCursorAuthorityConflicts(observation = observeCursorGlobalAuthority()) {
10760
- if (observation.status === "absent" || observation.status === "managed")
10761
- return [];
10762
- const detection = observation.provenance.detection;
10763
- const invalid = observation.status === "invalid";
10764
- return [{
10765
- tool: "cursor",
10766
- relativePath: CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH,
10767
- path: observation.path,
10768
- kind: invalid ? "invalid-unmanaged-authority" : "unknown-unmanaged-authority",
10769
- sha256: observation.sha256,
10770
- markers: observation.markers,
10771
- provenance: {
10772
- source: "filesystem",
10773
- authority: "unmanaged",
10774
- observedPath: observation.path,
10775
- detection
10911
+ detection: knownLegacy ? "known-legacy-markers" : "unknown-content"
10776
10912
  },
10777
- reason: invalid ? `Cursor fixed global authority ${CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH} is not a verifiable regular managed file; refusing to render project rules.` : `Cursor fixed global authority ${CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH} is unmanaged; refusing to guess whether it conflicts with the managed project render.`
10913
+ reason: knownLegacy ? "Claude target contains unmanaged legacy AGENTS.md with no-worktree directives; migrate or remove it through an owned authority path before applying." : "Claude target contains unmanaged AGENTS.md with unknown authority content; refusing to guess whether it conflicts with the managed Claude render."
10778
10914
  }];
10779
10915
  }
10780
- var CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH = ".cursor/rules/hasna-global.mdc", CURSOR_GLOBAL_AUTHORITY_MAX_BYTES, CURSOR_GLOBAL_AUTHORITY_MANAGED_MARKER = "Managed by @hasna/configs cursor global authority", CURSOR_GLOBAL_AUTHORITY_MARKER_PATTERN;
10781
- var init_cursor_authority = __esm(() => {
10782
- CURSOR_GLOBAL_AUTHORITY_MAX_BYTES = 256 * 1024;
10783
- CURSOR_GLOBAL_AUTHORITY_MARKER_PATTERN = /^<!-- Managed by @hasna\/configs cursor global authority hash=(sha256:[a-f0-9]{64}) -->$/m;
10916
+ var CLAUDE_LEGACY_AUTHORITY_RELATIVE_PATH = "AGENTS.md", CLAUDE_LEGACY_AUTHORITY_MAX_BYTES, CLAUDE_LEGACY_MARKERS;
10917
+ var init_session_authority = __esm(() => {
10918
+ CLAUDE_LEGACY_AUTHORITY_MAX_BYTES = 256 * 1024;
10919
+ CLAUDE_LEGACY_MARKERS = [
10920
+ { id: "claude-agent-rules-heading", pattern: /^# Agent Rules \(Claude\)/m },
10921
+ { id: "no-worktrees-heading", pattern: /^## No Worktrees/m },
10922
+ { id: "no-worktrees-directive", pattern: /\bNever use git worktrees\b/m }
10923
+ ];
10784
10924
  });
10785
10925
 
10786
10926
  // src/lib/session-render.ts
10787
- import { createHash as createHash5 } from "crypto";
10788
- import { existsSync as existsSync5, readFileSync as readFileSync3, realpathSync, statSync as statSync2 } from "fs";
10789
- import { homedir as homedir4 } from "os";
10790
- import { basename as basename3, dirname as dirname2, extname as extname2, isAbsolute as isAbsolute3, join as join6, parse as parse2, posix as posix2, relative as relative2, resolve as resolve4 } from "path";
10927
+ import { createHash as createHash6 } from "crypto";
10928
+ import { existsSync as existsSync5, readFileSync as readFileSync4, realpathSync, statSync as statSync3 } from "fs";
10929
+ import { homedir as homedir5 } from "os";
10930
+ import { basename as basename3, dirname as dirname2, extname as extname2, isAbsolute as isAbsolute3, join as join8, parse as parse2, posix as posix2, relative as relative2, resolve as resolve6 } from "path";
10791
10931
  function normalizeSessionInstructionLayer(value) {
10792
10932
  if (value === "provider")
10793
10933
  return "tool";
@@ -10804,11 +10944,11 @@ function ensureTrailingNewline3(content) {
10804
10944
  `) ? content : `${content}
10805
10945
  `;
10806
10946
  }
10807
- function sha2565(content) {
10808
- return createHash5("sha256").update(content).digest("hex");
10947
+ function sha2566(content) {
10948
+ return createHash6("sha256").update(content).digest("hex");
10809
10949
  }
10810
10950
  function fingerprint(value) {
10811
- return sha2565(JSON.stringify(value));
10951
+ return sha2566(JSON.stringify(value));
10812
10952
  }
10813
10953
  function canonicalFingerprintValue(value) {
10814
10954
  if (Array.isArray(value))
@@ -10826,7 +10966,7 @@ function ruleAttestation(rule) {
10826
10966
  };
10827
10967
  const applied = metadata["payloadFloorApplied"];
10828
10968
  return {
10829
- contentSha256: sha2565(rule.content ?? ""),
10969
+ contentSha256: sha2566(rule.content ?? ""),
10830
10970
  payloadFloorApplied: typeof applied === "boolean" ? applied : null,
10831
10971
  flooredFromRulesVersion: read("flooredFromRulesVersion"),
10832
10972
  flooredFromPayloadSha256: read("flooredFromPayloadSha256"),
@@ -10872,16 +11012,14 @@ function slug(value) {
10872
11012
  function yamlQuote2(value) {
10873
11013
  return `"${value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`;
10874
11014
  }
10875
- function getRawStoreRoot() {
10876
- return resolve4(process.env[RAW_STORE_ROOT_ENV] || join6(process.env["HOME"] || homedir4(), ".hasna", "configs"));
10877
- }
10878
11015
  function defaultTargetHome(tool, profile, sessionId) {
10879
- return join6(getRawStoreRoot(), "sessions", tool, slug(profile), slug(sessionId || "latest"));
11016
+ const home = process.env["HOME"] || homedir5();
11017
+ return join8(home, ".hasna", "accounts", "profiles", tool, slug(profile));
10880
11018
  }
10881
11019
  function joinTarget(targetHome, relativePath) {
10882
11020
  const safeTargetHome = assertSafeTargetRoot(targetHome);
10883
11021
  const safeRelativePath2 = assertSafeRelativePath(relativePath);
10884
- return join6(safeTargetHome, ...safeRelativePath2.split("/"));
11022
+ return join8(safeTargetHome, ...safeRelativePath2.split("/"));
10885
11023
  }
10886
11024
  function makeFile(targetHome, relativePath, role, content, sourceIds) {
10887
11025
  const safeTargetHome = assertSafeTargetRoot(targetHome);
@@ -10892,7 +11030,7 @@ function makeFile(targetHome, relativePath, role, content, sourceIds) {
10892
11030
  relativePath: safeRelativePath2,
10893
11031
  role,
10894
11032
  content: normalizedContent,
10895
- sha256: sha2565(normalizedContent),
11033
+ sha256: sha2566(normalizedContent),
10896
11034
  sourceIds
10897
11035
  };
10898
11036
  }
@@ -10926,7 +11064,7 @@ function applyAgentOperatingRulesFloor(source, content) {
10926
11064
  const floored = {
10927
11065
  payloadFloorApplied: true,
10928
11066
  flooredFromRulesVersion: parseAgentOperatingRulesVersion(content),
10929
- flooredFromPayloadSha256: sha2565(content)
11067
+ flooredFromPayloadSha256: sha2566(content)
10930
11068
  };
10931
11069
  return {
10932
11070
  content: payload.content,
@@ -10948,7 +11086,7 @@ function applyAgentOperatingRulesFloorToRule(source, rule, content) {
10948
11086
  const floored = {
10949
11087
  payloadFloorApplied: true,
10950
11088
  flooredFromRulesVersion: parseAgentOperatingRulesVersion(content),
10951
- flooredFromPayloadSha256: sha2565(content)
11089
+ flooredFromPayloadSha256: sha2566(content)
10952
11090
  };
10953
11091
  return {
10954
11092
  content: payload.content,
@@ -10967,7 +11105,7 @@ function skippedSource(source, reason) {
10967
11105
  order: source.resolvedOrder,
10968
11106
  path: source.path ?? null,
10969
11107
  hash: source.hash ?? null,
10970
- renderedPayloadSha256: sha2565(source.content),
11108
+ renderedPayloadSha256: sha2566(source.content),
10971
11109
  nonOverridable: source.nonOverridable === true,
10972
11110
  provenance: source.provenance ?? null
10973
11111
  }
@@ -11009,7 +11147,7 @@ function compareSessionInstructionSources(a, b) {
11009
11147
  return SESSION_LAYER_RANK[a.resolvedLayer] - SESSION_LAYER_RANK[b.resolvedLayer] || a.resolvedOrder - b.resolvedOrder || a.id.localeCompare(b.id);
11010
11148
  }
11011
11149
  function semanticPolicyIntegrity(body) {
11012
- return sha2565(body) === AGENT_OPERATING_RULES_PAYLOAD_SHA256 ? "pinned-digest" : "unverified-self-declared";
11150
+ return sha2566(body) === AGENT_OPERATING_RULES_PAYLOAD_SHA256 ? "pinned-digest" : "unverified-self-declared";
11013
11151
  }
11014
11152
  function semanticPolicyDeclaration(source) {
11015
11153
  const normalize = (value) => value.replace(/\r\n/g, `
@@ -11234,7 +11372,7 @@ function composeSources(sources, tool) {
11234
11372
  targetSourceId: target.id,
11235
11373
  targetNormalizedSourceId: target.normalizedId,
11236
11374
  targetHash: target.hash ?? null,
11237
- targetRenderedPayloadSha256: sha2565(target.content),
11375
+ targetRenderedPayloadSha256: sha2566(target.content),
11238
11376
  targetNonOverridable: protectedReplacement,
11239
11377
  authority: protectedReplacement ? "canonical-identity-export/codewith-provider/v1" : "overridable-source/v1"
11240
11378
  }
@@ -11416,7 +11554,7 @@ function buildOpenCodeFiles(targetHome, adapter, profile, sources, providerConfi
11416
11554
  ...sources.flatMap((source) => source.resolvedRules.map((rule) => rule.id))
11417
11555
  ]);
11418
11556
  const existingConfigPath = joinTarget(targetHome, adapter.configFile);
11419
- const selectedConfig = existsSync5(existingConfigPath) ? readOpenCodeConfig(readFileSync3(existingConfigPath, "utf8"), existingConfigPath) : providerConfig ? readOpenCodeConfig(providerConfig.content, providerConfig.sourceId) : {};
11557
+ const selectedConfig = existsSync5(existingConfigPath) ? readOpenCodeConfig(readFileSync4(existingConfigPath, "utf8"), existingConfigPath) : providerConfig ? readOpenCodeConfig(providerConfig.content, providerConfig.sourceId) : {};
11420
11558
  const preservedInstructions = normalizeOpenCodeInstructions(selectedConfig["instructions"]).filter((path) => !pathIsManagedOpenCodeInstruction(path, adapter.managedDir));
11421
11559
  const config = {
11422
11560
  ...selectedConfig,
@@ -11565,7 +11703,7 @@ function buildAssetFiles(input, targetHome, blocked) {
11565
11703
  relativePath: assertSafeRelativePath(relativePath),
11566
11704
  role: "asset",
11567
11705
  content,
11568
- sha256: sha2565(content),
11706
+ sha256: sha2566(content),
11569
11707
  sourceIds: [item.sourceConfigId, item.assetId]
11570
11708
  };
11571
11709
  });
@@ -11605,7 +11743,7 @@ function adapterFor(input) {
11605
11743
  return gatedNativeImports ? CODEWITH_NATIVE_ADAPTER : CODEWITH_FLATTENED_ADAPTER;
11606
11744
  }
11607
11745
  function getHomeDir() {
11608
- return process.env["CONFIGS_HOME"] || process.env["HOME"] || homedir4();
11746
+ return process.env["CONFIGS_HOME"] || process.env["HOME"] || homedir5();
11609
11747
  }
11610
11748
  function cleanSessionPathInput(path) {
11611
11749
  const trimmed = path.trim();
@@ -11620,16 +11758,16 @@ function resolveSessionPath(path) {
11620
11758
  throw new Error("Session render path cannot be empty.");
11621
11759
  const home = getHomeDir();
11622
11760
  if (cleaned === "~")
11623
- return resolve4(home);
11761
+ return resolve6(home);
11624
11762
  if (cleaned.startsWith("~/"))
11625
- return resolve4(home, cleaned.slice(2));
11763
+ return resolve6(home, cleaned.slice(2));
11626
11764
  if (cleaned === "{{HOME}}" || cleaned === "${HOME}")
11627
- return resolve4(home);
11765
+ return resolve6(home);
11628
11766
  if (cleaned.startsWith("{{HOME}}/"))
11629
- return resolve4(home, cleaned.slice("{{HOME}}/".length));
11767
+ return resolve6(home, cleaned.slice("{{HOME}}/".length));
11630
11768
  if (cleaned.startsWith("${HOME}/"))
11631
- return resolve4(home, cleaned.slice("${HOME}/".length));
11632
- return resolve4(cleaned);
11769
+ return resolve6(home, cleaned.slice("${HOME}/".length));
11770
+ return resolve6(cleaned);
11633
11771
  }
11634
11772
  function assertSafeRelativePath(relativePath) {
11635
11773
  if (!relativePath.trim())
@@ -11645,7 +11783,7 @@ function assertSafeRelativePath(relativePath) {
11645
11783
  function assertSafeTargetRoot(targetHome) {
11646
11784
  if (!isAbsolute3(targetHome))
11647
11785
  throw new Error(`Session render target must be an absolute path: ${targetHome}`);
11648
- const normalized = resolve4(targetHome);
11786
+ const normalized = resolve6(targetHome);
11649
11787
  if (normalized === parse2(normalized).root) {
11650
11788
  throw new Error(`Session render target cannot be the filesystem root: ${targetHome}`);
11651
11789
  }
@@ -11743,7 +11881,7 @@ function planSessionRender(input) {
11743
11881
  blockers: targetBlockers
11744
11882
  } = resolveRenderTarget(input);
11745
11883
  const authorityObservations = input.tool === "cursor" && targetKind !== "blocked" ? [observeCursorGlobalAuthority({ home: input.cursorAuthorityHome })] : [];
11746
- const authorityConflicts = input.tool === "cursor" && targetKind !== "blocked" ? detectCursorAuthorityConflicts(authorityObservations[0]) : [];
11884
+ const authorityConflicts = input.tool === "cursor" && targetKind !== "blocked" ? detectCursorAuthorityConflicts(authorityObservations[0]) : input.tool === "claude" && targetKind !== "blocked" ? detectClaudeAuthorityConflicts(targetHome) : [];
11747
11885
  const blockers = [
11748
11886
  ...targetBlockers,
11749
11887
  ...authorityConflicts.map((conflict) => `${conflict.relativePath}: ${conflict.reason}`)
@@ -11841,7 +11979,7 @@ function planSessionRender(input) {
11841
11979
  hash: rule.hash ?? null,
11842
11980
  ...ruleAttestation(rule)
11843
11981
  })),
11844
- renderedPayloadSha256: sha2565(source.content),
11982
+ renderedPayloadSha256: sha2566(source.content),
11845
11983
  provenance: source.provenance ?? null,
11846
11984
  metadata: source.metadata ?? null
11847
11985
  })),
@@ -11879,8 +12017,8 @@ function planSessionRender(input) {
11879
12017
  ...input.providerConfig ? {
11880
12018
  providerConfig: {
11881
12019
  sourceId: input.providerConfig.sourceId,
11882
- selectedPayloadSha256: sha2565(input.providerConfig.content),
11883
- renderedPayloadSha256: files.find((file) => file.relativePath === adapter.configFile)?.sha256 ?? sha2565(input.providerConfig.content),
12020
+ selectedPayloadSha256: sha2566(input.providerConfig.content),
12021
+ renderedPayloadSha256: files.find((file) => file.relativePath === adapter.configFile)?.sha256 ?? sha2566(input.providerConfig.content),
11884
12022
  selected: !existsSync5(joinTarget(targetHome, adapter.configFile))
11885
12023
  }
11886
12024
  } : {},
@@ -12166,7 +12304,7 @@ function readIdentitySourcePath(sourcePath, baseDir, sourceId) {
12166
12304
  }
12167
12305
  return;
12168
12306
  }
12169
- const stat = statSync2(resolvedPath);
12307
+ const stat = statSync3(resolvedPath);
12170
12308
  if (!stat.isFile()) {
12171
12309
  throw new Error(`Identity instruction source path is not a file for ${sourceId}: ${sourcePath.path}`);
12172
12310
  }
@@ -12175,7 +12313,7 @@ function readIdentitySourcePath(sourcePath, baseDir, sourceId) {
12175
12313
  if (!pathIsInside(realPath, realBase)) {
12176
12314
  throw new Error(`Identity instruction source path escapes export directory for ${sourceId}: ${sourcePath.path}`);
12177
12315
  }
12178
- return readFileSync3(realPath, "utf-8");
12316
+ return readFileSync4(realPath, "utf-8");
12179
12317
  }
12180
12318
  function resolveIdentitySourcePath(path, baseDir, sourceId) {
12181
12319
  const cleaned = cleanSessionPathInput(path);
@@ -12183,8 +12321,8 @@ function resolveIdentitySourcePath(path, baseDir, sourceId) {
12183
12321
  throw new Error(`Identity instruction source path cannot be empty for ${sourceId}.`);
12184
12322
  if (cleaned.includes("\\"))
12185
12323
  throw new Error(`Identity instruction source path must use POSIX separators for ${sourceId}: ${path}`);
12186
- const resolvedPath = isAbsolute3(cleaned) ? resolve4(cleaned) : resolve4(baseDir, cleaned);
12187
- if (!pathIsInside(resolvedPath, resolve4(baseDir))) {
12324
+ const resolvedPath = isAbsolute3(cleaned) ? resolve6(cleaned) : resolve6(baseDir, cleaned);
12325
+ if (!pathIsInside(resolvedPath, resolve6(baseDir))) {
12188
12326
  throw new Error(`Identity instruction source path escapes export directory for ${sourceId}: ${path}`);
12189
12327
  }
12190
12328
  return resolvedPath;
@@ -12272,7 +12410,7 @@ function asStringArray(value) {
12272
12410
  return [];
12273
12411
  return value.filter((item) => typeof item === "string");
12274
12412
  }
12275
- var RAW_STORE_ROOT_ENV = "HASNA_CONFIGS_HOME", ANTIGRAVITY_RULE_FILE_CHAR_LIMIT = 12000, SESSION_RENDERER_OWNER_ID = "instructions-session-renderer", SESSION_RENDER_TOOLS, 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, SESSION_LAYER_RANK, CANONICAL_IDENTITY_EXPORT_PACKAGES;
12413
+ var ANTIGRAVITY_RULE_FILE_CHAR_LIMIT = 12000, SESSION_RENDERER_OWNER_ID = "instructions-session-renderer", SESSION_RENDER_TOOLS, 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, SESSION_LAYER_RANK, CANONICAL_IDENTITY_EXPORT_PACKAGES;
12276
12414
  var init_session_render = __esm(() => {
12277
12415
  init_global_agent_rules_standard();
12278
12416
  init_codewith_shared_todos_storage_standard();
@@ -12281,8 +12419,11 @@ var init_session_render = __esm(() => {
12281
12419
  init_transforms();
12282
12420
  init_asset_plan();
12283
12421
  init_cursor_authority();
12422
+ init_session_authority();
12284
12423
  init_session_render_contract();
12285
12424
  init_session_render_contract();
12425
+ init_raw_store_root();
12426
+ init_raw_store_root();
12286
12427
  SESSION_RENDER_TOOLS = [
12287
12428
  "claude",
12288
12429
  "codex",
@@ -12483,7 +12624,7 @@ var init_session_render = __esm(() => {
12483
12624
  });
12484
12625
 
12485
12626
  // src/lib/instruction-graph.ts
12486
- import { createHash as createHash6 } from "crypto";
12627
+ import { createHash as createHash7 } from "crypto";
12487
12628
  function capability(provider, providerVersionRange, selectedRepresentation, loadingPath, options = {}) {
12488
12629
  return Object.freeze({
12489
12630
  schema: PROVIDER_CAPABILITY_SCHEMA,
@@ -12730,7 +12871,7 @@ function compileInstructionGraph(input) {
12730
12871
  effective_activation: effective.get(configId),
12731
12872
  fallback: row.binding.fallback,
12732
12873
  required: row.binding.required,
12733
- content_sha256: sha2566(config.content),
12874
+ content_sha256: sha2567(config.content),
12734
12875
  dependencies: dependencies.get(configId) ?? []
12735
12876
  };
12736
12877
  });
@@ -12767,7 +12908,7 @@ function compileInstructionGraph(input) {
12767
12908
  diagnostics
12768
12909
  };
12769
12910
  return {
12770
- plan: deepFreeze2({ ...planWithoutHash, source_hash: sha2566(stableJson2(planWithoutHash)) }),
12911
+ plan: deepFreeze2({ ...planWithoutHash, source_hash: sha2567(stableJson2(planWithoutHash)) }),
12771
12912
  sources,
12772
12913
  capability: capability2
12773
12914
  };
@@ -12941,8 +13082,8 @@ function assertExactOnce(units, artifacts) {
12941
13082
  function errorDiagnostic(configId, code, message) {
12942
13083
  return { severity: "error", code, config_id: configId, message };
12943
13084
  }
12944
- function sha2566(value) {
12945
- return createHash6("sha256").update(value).digest("hex");
13085
+ function sha2567(value) {
13086
+ return createHash7("sha256").update(value).digest("hex");
12946
13087
  }
12947
13088
  function stableJson2(value) {
12948
13089
  const canonical = (entry) => Array.isArray(entry) ? entry.map(canonical) : entry && typeof entry === "object" ? Object.fromEntries(Object.entries(entry).sort(([a], [b]) => a.localeCompare(b)).map(([key, child]) => [key, canonical(child)])) : entry;
@@ -13241,37 +13382,6 @@ var init_profiles = __esm(() => {
13241
13382
  init_asset_plan();
13242
13383
  });
13243
13384
 
13244
- // src/db/snapshots.ts
13245
- function createSnapshot(configId, content, version, db) {
13246
- const d = db || getDatabase();
13247
- const id = uuid();
13248
- const ts = now2();
13249
- d.run("INSERT INTO config_snapshots (id, config_id, content, version, created_at) VALUES (?, ?, ?, ?, ?)", [id, configId, content, version, ts]);
13250
- return { id, config_id: configId, content, version, created_at: ts };
13251
- }
13252
- function listSnapshots(configId, db) {
13253
- const d = db || getDatabase();
13254
- return d.query("SELECT * FROM config_snapshots WHERE config_id = ? ORDER BY version DESC").all(configId);
13255
- }
13256
- function getSnapshot(id, db) {
13257
- const d = db || getDatabase();
13258
- return d.query("SELECT * FROM config_snapshots WHERE id = ?").get(id);
13259
- }
13260
- function getSnapshotByVersion(configId, version, db) {
13261
- const d = db || getDatabase();
13262
- return d.query("SELECT * FROM config_snapshots WHERE config_id = ? AND version = ?").get(configId, version);
13263
- }
13264
- function pruneSnapshots(configId, keep = 10, db) {
13265
- const d = db || getDatabase();
13266
- const result = d.run(`DELETE FROM config_snapshots WHERE config_id = ? AND id NOT IN (
13267
- SELECT id FROM config_snapshots WHERE config_id = ? ORDER BY version DESC LIMIT ?
13268
- )`, [configId, configId, keep]);
13269
- return result.changes;
13270
- }
13271
- var init_snapshots = __esm(() => {
13272
- init_database();
13273
- });
13274
-
13275
13385
  // src/db/machines.ts
13276
13386
  import { arch, hostname, type } from "os";
13277
13387
  function currentHostname2() {
@@ -13873,8 +13983,8 @@ var init_config_store = __esm(() => {
13873
13983
  });
13874
13984
 
13875
13985
  // src/lib/session-render-ownership.ts
13876
- import { existsSync as existsSync6, readFileSync as readFileSync4, statSync as statSync3 } from "fs";
13877
- import { dirname as dirname3, join as join7, parse as parse3, relative as relative3, sep } from "path";
13986
+ import { existsSync as existsSync6, readFileSync as readFileSync5, statSync as statSync4 } from "fs";
13987
+ import { dirname as dirname3, join as join9, parse as parse3, relative as relative3, sep } from "path";
13878
13988
  function toSegments(absolutePath2) {
13879
13989
  return absolutePath2.replaceAll("\\", "/").split("/").filter(Boolean);
13880
13990
  }
@@ -13895,7 +14005,7 @@ function readManifestRelativePaths(manifestPath) {
13895
14005
  try {
13896
14006
  if (!existsSync6(manifestPath))
13897
14007
  return null;
13898
- stats = statSync3(manifestPath);
14008
+ stats = statSync4(manifestPath);
13899
14009
  } catch {
13900
14010
  return null;
13901
14011
  }
@@ -13905,7 +14015,7 @@ function readManifestRelativePaths(manifestPath) {
13905
14015
  }
13906
14016
  let manifest;
13907
14017
  try {
13908
- manifest = JSON.parse(readFileSync4(manifestPath, "utf-8"));
14018
+ manifest = JSON.parse(readFileSync5(manifestPath, "utf-8"));
13909
14019
  } catch {
13910
14020
  return null;
13911
14021
  }
@@ -13922,7 +14032,7 @@ function sessionRenderManifestClaimsPath(absolutePath2) {
13922
14032
  const root = parse3(absolutePath2).root;
13923
14033
  let home = dirname3(absolutePath2);
13924
14034
  for (let depth = 0;depth < MANIFEST_ANCESTOR_LIMIT; depth += 1) {
13925
- const manifestPath = join7(home, ...SESSION_RENDER_MANIFEST_RELATIVE_PATH.split("/"));
14035
+ const manifestPath = join9(home, ...SESSION_RENDER_MANIFEST_RELATIVE_PATH.split("/"));
13926
14036
  const relativePaths = readManifestRelativePaths(manifestPath);
13927
14037
  if (relativePaths) {
13928
14038
  const claimed = relative3(home, absolutePath2).split(sep).join("/");
@@ -13949,25 +14059,25 @@ var init_session_render_ownership = __esm(() => {
13949
14059
  // src/lib/apply.ts
13950
14060
  var exports_apply = {};
13951
14061
  __export(exports_apply, {
13952
- previewConfigs: () => previewConfigs,
13953
- normalizeTargetPath: () => normalizeTargetPath,
13954
- getConfigHome: () => getConfigHome,
13955
- expandPath: () => expandPath,
13956
- applyConfigsWithReport: () => applyConfigsWithReport,
14062
+ applyConfig: () => applyConfig,
13957
14063
  applyConfigs: () => applyConfigs,
13958
- applyConfig: () => applyConfig
14064
+ applyConfigsWithReport: () => applyConfigsWithReport,
14065
+ expandPath: () => expandPath,
14066
+ getConfigHome: () => getConfigHome,
14067
+ normalizeTargetPath: () => normalizeTargetPath,
14068
+ previewConfigs: () => previewConfigs
13959
14069
  });
13960
- import { existsSync as existsSync7, mkdirSync as mkdirSync3, readFileSync as readFileSync5, realpathSync as realpathSync2, writeFileSync as writeFileSync2 } from "fs";
13961
- import { basename as basename4, dirname as dirname4, join as join8, resolve as resolve5 } from "path";
13962
- import { homedir as homedir5 } from "os";
14070
+ import { existsSync as existsSync7, mkdirSync as mkdirSync3, readFileSync as readFileSync6, realpathSync as realpathSync2, writeFileSync as writeFileSync2 } from "fs";
14071
+ import { basename as basename4, dirname as dirname4, join as join10, resolve as resolve7 } from "path";
14072
+ import { homedir as homedir6 } from "os";
13963
14073
  function getConfigHome() {
13964
- return process.env["CONFIGS_HOME"] || process.env["HOME"] || homedir5();
14074
+ return process.env["CONFIGS_HOME"] || process.env["HOME"] || homedir6();
13965
14075
  }
13966
14076
  function expandPath(p) {
13967
14077
  if (p.startsWith("~/")) {
13968
- return resolve5(getConfigHome(), p.slice(2));
14078
+ return resolve7(getConfigHome(), p.slice(2));
13969
14079
  }
13970
- return resolve5(p);
14080
+ return resolve7(p);
13971
14081
  }
13972
14082
  function normalizeTargetPath(p) {
13973
14083
  const expanded = expandPath(p);
@@ -13979,7 +14089,7 @@ function normalizeTargetPath(p) {
13979
14089
  while (true) {
13980
14090
  if (existsSync7(current)) {
13981
14091
  try {
13982
- return resolve5(realpathSync2(current), ...missingSegments);
14092
+ return resolve7(realpathSync2(current), ...missingSegments);
13983
14093
  } catch {
13984
14094
  return expanded;
13985
14095
  }
@@ -14007,8 +14117,9 @@ async function writeConfigResult(config, targetPath, content, opts, meta = {}) {
14007
14117
  throw new ConfigApplyError(`Antigravity rule file ${renderedTargetPath} is ${renderedContent.length} characters; split it before applying because Antigravity limits rule files to ${ANTIGRAVITY_RULE_FILE_CHAR_LIMIT} characters.`);
14008
14118
  }
14009
14119
  const path = expandPath(renderedTargetPath);
14010
- const previousContent = existsSync7(path) ? readFileSync5(path, "utf-8") : null;
14011
- const changed = previousContent !== renderedContent;
14120
+ const renderedForTarget = isCursorGlobalAuthorityPath(path) ? stampCursorGlobalAuthorityMarker(renderedContent) : renderedContent;
14121
+ const previousContent = existsSync7(path) ? readFileSync6(path, "utf-8") : null;
14122
+ const changed = previousContent !== renderedForTarget;
14012
14123
  if (!opts.dryRun) {
14013
14124
  const dir = dirname4(path);
14014
14125
  if (!existsSync7(dir)) {
@@ -14018,13 +14129,13 @@ async function writeConfigResult(config, targetPath, content, opts, meta = {}) {
14018
14129
  const store = opts.store ?? resolveConfigStore();
14019
14130
  await store.createSnapshot(config.id, previousContent, config.version);
14020
14131
  }
14021
- writeFileSync2(path, renderedContent, "utf-8");
14132
+ writeFileSync2(path, renderedForTarget, "utf-8");
14022
14133
  }
14023
14134
  return {
14024
14135
  config_id: config.id,
14025
14136
  path,
14026
14137
  previous_content: previousContent,
14027
- new_content: renderedContent,
14138
+ new_content: renderedForTarget,
14028
14139
  dry_run: opts.dryRun ?? false,
14029
14140
  changed,
14030
14141
  primary_changed: changed,
@@ -14047,7 +14158,7 @@ function wouldDestroyACredential(targetPath, renderedContent, format) {
14047
14158
  const path = expandPath(targetPath);
14048
14159
  if (!existsSync7(path))
14049
14160
  return [];
14050
- current = readFileSync5(path, "utf-8");
14161
+ current = readFileSync6(path, "utf-8");
14051
14162
  } catch {
14052
14163
  return secretTokens;
14053
14164
  }
@@ -14371,7 +14482,7 @@ function sessionRendererOwnsCanonicalTarget(normalized, opts) {
14371
14482
  getConfigHome(),
14372
14483
  opts.vars?.["HOME_DIR"]
14373
14484
  ].filter((home) => typeof home === "string" && home.length > 0));
14374
- if ([...homes].some((home) => SESSION_RENDER_OWNED_CONFIG_TARGETS.some((relativePath) => normalized === normalizeTargetPath(join8(home, ...relativePath.split("/"))))))
14485
+ if ([...homes].some((home) => SESSION_RENDER_OWNED_CONFIG_TARGETS.some((relativePath) => normalized === normalizeTargetPath(join10(home, ...relativePath.split("/"))))))
14375
14486
  return true;
14376
14487
  return sessionRenderOwnsPath(normalized);
14377
14488
  }
@@ -14385,12 +14496,13 @@ var init_apply = __esm(() => {
14385
14496
  init_redact();
14386
14497
  init_template();
14387
14498
  init_transforms();
14499
+ init_cursor_authority();
14388
14500
  });
14389
14501
 
14390
14502
  // src/lib/sync-dir.ts
14391
- import { existsSync as existsSync8, readdirSync, readFileSync as readFileSync6, statSync as statSync4 } from "fs";
14392
- import { join as join9, relative as relative4 } from "path";
14393
- import { homedir as homedir6 } from "os";
14503
+ import { existsSync as existsSync8, readdirSync, readFileSync as readFileSync7, statSync as statSync5 } from "fs";
14504
+ import { join as join11, relative as relative4 } from "path";
14505
+ import { homedir as homedir7 } from "os";
14394
14506
  function shouldSkip(p) {
14395
14507
  return SKIP.some((s) => p.includes(s));
14396
14508
  }
@@ -14399,9 +14511,9 @@ async function syncFromDir(dir, opts = {}) {
14399
14511
  const absDir = expandPath(dir);
14400
14512
  if (!existsSync8(absDir))
14401
14513
  return { added: 0, updated: 0, unchanged: 0, skipped: [`Not found: ${absDir}`] };
14402
- const files = opts.recursive !== false ? walkDir(absDir) : readdirSync(absDir).map((f) => join9(absDir, f)).filter((f) => statSync4(f).isFile());
14514
+ const files = opts.recursive !== false ? walkDir(absDir) : readdirSync(absDir).map((f) => join11(absDir, f)).filter((f) => statSync5(f).isFile());
14403
14515
  const result = { added: 0, updated: 0, unchanged: 0, skipped: [] };
14404
- const home = homedir6();
14516
+ const home = homedir7();
14405
14517
  const allConfigs = await store.listConfigs();
14406
14518
  for (const file of files) {
14407
14519
  if (shouldSkip(file)) {
@@ -14409,7 +14521,7 @@ async function syncFromDir(dir, opts = {}) {
14409
14521
  continue;
14410
14522
  }
14411
14523
  try {
14412
- const content = readFileSync6(file, "utf-8");
14524
+ const content = readFileSync7(file, "utf-8");
14413
14525
  if (content.length > 500000) {
14414
14526
  result.skipped.push(file + " (too large)");
14415
14527
  continue;
@@ -14435,7 +14547,7 @@ async function syncFromDir(dir, opts = {}) {
14435
14547
  }
14436
14548
  async function syncToDir(dir, opts = {}) {
14437
14549
  const store = opts.store ?? resolveConfigStore();
14438
- const home = homedir6();
14550
+ const home = homedir7();
14439
14551
  const absDir = expandPath(dir);
14440
14552
  const normalized = dir.startsWith("~/") ? dir : absDir.replace(home, "~");
14441
14553
  const configs = (await store.listConfigs()).filter((c) => c.target_path && (c.target_path.startsWith(normalized) || c.target_path.startsWith(absDir)));
@@ -14459,7 +14571,7 @@ async function syncToDir(dir, opts = {}) {
14459
14571
  }
14460
14572
  function walkDir(dir, files = []) {
14461
14573
  for (const entry of readdirSync(dir, { withFileTypes: true })) {
14462
- const full = join9(dir, entry.name);
14574
+ const full = join11(dir, entry.name);
14463
14575
  if (shouldSkip(full))
14464
14576
  continue;
14465
14577
  if (entry.isDirectory())
@@ -14480,21 +14592,21 @@ var init_sync_dir = __esm(() => {
14480
14592
  // src/lib/sync.ts
14481
14593
  var exports_sync = {};
14482
14594
  __export(exports_sync, {
14483
- syncToDisk: () => syncToDisk,
14484
- syncToDir: () => syncToDir,
14485
- syncProject: () => syncProject,
14486
- syncKnown: () => syncKnown,
14487
- syncFromDir: () => syncFromDir,
14488
- diffConfig: () => diffConfig,
14489
- detectFormat: () => detectFormat,
14490
- detectCategory: () => detectCategory,
14491
- detectAgent: () => detectAgent,
14492
- PROJECT_CONFIG_FILES: () => PROJECT_CONFIG_FILES,
14595
+ CLAUDE_PROMPT_OUTPUTS: () => CLAUDE_PROMPT_OUTPUTS,
14493
14596
  KNOWN_CONFIGS: () => KNOWN_CONFIGS,
14494
- CLAUDE_PROMPT_OUTPUTS: () => CLAUDE_PROMPT_OUTPUTS
14597
+ PROJECT_CONFIG_FILES: () => PROJECT_CONFIG_FILES,
14598
+ detectAgent: () => detectAgent,
14599
+ detectCategory: () => detectCategory,
14600
+ detectFormat: () => detectFormat,
14601
+ diffConfig: () => diffConfig,
14602
+ syncFromDir: () => syncFromDir,
14603
+ syncKnown: () => syncKnown,
14604
+ syncProject: () => syncProject,
14605
+ syncToDir: () => syncToDir,
14606
+ syncToDisk: () => syncToDisk
14495
14607
  });
14496
- import { existsSync as existsSync9, readdirSync as readdirSync2, readFileSync as readFileSync7 } from "fs";
14497
- import { basename as basename5, extname as extname3, join as join10 } from "path";
14608
+ import { existsSync as existsSync9, readdirSync as readdirSync2, readFileSync as readFileSync8 } from "fs";
14609
+ import { basename as basename5, extname as extname3, join as join12 } from "path";
14498
14610
  function claudeRuleOutputs(fileName) {
14499
14611
  const stem = basename5(fileName, extname3(fileName));
14500
14612
  return [
@@ -14558,11 +14670,11 @@ async function syncProject(opts) {
14558
14670
  const allConfigs = await store.listConfigs();
14559
14671
  const machine = detectMachineContext();
14560
14672
  for (const pf of PROJECT_CONFIG_FILES) {
14561
- const abs = join10(absDir, pf.file);
14673
+ const abs = join12(absDir, pf.file);
14562
14674
  if (!existsSync9(abs))
14563
14675
  continue;
14564
14676
  try {
14565
- const rawContent = readFileSync7(abs, "utf-8");
14677
+ const rawContent = readFileSync8(abs, "utf-8");
14566
14678
  if (rawContent.length > 500000) {
14567
14679
  result.skipped.push(pf.file);
14568
14680
  continue;
@@ -14591,20 +14703,20 @@ async function syncProject(opts) {
14591
14703
  }
14592
14704
  }
14593
14705
  for (const ruleDir of [
14594
- { dir: join10(absDir, ".claude", "rules"), agent: "claude", namePrefix: "rules" },
14595
- { dir: join10(absDir, ".agents", "rules"), agent: "antigravity", namePrefix: "antigravity-rules" },
14596
- { dir: join10(absDir, ".cursor", "rules"), agent: "cursor", namePrefix: "cursor-rules" },
14597
- { dir: join10(absDir, ".github", "instructions"), agent: "copilot", namePrefix: "copilot-instructions" },
14598
- { dir: join10(absDir, ".devin", "rules"), agent: "devin", namePrefix: "devin-rules" },
14599
- { dir: join10(absDir, ".windsurf", "rules"), agent: "windsurf-legacy", namePrefix: "windsurf-rules" },
14600
- { dir: join10(absDir, ".clinerules"), agent: "cline", namePrefix: "cline-rules" }
14706
+ { dir: join12(absDir, ".claude", "rules"), agent: "claude", namePrefix: "rules" },
14707
+ { dir: join12(absDir, ".agents", "rules"), agent: "antigravity", namePrefix: "antigravity-rules" },
14708
+ { dir: join12(absDir, ".cursor", "rules"), agent: "cursor", namePrefix: "cursor-rules" },
14709
+ { dir: join12(absDir, ".github", "instructions"), agent: "copilot", namePrefix: "copilot-instructions" },
14710
+ { dir: join12(absDir, ".devin", "rules"), agent: "devin", namePrefix: "devin-rules" },
14711
+ { dir: join12(absDir, ".windsurf", "rules"), agent: "windsurf-legacy", namePrefix: "windsurf-rules" },
14712
+ { dir: join12(absDir, ".clinerules"), agent: "cline", namePrefix: "cline-rules" }
14601
14713
  ]) {
14602
14714
  if (!existsSync9(ruleDir.dir))
14603
14715
  continue;
14604
14716
  const mdFiles = readdirSync2(ruleDir.dir).filter((f) => f.endsWith(".md") || f.endsWith(".mdc"));
14605
14717
  for (const f of mdFiles) {
14606
- const abs = join10(ruleDir.dir, f);
14607
- const raw = readFileSync7(abs, "utf-8");
14718
+ const abs = join12(ruleDir.dir, f);
14719
+ const raw = readFileSync8(abs, "utf-8");
14608
14720
  const redacted = redactContent(raw, "markdown");
14609
14721
  const machineAware = templateizeMachineContent(redacted.content, machine);
14610
14722
  const content = machineAware.content;
@@ -14650,13 +14762,13 @@ async function syncKnown(opts = {}) {
14650
14762
  const extensions = known.rulesExtensions ?? [".md", ".mdc"];
14651
14763
  const ruleFiles = readdirSync2(absDir).filter((f) => extensions.some((ext) => f.endsWith(ext)));
14652
14764
  for (const f of ruleFiles) {
14653
- const abs2 = join10(absDir, f);
14765
+ const abs2 = join12(absDir, f);
14654
14766
  const targetPath = abs2.replace(home, "~");
14655
14767
  if (existingOutputOwners.has(normalizeTargetPath(targetPath)) || isKnownGeneratedTargetPath(targetPath)) {
14656
14768
  result.skipped.push(`${targetPath} (generated output)`);
14657
14769
  continue;
14658
14770
  }
14659
- const raw = readFileSync7(abs2, "utf-8");
14771
+ const raw = readFileSync8(abs2, "utf-8");
14660
14772
  const redacted = redactContent(raw, "markdown");
14661
14773
  const machineAware = templateizeMachineContent(redacted.content, machine);
14662
14774
  const content = machineAware.content;
@@ -14689,7 +14801,7 @@ async function syncKnown(opts = {}) {
14689
14801
  continue;
14690
14802
  }
14691
14803
  try {
14692
- const rawContent = normalizeKnownConfigSource(known, readFileSync7(abs, "utf-8"));
14804
+ const rawContent = normalizeKnownConfigSource(known, readFileSync8(abs, "utf-8"));
14693
14805
  if (rawContent.length > 500000) {
14694
14806
  result.skipped.push(known.path + " (too large)");
14695
14807
  continue;
@@ -14792,7 +14904,7 @@ function buildDiff(expectedContent, targetPath, storedFormat, showSecrets) {
14792
14904
  const path = expandPath(targetPath);
14793
14905
  if (!existsSync9(path))
14794
14906
  return `(file not found on disk: ${path})`;
14795
- const diskContent = readFileSync7(path, "utf-8");
14907
+ const diskContent = readFileSync8(path, "utf-8");
14796
14908
  if (diskContent === expectedContent)
14797
14909
  return "(no diff \u2014 identical)";
14798
14910
  const format = redactFormatForTarget(targetPath, storedFormat);
@@ -15025,18 +15137,18 @@ __export(exports_package_manager_guard, {
15025
15137
  scanPackageManagerSecrets: () => scanPackageManagerSecrets
15026
15138
  });
15027
15139
  import { execFileSync as execFileSync2 } from "child_process";
15028
- import { existsSync as existsSync15, lstatSync as lstatSync4, readdirSync as readdirSync4, readFileSync as readFileSync12 } from "fs";
15029
- import { homedir as homedir7 } from "os";
15030
- import { basename as basename6, dirname as dirname7, isAbsolute as isAbsolute5, join as join15, relative as relative6, resolve as resolve9 } from "path";
15140
+ import { existsSync as existsSync16, lstatSync as lstatSync6, readdirSync as readdirSync4, readFileSync as readFileSync14 } from "fs";
15141
+ import { homedir as homedir9 } from "os";
15142
+ import { basename as basename6, dirname as dirname8, isAbsolute as isAbsolute5, join as join18, relative as relative7, resolve as resolve12 } from "path";
15031
15143
  function scanPackageManagerSecrets(options = {}) {
15032
- const cwd = options.cwd ? resolve9(options.cwd) : process.cwd();
15033
- const roots = (options.roots && options.roots.length > 0 ? options.roots : [cwd]).map((root) => resolve9(cwd, root));
15144
+ const cwd = options.cwd ? resolve12(options.cwd) : process.cwd();
15145
+ const roots = (options.roots && options.roots.length > 0 ? options.roots : [cwd]).map((root) => resolve12(cwd, root));
15034
15146
  const findings = [];
15035
15147
  let scannedFiles = 0;
15036
15148
  for (const root of roots) {
15037
- if (!existsSync15(root))
15149
+ if (!existsSync16(root))
15038
15150
  continue;
15039
- const stat = lstatSync4(root);
15151
+ const stat = lstatSync6(root);
15040
15152
  if (stat.isFile()) {
15041
15153
  if (!shouldScanRepoFile(root))
15042
15154
  continue;
@@ -15044,14 +15156,14 @@ function scanPackageManagerSecrets(options = {}) {
15044
15156
  if (text === null)
15045
15157
  continue;
15046
15158
  scannedFiles++;
15047
- findings.push(...scanFile(root, text, classifyRepoFile(root), isTrackedFile(root), dirname7(root)));
15159
+ findings.push(...scanFile(root, text, classifyRepoFile(root), isTrackedFile(root), dirname8(root)));
15048
15160
  continue;
15049
15161
  }
15050
15162
  if (!stat.isDirectory())
15051
15163
  continue;
15052
15164
  const tracked = trackedFiles(root);
15053
15165
  for (const file of collectRepoFiles(root)) {
15054
- const rel = toPosix(relative6(root, file));
15166
+ const rel = toPosix(relative7(root, file));
15055
15167
  const isTracked = tracked.has(rel);
15056
15168
  const text = readTextFile(file);
15057
15169
  if (text === null)
@@ -15061,10 +15173,10 @@ function scanPackageManagerSecrets(options = {}) {
15061
15173
  }
15062
15174
  }
15063
15175
  if (options.includeHome) {
15064
- const home = homedir7();
15176
+ const home = homedir9();
15065
15177
  for (const name of HOME_FILES) {
15066
- const file = join15(home, name);
15067
- if (!existsSync15(file))
15178
+ const file = join18(home, name);
15179
+ if (!existsSync16(file))
15068
15180
  continue;
15069
15181
  const text = readTextFile(file);
15070
15182
  if (text === null)
@@ -15088,12 +15200,12 @@ function collectRepoFiles(root) {
15088
15200
  if (entry.isDirectory()) {
15089
15201
  if (SKIP_DIRS.has(entry.name))
15090
15202
  continue;
15091
- visit(join15(dir, entry.name));
15203
+ visit(join18(dir, entry.name));
15092
15204
  continue;
15093
15205
  }
15094
15206
  if (!entry.isFile())
15095
15207
  continue;
15096
- const file = join15(dir, entry.name);
15208
+ const file = join18(dir, entry.name);
15097
15209
  if (shouldScanRepoFile(file))
15098
15210
  out.push(file);
15099
15211
  }
@@ -15128,10 +15240,10 @@ function isNpmrcName(name) {
15128
15240
  }
15129
15241
  function readTextFile(file) {
15130
15242
  try {
15131
- const stat = lstatSync4(file);
15243
+ const stat = lstatSync6(file);
15132
15244
  if (!stat.isFile() || stat.size > 5000000)
15133
15245
  return null;
15134
- const buf = readFileSync12(file);
15246
+ const buf = readFileSync14(file);
15135
15247
  if (buf.includes(0))
15136
15248
  return null;
15137
15249
  return buf.toString("utf-8");
@@ -15331,11 +15443,11 @@ function trackedFiles(root) {
15331
15443
  }
15332
15444
  function isTrackedFile(file) {
15333
15445
  try {
15334
- const repoRoot = execFileSync2("git", ["-C", dirname7(file), "rev-parse", "--show-toplevel"], {
15446
+ const repoRoot = execFileSync2("git", ["-C", dirname8(file), "rev-parse", "--show-toplevel"], {
15335
15447
  encoding: "utf-8",
15336
15448
  stdio: ["ignore", "pipe", "ignore"]
15337
15449
  }).trim();
15338
- const rel = toPosix(relative6(repoRoot, file));
15450
+ const rel = toPosix(relative7(repoRoot, file));
15339
15451
  execFileSync2("git", ["-C", repoRoot, "ls-files", "--error-unmatch", "--", rel], {
15340
15452
  stdio: ["ignore", "ignore", "ignore"]
15341
15453
  });
@@ -15361,13 +15473,13 @@ function stripInlineComment(value) {
15361
15473
  return value.replace(/\s[#;].*$/, "").trim();
15362
15474
  }
15363
15475
  function displayPath(file, root) {
15364
- const home = homedir7();
15476
+ const home = homedir9();
15365
15477
  if (root === home && (file === home || file.startsWith(home + "/")))
15366
- return "~/" + toPosix(relative6(home, file));
15478
+ return "~/" + toPosix(relative7(home, file));
15367
15479
  if (isAbsolute5(root) && file.startsWith(root + "/"))
15368
- return toPosix(relative6(root, file));
15480
+ return toPosix(relative7(root, file));
15369
15481
  if (file === home || file.startsWith(home + "/"))
15370
- return "~/" + toPosix(relative6(home, file));
15482
+ return "~/" + toPosix(relative7(home, file));
15371
15483
  return file;
15372
15484
  }
15373
15485
  function toPosix(path) {
@@ -15412,7 +15524,7 @@ var init_package_manager_guard = __esm(() => {
15412
15524
  ];
15413
15525
  });
15414
15526
 
15415
- // ../../node_modules/.bun/@hasna+events@0.1.15/node_modules/@hasna/events/dist/commander.js
15527
+ // ../events/dist/commander.js
15416
15528
  import { chmod, mkdir, readFile, rename, writeFile } from "fs/promises";
15417
15529
  import { Buffer as Buffer2 } from "buffer";
15418
15530
  import { existsSync } from "fs";
@@ -16613,9 +16725,9 @@ var {
16613
16725
  // src/cli/index.tsx
16614
16726
  init_apply();
16615
16727
  import chalk from "chalk";
16616
- import { existsSync as existsSync16, lstatSync as lstatSync5, readFileSync as readFileSync13, readSync, writeSync } from "fs";
16617
- import { homedir as homedir8 } from "os";
16618
- import { basename as basename7, join as join16, resolve as resolve10 } from "path";
16728
+ import { existsSync as existsSync17, lstatSync as lstatSync7, readFileSync as readFileSync15, readSync, writeSync } from "fs";
16729
+ import { homedir as homedir10 } from "os";
16730
+ import { basename as basename7, join as join19, resolve as resolve13 } from "path";
16619
16731
 
16620
16732
  // src/lib/config-target-identity.ts
16621
16733
  init_apply();
@@ -16662,14 +16774,14 @@ init_redact();
16662
16774
  // src/lib/export.ts
16663
16775
  init_config_store();
16664
16776
  import { existsSync as existsSync10, mkdirSync as mkdirSync4, rmSync as rmSync3, writeFileSync as writeFileSync3 } from "fs";
16665
- import { join as join11, resolve as resolve6 } from "path";
16777
+ import { join as join13, resolve as resolve8 } from "path";
16666
16778
  import { tmpdir } from "os";
16667
16779
  async function exportConfigs(outputPath, opts = {}) {
16668
16780
  const store = opts.store ?? resolveConfigStore();
16669
16781
  const configs = await store.listConfigs(opts.filter);
16670
- const absOutput = resolve6(outputPath);
16671
- const tmpDir = join11(tmpdir(), `configs-export-${Date.now()}`);
16672
- const contentsDir = join11(tmpDir, "contents");
16782
+ const absOutput = resolve8(outputPath);
16783
+ const tmpDir = join13(tmpdir(), `configs-export-${Date.now()}`);
16784
+ const contentsDir = join13(tmpDir, "contents");
16673
16785
  try {
16674
16786
  mkdirSync4(contentsDir, { recursive: true });
16675
16787
  const manifest = {
@@ -16677,10 +16789,10 @@ async function exportConfigs(outputPath, opts = {}) {
16677
16789
  exported_at: new Date().toISOString(),
16678
16790
  configs: configs.map(({ content: _content, ...meta }) => meta)
16679
16791
  };
16680
- writeFileSync3(join11(tmpDir, "manifest.json"), JSON.stringify(manifest, null, 2), "utf-8");
16792
+ writeFileSync3(join13(tmpDir, "manifest.json"), JSON.stringify(manifest, null, 2), "utf-8");
16681
16793
  for (const config of configs) {
16682
16794
  const fileName = `${config.slug}.${config.format === "text" ? "txt" : config.format}`;
16683
- writeFileSync3(join11(contentsDir, fileName), config.content, "utf-8");
16795
+ writeFileSync3(join13(contentsDir, fileName), config.content, "utf-8");
16684
16796
  }
16685
16797
  const proc = Bun.spawn(["tar", "czf", absOutput, "-C", tmpDir, "."], {
16686
16798
  stdout: "pipe",
@@ -16701,14 +16813,14 @@ async function exportConfigs(outputPath, opts = {}) {
16701
16813
 
16702
16814
  // src/lib/import.ts
16703
16815
  init_config_store();
16704
- import { existsSync as existsSync11, mkdirSync as mkdirSync5, readFileSync as readFileSync8, rmSync as rmSync4 } from "fs";
16705
- import { join as join12, resolve as resolve7 } from "path";
16816
+ import { existsSync as existsSync11, mkdirSync as mkdirSync5, readFileSync as readFileSync9, rmSync as rmSync4 } from "fs";
16817
+ import { join as join14, resolve as resolve9 } from "path";
16706
16818
  import { tmpdir as tmpdir2 } from "os";
16707
16819
  async function importConfigs(bundlePath, opts = {}) {
16708
16820
  const store = opts.store ?? resolveConfigStore();
16709
16821
  const conflict = opts.conflict ?? "skip";
16710
- const absPath = resolve7(bundlePath);
16711
- const tmpDir = join12(tmpdir2(), `configs-import-${Date.now()}`);
16822
+ const absPath = resolve9(bundlePath);
16823
+ const tmpDir = join14(tmpdir2(), `configs-import-${Date.now()}`);
16712
16824
  const result = { created: 0, updated: 0, skipped: 0, errors: [] };
16713
16825
  try {
16714
16826
  mkdirSync5(tmpDir, { recursive: true });
@@ -16721,15 +16833,15 @@ async function importConfigs(bundlePath, opts = {}) {
16721
16833
  const stderr = await new Response(proc.stderr).text();
16722
16834
  throw new Error(`tar extraction failed: ${stderr}`);
16723
16835
  }
16724
- const manifestPath = join12(tmpDir, "manifest.json");
16836
+ const manifestPath = join14(tmpDir, "manifest.json");
16725
16837
  if (!existsSync11(manifestPath))
16726
16838
  throw new Error("Invalid bundle: missing manifest.json");
16727
- const manifest = JSON.parse(readFileSync8(manifestPath, "utf-8"));
16839
+ const manifest = JSON.parse(readFileSync9(manifestPath, "utf-8"));
16728
16840
  for (const meta of manifest.configs) {
16729
16841
  try {
16730
16842
  const ext = meta.format === "text" ? "txt" : meta.format;
16731
- const contentFile = join12(tmpDir, "contents", `${meta.slug}.${ext}`);
16732
- const content = existsSync11(contentFile) ? readFileSync8(contentFile, "utf-8") : "";
16843
+ const contentFile = join14(tmpDir, "contents", `${meta.slug}.${ext}`);
16844
+ const content = existsSync11(contentFile) ? readFileSync9(contentFile, "utf-8") : "";
16733
16845
  let existing = null;
16734
16846
  try {
16735
16847
  existing = await store.getConfig(meta.slug);
@@ -16777,16 +16889,17 @@ init_machine();
16777
16889
  init_project_context();
16778
16890
  init_session_render();
16779
16891
  init_cursor_authority();
16780
- import { createHash as createHash7, randomUUID as randomUUID7 } from "crypto";
16892
+ init_session_authority();
16893
+ import { createHash as createHash8, randomUUID as randomUUID7 } from "crypto";
16781
16894
  import {
16782
16895
  existsSync as existsSync12,
16783
- lstatSync as lstatSync3,
16896
+ lstatSync as lstatSync4,
16784
16897
  mkdirSync as mkdirSync6,
16785
- readFileSync as readFileSync9,
16898
+ readFileSync as readFileSync10,
16786
16899
  readdirSync as readdirSync3,
16787
- statSync as statSync5
16900
+ statSync as statSync6
16788
16901
  } from "fs";
16789
- import { dirname as dirname5, isAbsolute as isAbsolute4, join as join13, parse as parse4, relative as relative5, resolve as resolve8 } from "path";
16902
+ import { dirname as dirname5, isAbsolute as isAbsolute4, join as join15, parse as parse4, relative as relative5, resolve as resolve10 } from "path";
16790
16903
 
16791
16904
  class SessionApplyError extends Error {
16792
16905
  constructor(message) {
@@ -16807,6 +16920,7 @@ function applySessionRenderUnlocked(plan, options, coordination) {
16807
16920
  }
16808
16921
  assertCursorAuthorityUnchanged(plan);
16809
16922
  const targetHome = assertSafeTargetHome(plan.targetHome);
16923
+ assertClaudeAuthorityStillClear(plan, targetHome);
16810
16924
  const payloadFiles = [...plan.files, ...plan.assetFiles ?? []];
16811
16925
  const files = [...payloadFiles, plan.manifestFile];
16812
16926
  const manifestPath = resolvePlannedFilePath(plan, plan.manifestFile, targetHome);
@@ -16907,6 +17021,15 @@ function assertCursorAuthorityUnchanged(plan) {
16907
17021
  throw new SessionApplyError("Cursor fixed global authority changed after planning; refusing to apply a stale render plan.");
16908
17022
  }
16909
17023
  }
17024
+ function assertClaudeAuthorityStillClear(plan, targetHome) {
17025
+ if (plan.tool !== "claude" || plan.targetKind === "blocked")
17026
+ return;
17027
+ const conflicts = detectClaudeAuthorityConflicts(targetHome);
17028
+ if (conflicts.length === 0)
17029
+ return;
17030
+ const summary = conflicts.map((conflict) => `${conflict.relativePath}: ${conflict.reason}`).join("; ");
17031
+ throw new SessionApplyError(`Claude authority changed after planning; refusing to apply: ${summary}`);
17032
+ }
16910
17033
  function ensureSessionTargetHome(targetHome) {
16911
17034
  if (!existsSync12(targetHome))
16912
17035
  mkdirSync6(targetHome, { recursive: true, mode: 448 });
@@ -16914,7 +17037,7 @@ function ensureSessionTargetHome(targetHome) {
16914
17037
  }
16915
17038
  function checkSessionRenderDrift(targetHome, manifestPath) {
16916
17039
  const safeTargetHome = assertSafeTargetHome(targetHome);
16917
- const resolvedManifestPath = manifestPath ? resolveManifestRelativePath(relative5(safeTargetHome, resolve8(manifestPath)), safeTargetHome) : resolve8(safeTargetHome, ".hasna", "session-render-manifest.json");
17040
+ const resolvedManifestPath = manifestPath ? resolveManifestRelativePath(relative5(safeTargetHome, resolve10(manifestPath)), safeTargetHome) : resolve10(safeTargetHome, ".hasna", "session-render-manifest.json");
16918
17041
  const checkedAt = new Date().toISOString();
16919
17042
  const previousManifest = readPreviousManifest(resolvedManifestPath);
16920
17043
  if (!previousManifest) {
@@ -16941,7 +17064,7 @@ function checkSessionRenderDrift(targetHome, manifestPath) {
16941
17064
  });
16942
17065
  continue;
16943
17066
  }
16944
- const actualSha256 = sha2567(readFileSync9(target, "utf-8"));
17067
+ const actualSha256 = sha2568(readFileSync10(target, "utf-8"));
16945
17068
  if (actualSha256 !== file.sha256) {
16946
17069
  drifted.push({
16947
17070
  path: target,
@@ -16964,7 +17087,7 @@ function checkSessionRenderDrift(targetHome, manifestPath) {
16964
17087
  function restoreSessionRenderSnapshot(snapshotPath, options = {}) {
16965
17088
  const snapshot = readSessionRenderSnapshot(snapshotPath);
16966
17089
  const targetHome = assertSafeTargetHome(snapshot.targetHome);
16967
- const resolvedSnapshotPath = resolve8(snapshotPath);
17090
+ const resolvedSnapshotPath = resolve10(snapshotPath);
16968
17091
  const snapshotRelativePath = relative5(targetHome, resolvedSnapshotPath);
16969
17092
  if (snapshotRelativePath === "" || snapshotRelativePath === ".." || snapshotRelativePath.startsWith("../") || isAbsolute4(snapshotRelativePath)) {
16970
17093
  throw new SessionApplyError("Session snapshot must be stored inside its target home.");
@@ -17082,19 +17205,19 @@ function requiredRestoreHash(file) {
17082
17205
  return file.previousSha256;
17083
17206
  }
17084
17207
  function readSessionRenderSnapshot(snapshotPath) {
17085
- const resolved = resolve8(snapshotPath);
17208
+ const resolved = resolve10(snapshotPath);
17086
17209
  if (!existsSync12(resolved))
17087
17210
  throw new SessionApplyError(`Session snapshot not found: ${snapshotPath}`);
17088
- const stat = lstatSync3(resolved);
17211
+ const stat = lstatSync4(resolved);
17089
17212
  if (stat.isSymbolicLink() || !stat.isFile()) {
17090
17213
  throw new SessionApplyError(`Session snapshot is not a regular file: ${snapshotPath}`);
17091
17214
  }
17092
- if (statSync5(resolved).size > 32 * 1024 * 1024) {
17215
+ if (statSync6(resolved).size > 32 * 1024 * 1024) {
17093
17216
  throw new SessionApplyError(`Session snapshot exceeds the 32 MiB restore limit: ${snapshotPath}`);
17094
17217
  }
17095
17218
  let parsed;
17096
17219
  try {
17097
- parsed = JSON.parse(readFileSync9(resolved, "utf8"));
17220
+ parsed = JSON.parse(readFileSync10(resolved, "utf8"));
17098
17221
  } catch {
17099
17222
  throw new SessionApplyError(`Session snapshot is not valid JSON: ${snapshotPath}`);
17100
17223
  }
@@ -17116,7 +17239,7 @@ function readSessionRenderSnapshot(snapshotPath) {
17116
17239
  const previousManifest = snapshot.previousManifest;
17117
17240
  const previousFiles = new Map;
17118
17241
  for (const file of snapshot.files) {
17119
- if (!file || typeof file.relativePath !== "string" || typeof file.path !== "string" || typeof file.sha256 !== "string" || typeof file.content !== "string" || sha2567(file.content) !== file.sha256) {
17242
+ if (!file || typeof file.relativePath !== "string" || typeof file.path !== "string" || typeof file.sha256 !== "string" || typeof file.content !== "string" || sha2568(file.content) !== file.sha256) {
17120
17243
  throw new SessionApplyError(`Session snapshot previous file metadata is invalid: ${snapshotPath}`);
17121
17244
  }
17122
17245
  resolveSnapshotFilePath(file.relativePath, file.path, targetHome);
@@ -17163,7 +17286,7 @@ function readSessionRenderSnapshot(snapshotPath) {
17163
17286
  }
17164
17287
  function reconstructPreRollbackLegacyV1Snapshot(snapshot, previousFiles, previousManifestFiles, targetHome, snapshotPath) {
17165
17288
  assertNoNewerSessionSnapshot(snapshotPath, snapshot.createdAt, targetHome);
17166
- const manifestPath = resolve8(snapshot.manifestPath);
17289
+ const manifestPath = resolve10(snapshot.manifestPath);
17167
17290
  const manifestRelativePath = relative5(targetHome, manifestPath).replaceAll("\\", "/");
17168
17291
  resolveSnapshotFilePath(manifestRelativePath, snapshot.manifestPath, targetHome);
17169
17292
  const manifestSha256 = currentSessionFileHash(manifestPath, targetHome);
@@ -17172,7 +17295,7 @@ function reconstructPreRollbackLegacyV1Snapshot(snapshot, previousFiles, previou
17172
17295
  }
17173
17296
  let parsedManifest;
17174
17297
  try {
17175
- parsedManifest = JSON.parse(readFileSync9(manifestPath, "utf8"));
17298
+ parsedManifest = JSON.parse(readFileSync10(manifestPath, "utf8"));
17176
17299
  } catch {
17177
17300
  throw new SessionApplyError(`Pre-rollback legacy v1 applied manifest is not valid JSON: ${snapshotPath}`);
17178
17301
  }
@@ -17180,7 +17303,7 @@ function reconstructPreRollbackLegacyV1Snapshot(snapshot, previousFiles, previou
17180
17303
  throw new SessionApplyError(`Pre-rollback legacy v1 applied manifest is invalid: ${snapshotPath}`);
17181
17304
  }
17182
17305
  const appliedManifest = parsedManifest;
17183
- if (appliedManifest.schema !== SESSION_RENDER_SCHEMA || appliedManifest.tool !== snapshot.tool || appliedManifest.profile !== snapshot.profile || typeof appliedManifest.targetHome !== "string" || resolve8(appliedManifest.targetHome) !== targetHome || appliedManifest.targetKind !== "session-home" && appliedManifest.targetKind !== "project-root" || !Array.isArray(appliedManifest.files)) {
17306
+ if (appliedManifest.schema !== SESSION_RENDER_SCHEMA || appliedManifest.tool !== snapshot.tool || appliedManifest.profile !== snapshot.profile || typeof appliedManifest.targetHome !== "string" || resolve10(appliedManifest.targetHome) !== targetHome || appliedManifest.targetKind !== "session-home" && appliedManifest.targetKind !== "project-root" || !Array.isArray(appliedManifest.files)) {
17184
17307
  throw new SessionApplyError(`Pre-rollback legacy v1 applied manifest does not match its snapshot: ${snapshotPath}`);
17185
17308
  }
17186
17309
  const afterFiles = [];
@@ -17265,16 +17388,16 @@ function assertNoNewerSessionSnapshot(snapshotPath, createdAt, targetHome) {
17265
17388
  throw new SessionApplyError(`Pre-rollback legacy v1 snapshot has an invalid creation time: ${snapshotPath}`);
17266
17389
  }
17267
17390
  for (const entry of readdirSync3(dirname5(snapshotPath))) {
17268
- const candidatePath = resolve8(dirname5(snapshotPath), entry);
17269
- if (candidatePath === resolve8(snapshotPath) || !entry.endsWith(".json"))
17391
+ const candidatePath = resolve10(dirname5(snapshotPath), entry);
17392
+ if (candidatePath === resolve10(snapshotPath) || !entry.endsWith(".json"))
17270
17393
  continue;
17271
- const candidateStat = lstatSync3(candidatePath);
17394
+ const candidateStat = lstatSync4(candidatePath);
17272
17395
  if (candidateStat.isSymbolicLink() || !candidateStat.isFile() || candidateStat.size > 32 * 1024 * 1024)
17273
17396
  continue;
17274
17397
  try {
17275
- const candidate = JSON.parse(readFileSync9(candidatePath, "utf8"));
17398
+ const candidate = JSON.parse(readFileSync10(candidatePath, "utf8"));
17276
17399
  const candidateCreatedAtMs = typeof candidate.createdAt === "string" ? Date.parse(candidate.createdAt) : Number.NaN;
17277
- if ((candidate.schema === "hasna.configs.session-render-snapshot/v1" || candidate.schema === "hasna.configs.session-render-snapshot/v2") && typeof candidate.targetHome === "string" && resolve8(candidate.targetHome) === targetHome && Number.isFinite(candidateCreatedAtMs) && candidateCreatedAtMs >= createdAtMs) {
17400
+ if ((candidate.schema === "hasna.configs.session-render-snapshot/v1" || candidate.schema === "hasna.configs.session-render-snapshot/v2") && typeof candidate.targetHome === "string" && resolve10(candidate.targetHome) === targetHome && Number.isFinite(candidateCreatedAtMs) && candidateCreatedAtMs >= createdAtMs) {
17278
17401
  throw new SessionApplyError(`Cannot restore pre-rollback legacy v1 snapshot after a newer session snapshot exists: ${candidatePath}`);
17279
17402
  }
17280
17403
  } catch (error) {
@@ -17332,7 +17455,7 @@ function inferLegacySnapshotAction(file, previousFiles, previousManifestFiles, p
17332
17455
  return "create";
17333
17456
  }
17334
17457
  if (file.role === "manifest" && previousManifest) {
17335
- const previousManifestSha256 = sha2567(`${JSON.stringify(previousManifest, null, 2)}
17458
+ const previousManifestSha256 = sha2568(`${JSON.stringify(previousManifest, null, 2)}
17336
17459
  `);
17337
17460
  if (previousManifestSha256 !== file.sha256) {
17338
17461
  throw new SessionApplyError(`Cannot infer legacy v1 manifest action without a before-image: ${file.relativePath}`);
@@ -17343,15 +17466,15 @@ function inferLegacySnapshotAction(file, previousFiles, previousManifestFiles, p
17343
17466
  }
17344
17467
  function resolveSnapshotFilePath(relativePath, recordedPath, targetHome) {
17345
17468
  const path = resolveManifestRelativePath(relativePath, targetHome);
17346
- if (resolve8(recordedPath) !== path) {
17469
+ if (resolve10(recordedPath) !== path) {
17347
17470
  throw new SessionApplyError(`Session snapshot file path mismatch for ${relativePath}`);
17348
17471
  }
17349
17472
  return path;
17350
17473
  }
17351
17474
  function planFileResult(plan, file, targetHome, previousHashes, previousManifest, options) {
17352
17475
  const target = resolvePlannedFilePath(plan, file, targetHome);
17353
- const previousContent = existsSync12(target) ? readFileSync9(target, "utf-8") : null;
17354
- const previousSha256 = previousContent === null ? null : sha2567(previousContent);
17476
+ const previousContent = existsSync12(target) ? readFileSync10(target, "utf-8") : null;
17477
+ const previousSha256 = previousContent === null ? null : sha2568(previousContent);
17355
17478
  const previouslyManaged = isPreviouslyManaged(file, previousSha256, previousHashes, previousManifest);
17356
17479
  const changed = previousContent !== file.content;
17357
17480
  if (previousContent !== null && !options.force && !previouslyManaged) {
@@ -17448,8 +17571,8 @@ function planStaleFileResult(file, targetHome, options) {
17448
17571
  const target = resolveManifestRelativePath(file.relativePath, targetHome);
17449
17572
  if (!existsSync12(target))
17450
17573
  return null;
17451
- const previousContent = readFileSync9(target, "utf-8");
17452
- const previousSha256 = sha2567(previousContent);
17574
+ const previousContent = readFileSync10(target, "utf-8");
17575
+ const previousSha256 = sha2568(previousContent);
17453
17576
  if (!options.force && previousSha256 !== file.sha256) {
17454
17577
  return {
17455
17578
  path: target,
@@ -17493,19 +17616,19 @@ function isPreviouslyManaged(file, previousSha256, previousHashes, previousManif
17493
17616
  return previousHashes.get(file.relativePath) === previousSha256;
17494
17617
  }
17495
17618
  function resolvePlannedFilePath(plan, file, targetHome) {
17496
- const target = resolve8(targetHome, ...file.relativePath.split("/"));
17619
+ const target = resolve10(targetHome, ...file.relativePath.split("/"));
17497
17620
  const rel = relative5(targetHome, target);
17498
17621
  if (rel === "" || rel === ".." || rel.startsWith("../") || isAbsolute4(rel)) {
17499
17622
  throw new SessionApplyError(`Session file escapes target home: ${file.relativePath}`);
17500
17623
  }
17501
- if (resolve8(file.path) !== target) {
17624
+ if (resolve10(file.path) !== target) {
17502
17625
  throw new SessionApplyError(`Session file path mismatch for ${file.relativePath}: ${file.path}`);
17503
17626
  }
17504
17627
  assertNoSymlinkSegments2(targetHome, target);
17505
17628
  return target;
17506
17629
  }
17507
17630
  function resolveManifestRelativePath(relativePath, targetHome) {
17508
- const target = resolve8(targetHome, ...relativePath.split(/[\\/]+/));
17631
+ const target = resolve10(targetHome, ...relativePath.split(/[\\/]+/));
17509
17632
  const rel = relative5(targetHome, target);
17510
17633
  if (rel === "" || rel === ".." || rel.startsWith("../") || isAbsolute4(rel)) {
17511
17634
  throw new SessionApplyError(`Session manifest file escapes target home: ${relativePath}`);
@@ -17517,7 +17640,7 @@ function readPreviousManifest(path) {
17517
17640
  if (!existsSync12(path))
17518
17641
  return null;
17519
17642
  try {
17520
- const parsed = JSON.parse(readFileSync9(path, "utf-8"));
17643
+ const parsed = JSON.parse(readFileSync10(path, "utf-8"));
17521
17644
  if (parsed.schema !== SESSION_RENDER_SCHEMA)
17522
17645
  return null;
17523
17646
  if (!Array.isArray(parsed.files))
@@ -17558,11 +17681,11 @@ function currentSessionFileHash(path, targetHome) {
17558
17681
  assertNoSymlinkSegments2(targetHome, path);
17559
17682
  if (!existsSync12(path))
17560
17683
  return null;
17561
- const stat = lstatSync3(path);
17684
+ const stat = lstatSync4(path);
17562
17685
  if (stat.isSymbolicLink() || !stat.isFile()) {
17563
17686
  throw new SessionApplyError(`Session apply path is not a regular file: ${path}`);
17564
17687
  }
17565
- return sha2567(readFileSync9(path, "utf-8"));
17688
+ return sha2568(readFileSync10(path, "utf-8"));
17566
17689
  }
17567
17690
  function requiredPreviousHash(result) {
17568
17691
  if (result.previousSha256 === null) {
@@ -17572,12 +17695,12 @@ function requiredPreviousHash(result) {
17572
17695
  }
17573
17696
  function writeSessionSnapshot(plan, targetHome, manifestPath, results, previousManifest, coordination, allowPortableFallback, forcePortableFileOps) {
17574
17697
  const existingFiles = results.filter((result) => result.action === "update" || result.action === "delete").filter((result) => existsSync12(result.path)).map((result) => {
17575
- const content = readFileSync9(result.path, "utf-8");
17698
+ const content = readFileSync10(result.path, "utf-8");
17576
17699
  return {
17577
17700
  path: result.path,
17578
17701
  relativePath: result.relativePath,
17579
17702
  role: result.role,
17580
- sha256: sha2567(content),
17703
+ sha256: sha2568(content),
17581
17704
  content
17582
17705
  };
17583
17706
  });
@@ -17590,7 +17713,7 @@ function writeSessionSnapshot(plan, targetHome, manifestPath, results, previousM
17590
17713
  };
17591
17714
  }
17592
17715
  const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
17593
- const snapshotPath = resolve8(targetHome, ".hasna", "session-render-snapshots", `${timestamp}-${randomUUID7()}.json`);
17716
+ const snapshotPath = resolve10(targetHome, ".hasna", "session-render-snapshots", `${timestamp}-${randomUUID7()}.json`);
17594
17717
  const afterFiles = results.map((result) => {
17595
17718
  if (result.action === "conflict") {
17596
17719
  throw new SessionApplyError(`Cannot snapshot unresolved conflict: ${result.relativePath}`);
@@ -17638,12 +17761,12 @@ function writeSessionSnapshot(plan, targetHome, manifestPath, results, previousM
17638
17761
  function assertSafeTargetHome(targetHome) {
17639
17762
  if (!isAbsolute4(targetHome))
17640
17763
  throw new SessionApplyError(`Session target home must be absolute: ${targetHome}`);
17641
- const normalized = resolve8(targetHome);
17764
+ const normalized = resolve10(targetHome);
17642
17765
  if (normalized === parse4(normalized).root) {
17643
17766
  throw new SessionApplyError(`Session target home cannot be the filesystem root: ${targetHome}`);
17644
17767
  }
17645
17768
  assertNoSymlinkAncestors2(normalized);
17646
- if (existsSync12(normalized) && lstatSync3(normalized).isSymbolicLink()) {
17769
+ if (existsSync12(normalized) && lstatSync4(normalized).isSymbolicLink()) {
17647
17770
  throw new SessionApplyError(`Session target home cannot be a symlink: ${normalized}`);
17648
17771
  }
17649
17772
  return normalized;
@@ -17653,32 +17776,33 @@ function assertNoSymlinkSegments2(root, target) {
17653
17776
  const rel = relative5(root, target);
17654
17777
  let current = root;
17655
17778
  for (const segment of rel.split(/[\\/]+/).filter(Boolean)) {
17656
- current = join13(current, segment);
17657
- if (existsSync12(current) && lstatSync3(current).isSymbolicLink()) {
17779
+ current = join15(current, segment);
17780
+ if (existsSync12(current) && lstatSync4(current).isSymbolicLink()) {
17658
17781
  throw new SessionApplyError(`Session apply path uses a symlink: ${current}`);
17659
17782
  }
17660
17783
  }
17661
17784
  }
17662
17785
  function assertNoSymlinkAncestors2(path) {
17663
- const normalized = resolve8(path);
17786
+ const normalized = resolve10(path);
17664
17787
  const parsed = parse4(normalized);
17665
17788
  let current = parsed.root;
17666
17789
  const rel = relative5(parsed.root, normalized);
17667
17790
  for (const segment of rel.split(/[\\/]+/).filter(Boolean)) {
17668
- current = join13(current, segment);
17791
+ current = join15(current, segment);
17669
17792
  if (!existsSync12(current))
17670
17793
  return;
17671
- if (lstatSync3(current).isSymbolicLink()) {
17794
+ if (lstatSync4(current).isSymbolicLink()) {
17672
17795
  throw new SessionApplyError(`Session apply path uses a symlink ancestor: ${current}`);
17673
17796
  }
17674
17797
  }
17675
17798
  }
17676
- function sha2567(content) {
17677
- return createHash7("sha256").update(content).digest("hex");
17799
+ function sha2568(content) {
17800
+ return createHash8("sha256").update(content).digest("hex");
17678
17801
  }
17679
17802
 
17680
17803
  // src/cli/index.tsx
17681
17804
  init_session_render();
17805
+ init_raw_store_root();
17682
17806
  init_asset_plan();
17683
17807
  init_instruction_graph();
17684
17808
 
@@ -18025,34 +18149,433 @@ async function ensureDangerousOperationGuardStandardConfig(store = resolveConfig
18025
18149
 
18026
18150
  // src/cli/index.tsx
18027
18151
  init_codewith_shared_todos_storage_standard();
18152
+
18153
+ // src/lib/managed-skill-runtimes.ts
18154
+ import { createHash as createHash9 } from "crypto";
18155
+ import { spawnSync } from "child_process";
18156
+ import {
18157
+ existsSync as existsSync13,
18158
+ lstatSync as lstatSync5,
18159
+ mkdirSync as mkdirSync7,
18160
+ readFileSync as readFileSync11,
18161
+ renameSync as renameSync2,
18162
+ rmSync as rmSync5,
18163
+ writeFileSync as writeFileSync4
18164
+ } from "fs";
18165
+ import { homedir as homedir8 } from "os";
18166
+ import { dirname as dirname6, join as join16, parse as parse5, relative as relative6, resolve as resolve11 } from "path";
18167
+ var INBOX_CONVERSATIONS_MINIMUM_VERSION = "0.5.28";
18168
+ var INBOX_SKILL_MARKERS = [
18169
+ [".claude", "skills", "inbox", "SKILL.md"],
18170
+ [".codex", "skills", "inbox", "SKILL.md"],
18171
+ [".codewith", "skills", "inbox", "SKILL.md"],
18172
+ [".config", "opencode", "skills", "inbox", "SKILL.md"],
18173
+ [".cursor", "skills", "inbox", "SKILL.md"]
18174
+ ];
18175
+ var REQUIRED_WATCH_FLAGS = ["--from <agent>", "--all", "--full-content"];
18176
+ function sha2569(content) {
18177
+ return createHash9("sha256").update(content).digest("hex");
18178
+ }
18179
+ function lstatOrNull(path) {
18180
+ try {
18181
+ return lstatSync5(path);
18182
+ } catch {
18183
+ return null;
18184
+ }
18185
+ }
18186
+ function findSymlinkedAncestor(path) {
18187
+ const normalized = resolve11(path);
18188
+ const parsed = parse5(normalized);
18189
+ let current = parsed.root;
18190
+ const rel = relative6(parsed.root, normalized);
18191
+ for (const segment of rel.split(/[\\/]+/).filter(Boolean)) {
18192
+ current = join16(current, segment);
18193
+ if (!existsSync13(current))
18194
+ return null;
18195
+ if (lstatSync5(current).isSymbolicLink())
18196
+ return current;
18197
+ }
18198
+ return null;
18199
+ }
18200
+ function assertNoSymlinkAncestors3(path) {
18201
+ const found = findSymlinkedAncestor(path);
18202
+ if (found !== null) {
18203
+ throw new Error(`managed skill path uses a symlink ancestor: ${found}`);
18204
+ }
18205
+ }
18206
+ function packagedInboxSkillPath(explicitPath) {
18207
+ if (explicitPath)
18208
+ return explicitPath;
18209
+ const candidates = [
18210
+ join16(import.meta.dir, "..", "..", "assets", "skills", "inbox", "SKILL.md"),
18211
+ join16(import.meta.dir, "..", "assets", "skills", "inbox", "SKILL.md"),
18212
+ join16(process.cwd(), "assets", "skills", "inbox", "SKILL.md")
18213
+ ];
18214
+ const found = candidates.find((candidate) => existsSync13(candidate));
18215
+ if (!found) {
18216
+ throw new Error(`packaged inbox skill contract is missing (checked ${candidates.length} package-relative locations)`);
18217
+ }
18218
+ return found;
18219
+ }
18220
+ function readCanonicalSkill(explicitPath) {
18221
+ const assetPath = packagedInboxSkillPath(explicitPath);
18222
+ const stat = lstatOrNull(assetPath);
18223
+ if (!stat?.isFile()) {
18224
+ throw new Error("packaged inbox skill contract is not a regular file");
18225
+ }
18226
+ const content = readFileSync11(assetPath, "utf8");
18227
+ if (!content.includes("conversations watch --from <agent> --all")) {
18228
+ throw new Error("packaged inbox skill contract does not declare the canonical conversations watcher");
18229
+ }
18230
+ if (!content.includes("There is no separate")) {
18231
+ throw new Error("packaged inbox skill contract does not retire the legacy executable");
18232
+ }
18233
+ return { content, sha256: sha2569(content) };
18234
+ }
18235
+ function runProbe(command, args) {
18236
+ const result = spawnSync(command, args, {
18237
+ encoding: "utf8",
18238
+ timeout: 5000,
18239
+ stdio: ["ignore", "pipe", "pipe"]
18240
+ });
18241
+ if (result.error || result.status !== 0) {
18242
+ return { ok: false, output: "" };
18243
+ }
18244
+ return {
18245
+ ok: true,
18246
+ output: `${result.stdout ?? ""}
18247
+ ${result.stderr ?? ""}`.trim()
18248
+ };
18249
+ }
18250
+ function parseVersion(output) {
18251
+ return output.match(/\b(\d+\.\d+\.\d+)\b/)?.[1] ?? null;
18252
+ }
18253
+ function compareVersions(left, right) {
18254
+ const a = left.split(".").map(Number);
18255
+ const b = right.split(".").map(Number);
18256
+ for (let i = 0;i < Math.max(a.length, b.length); i++) {
18257
+ const delta = (a[i] ?? 0) - (b[i] ?? 0);
18258
+ if (delta !== 0)
18259
+ return delta;
18260
+ }
18261
+ return 0;
18262
+ }
18263
+ function inspectSkillMarkers(homeDir2) {
18264
+ return INBOX_SKILL_MARKERS.map((parts) => join16(homeDir2, ...parts)).map((path) => {
18265
+ const stat = lstatOrNull(path);
18266
+ if (!stat)
18267
+ return null;
18268
+ if (!stat.isFile()) {
18269
+ return { path, content: null, mode: null, regular: false };
18270
+ }
18271
+ return {
18272
+ path,
18273
+ content: readFileSync11(path, "utf8"),
18274
+ mode: stat.mode & 511,
18275
+ regular: true
18276
+ };
18277
+ }).filter((snapshot) => snapshot !== null);
18278
+ }
18279
+ function inspectInbox(options) {
18280
+ const homeDir2 = options.homeDir ?? homedir8();
18281
+ const runtimeCommand = options.conversationsCommand ?? "conversations";
18282
+ const snapshots = inspectSkillMarkers(homeDir2);
18283
+ const skillPresent = snapshots.length > 0;
18284
+ let canonicalContent = null;
18285
+ let canonicalSha256 = null;
18286
+ let assetError = null;
18287
+ try {
18288
+ const canonical = readCanonicalSkill(options.assetPath);
18289
+ canonicalContent = canonical.content;
18290
+ canonicalSha256 = canonical.sha256;
18291
+ } catch (error) {
18292
+ assetError = error instanceof Error ? error.message : String(error);
18293
+ }
18294
+ const versionProbe = skillPresent ? runProbe(runtimeCommand, ["--version"]) : { ok: false, output: "" };
18295
+ const helpProbe = versionProbe.ok ? runProbe(runtimeCommand, ["watch", "--help"]) : { ok: false, output: "" };
18296
+ const runtimeVersion = versionProbe.ok ? parseVersion(versionProbe.output) : null;
18297
+ const supportsFrom = helpProbe.ok && helpProbe.output.includes(REQUIRED_WATCH_FLAGS[0]);
18298
+ const supportsAll = helpProbe.ok && helpProbe.output.includes(REQUIRED_WATCH_FLAGS[1]);
18299
+ const supportsFullContent = helpProbe.ok && helpProbe.output.includes(REQUIRED_WATCH_FLAGS[2]);
18300
+ const packageReady = versionProbe.ok && runtimeVersion !== null && compareVersions(runtimeVersion, INBOX_CONVERSATIONS_MINIMUM_VERSION) >= 0 && helpProbe.ok && supportsFrom && supportsAll && supportsFullContent;
18301
+ const heartbeatProbe = skillPresent && packageReady && options.agent ? runProbe(runtimeCommand, ["agents", "heartbeat", "--from", options.agent, "--json"]) : null;
18302
+ const hostedHeartbeat = heartbeatProbe === null ? "unverified" : heartbeatProbe.ok ? "passed" : "failed";
18303
+ const deliveryVerified = hostedHeartbeat === "passed" && options.deliveryVerified === true;
18304
+ const staleMarkers = canonicalContent === null ? snapshots.map((snapshot) => snapshot.path) : snapshots.filter((snapshot) => !snapshot.regular || snapshot.content !== canonicalContent).map((snapshot) => snapshot.path);
18305
+ let reason = "skill not installed";
18306
+ if (skillPresent) {
18307
+ const nonRegular = snapshots.some((snapshot) => !snapshot.regular);
18308
+ const symlinkAncestor = snapshots.map((snapshot) => snapshot.path).map((path) => findSymlinkedAncestor(dirname6(path))).find((found) => found !== null);
18309
+ if (nonRegular)
18310
+ reason = "managed skill target is not a regular file";
18311
+ else if (symlinkAncestor)
18312
+ reason = `managed skill path uses a symlink ancestor: ${symlinkAncestor}`;
18313
+ else if (assetError)
18314
+ reason = assetError;
18315
+ else if (!versionProbe.ok)
18316
+ reason = "conversations command unavailable";
18317
+ else if (!runtimeVersion)
18318
+ reason = "conversations version is unreadable";
18319
+ else if (compareVersions(runtimeVersion, INBOX_CONVERSATIONS_MINIMUM_VERSION) < 0) {
18320
+ reason = `conversations ${runtimeVersion} is older than ${INBOX_CONVERSATIONS_MINIMUM_VERSION}`;
18321
+ } else if (!helpProbe.ok)
18322
+ reason = "conversations watch help is unavailable";
18323
+ else if (!supportsFrom || !supportsAll || !supportsFullContent) {
18324
+ const missing = [
18325
+ !supportsFrom ? "--from" : null,
18326
+ !supportsAll ? "--all" : null,
18327
+ !supportsFullContent ? "--full-content" : null
18328
+ ].filter((flag) => flag !== null);
18329
+ reason = `conversations watch is missing required flags: ${missing.join(", ")}`;
18330
+ } else if (staleMarkers.length > 0)
18331
+ reason = "skill contract stale";
18332
+ else if (hostedHeartbeat === "failed")
18333
+ reason = "hosted heartbeat failed; manual fallback required";
18334
+ else if (hostedHeartbeat === "unverified")
18335
+ reason = "hosted heartbeat unverified; manual fallback required";
18336
+ else if (!deliveryVerified)
18337
+ reason = "hosted heartbeat passed; channel and DM delivery verification required";
18338
+ else
18339
+ reason = "ready";
18340
+ }
18341
+ return {
18342
+ status: {
18343
+ skill: "inbox",
18344
+ runtime: "conversations watch",
18345
+ minimum_version: INBOX_CONVERSATIONS_MINIMUM_VERSION,
18346
+ skill_present: skillPresent,
18347
+ skill_markers: snapshots.map((snapshot) => snapshot.path),
18348
+ skill_contracts_current: snapshots.length - staleMarkers.length,
18349
+ stale_skill_markers: staleMarkers,
18350
+ expected_skill_sha256: canonicalSha256,
18351
+ runtime_command: runtimeCommand,
18352
+ runtime_present: versionProbe.ok,
18353
+ runtime_version: runtimeVersion,
18354
+ watch_supports_from: supportsFrom,
18355
+ watch_supports_all: supportsAll,
18356
+ watch_supports_full_content: supportsFullContent,
18357
+ hosted_heartbeat: hostedHeartbeat,
18358
+ delivery_verified: deliveryVerified,
18359
+ manual_fallback_ready: skillPresent && staleMarkers.length === 0 && packageReady,
18360
+ healthy: !skillPresent || reason === "ready",
18361
+ reason
18362
+ },
18363
+ canonicalContent,
18364
+ snapshots
18365
+ };
18366
+ }
18367
+ function inspectManagedSkillRuntimes(options = {}) {
18368
+ const runtime = inspectInbox(options).status;
18369
+ const installed = runtime.skill_present ? [runtime] : [];
18370
+ return {
18371
+ runtimes: [runtime],
18372
+ skills_present: installed.length,
18373
+ healthy: installed.filter((item) => item.healthy).length,
18374
+ missing: installed.filter((item) => !item.healthy).length
18375
+ };
18376
+ }
18377
+ function runtimeReadyForWrite(status) {
18378
+ return status.runtime_present && status.runtime_version !== null && compareVersions(status.runtime_version, INBOX_CONVERSATIONS_MINIMUM_VERSION) >= 0 && status.watch_supports_from && status.watch_supports_all && status.watch_supports_full_content;
18379
+ }
18380
+ function projectUpdatedStatus(status, contractCount) {
18381
+ const healthy = status.hosted_heartbeat === "passed" && status.delivery_verified;
18382
+ return {
18383
+ ...status,
18384
+ skill_contracts_current: contractCount,
18385
+ stale_skill_markers: [],
18386
+ manual_fallback_ready: true,
18387
+ healthy,
18388
+ reason: healthy ? "ready" : status.hosted_heartbeat === "failed" ? "hosted heartbeat failed; manual fallback required" : status.hosted_heartbeat === "unverified" ? "hosted heartbeat unverified; manual fallback required" : "hosted heartbeat passed; channel and DM delivery verification required"
18389
+ };
18390
+ }
18391
+ function cleanup(path) {
18392
+ rmSync5(path, { force: true });
18393
+ }
18394
+ function writeAtomic(path, content, mode) {
18395
+ assertNoSymlinkAncestors3(dirname6(path));
18396
+ const tempPath = `${path}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`;
18397
+ try {
18398
+ mkdirSync7(dirname6(path), { recursive: true, mode: 493 });
18399
+ writeFileSync4(tempPath, content, { mode, flag: "wx" });
18400
+ renameSync2(tempPath, path);
18401
+ } finally {
18402
+ cleanup(tempPath);
18403
+ }
18404
+ }
18405
+ var DEFAULT_SKILL_WRITE_FILE_OPERATIONS = {
18406
+ lstat: lstatOrNull,
18407
+ read: (path) => readFileSync11(path, "utf8"),
18408
+ write: writeAtomic
18409
+ };
18410
+ function writeSkillContractsTransactional(snapshots, canonicalContent, fileOperations = DEFAULT_SKILL_WRITE_FILE_OPERATIONS) {
18411
+ const written = [];
18412
+ try {
18413
+ for (const snapshot of snapshots) {
18414
+ const currentStat = fileOperations.lstat(snapshot.path);
18415
+ if (!currentStat?.isFile() || fileOperations.read(snapshot.path) !== snapshot.content) {
18416
+ throw new Error("managed skill changed after inspection; refusing a stale write");
18417
+ }
18418
+ fileOperations.write(snapshot.path, canonicalContent, snapshot.mode);
18419
+ written.push(snapshot);
18420
+ }
18421
+ return { ok: true, error: null, rollback_conflicts: [] };
18422
+ } catch (error) {
18423
+ const rollbackConflicts = [];
18424
+ for (const snapshot of written.reverse()) {
18425
+ const currentStat = fileOperations.lstat(snapshot.path);
18426
+ if (!currentStat?.isFile()) {
18427
+ rollbackConflicts.push(`${snapshot.path}: no longer a regular file`);
18428
+ continue;
18429
+ }
18430
+ let currentContent;
18431
+ try {
18432
+ currentContent = fileOperations.read(snapshot.path);
18433
+ } catch {
18434
+ rollbackConflicts.push(`${snapshot.path}: could not read the current file`);
18435
+ continue;
18436
+ }
18437
+ if (currentContent !== canonicalContent) {
18438
+ rollbackConflicts.push(`${snapshot.path}: changed after this reconciliation wrote it`);
18439
+ continue;
18440
+ }
18441
+ try {
18442
+ fileOperations.write(snapshot.path, snapshot.content, snapshot.mode);
18443
+ } catch {
18444
+ rollbackConflicts.push(`${snapshot.path}: still owned but could not be restored`);
18445
+ }
18446
+ }
18447
+ return {
18448
+ ok: false,
18449
+ error: error instanceof Error ? error.message : String(error),
18450
+ rollback_conflicts: rollbackConflicts
18451
+ };
18452
+ }
18453
+ }
18454
+ async function reconcileManagedSkillRuntimes(options = {}) {
18455
+ const dryRun = options.dryRun ?? false;
18456
+ const before = inspectInbox(options);
18457
+ const status = before.status;
18458
+ if (!status.skill_present) {
18459
+ return {
18460
+ runtimes: [{ ...status, action: "skipped", dry_run: dryRun, skill_contracts_changed: 0 }],
18461
+ changed: 0,
18462
+ failed: 0,
18463
+ dry_run: dryRun
18464
+ };
18465
+ }
18466
+ if (before.snapshots.some((snapshot) => !snapshot.regular)) {
18467
+ return {
18468
+ runtimes: [{ ...status, action: "failed", dry_run: dryRun, skill_contracts_changed: 0 }],
18469
+ changed: 0,
18470
+ failed: 1,
18471
+ dry_run: dryRun
18472
+ };
18473
+ }
18474
+ const symlinkedAncestor = before.snapshots.map((snapshot) => snapshot.path).map((path) => findSymlinkedAncestor(dirname6(path))).find((found) => found !== null);
18475
+ if (symlinkedAncestor) {
18476
+ return {
18477
+ runtimes: [{ ...status, action: "failed", dry_run: dryRun, skill_contracts_changed: 0 }],
18478
+ changed: 0,
18479
+ failed: 1,
18480
+ dry_run: dryRun
18481
+ };
18482
+ }
18483
+ if (!before.canonicalContent || !runtimeReadyForWrite(status)) {
18484
+ return {
18485
+ runtimes: [{ ...status, action: "failed", dry_run: dryRun, skill_contracts_changed: 0 }],
18486
+ changed: 0,
18487
+ failed: 1,
18488
+ dry_run: dryRun
18489
+ };
18490
+ }
18491
+ const staleSnapshots = before.snapshots.filter((snapshot) => snapshot.content !== before.canonicalContent);
18492
+ if (staleSnapshots.length === 0) {
18493
+ return {
18494
+ runtimes: [{ ...status, action: "unchanged", dry_run: dryRun, skill_contracts_changed: 0 }],
18495
+ changed: 0,
18496
+ failed: 0,
18497
+ dry_run: dryRun
18498
+ };
18499
+ }
18500
+ if (dryRun) {
18501
+ const projected = projectUpdatedStatus(status, before.snapshots.length);
18502
+ return {
18503
+ runtimes: [{
18504
+ ...projected,
18505
+ action: "update",
18506
+ dry_run: true,
18507
+ skill_contracts_changed: staleSnapshots.length
18508
+ }],
18509
+ changed: 1,
18510
+ failed: 0,
18511
+ dry_run: true
18512
+ };
18513
+ }
18514
+ const transaction = writeSkillContractsTransactional(staleSnapshots.map((snapshot) => ({
18515
+ path: snapshot.path,
18516
+ content: snapshot.content,
18517
+ mode: snapshot.mode ?? 420
18518
+ })), before.canonicalContent);
18519
+ if (!transaction.ok) {
18520
+ const rollbackConflictReason = transaction.rollback_conflicts.length > 0 ? `; rollback conflicts: ${transaction.rollback_conflicts.join("; ")}` : "";
18521
+ const reason = `${transaction.error ?? "managed skill reconciliation failed"}${rollbackConflictReason}`;
18522
+ return {
18523
+ runtimes: [{
18524
+ ...status,
18525
+ action: "failed",
18526
+ dry_run: false,
18527
+ skill_contracts_changed: 0,
18528
+ reason
18529
+ }],
18530
+ changed: 0,
18531
+ failed: 1,
18532
+ dry_run: false
18533
+ };
18534
+ }
18535
+ const after = inspectInbox(options).status;
18536
+ const accepted = after.healthy || after.manual_fallback_ready;
18537
+ return {
18538
+ runtimes: [{
18539
+ ...after,
18540
+ action: accepted ? "update" : "failed",
18541
+ dry_run: false,
18542
+ skill_contracts_changed: accepted ? staleSnapshots.length : 0
18543
+ }],
18544
+ changed: accepted ? 1 : 0,
18545
+ failed: accepted ? 0 : 1,
18546
+ dry_run: false
18547
+ };
18548
+ }
18549
+
18550
+ // src/cli/index.tsx
18028
18551
  init_project_context();
18029
18552
 
18030
18553
  // src/status.ts
18031
18554
  init_config_store();
18032
18555
  init_apply();
18033
18556
  init_config_agents();
18034
- import { existsSync as existsSync14, readFileSync as readFileSync11 } from "fs";
18557
+ import { existsSync as existsSync15, readFileSync as readFileSync13 } from "fs";
18035
18558
 
18036
18559
  // src/lib/package-version.ts
18037
- import { existsSync as existsSync13, readFileSync as readFileSync10 } from "fs";
18038
- import { dirname as dirname6, join as join14 } from "path";
18560
+ import { existsSync as existsSync14, readFileSync as readFileSync12 } from "fs";
18561
+ import { dirname as dirname7, join as join17 } from "path";
18039
18562
  import { fileURLToPath } from "url";
18040
18563
  var cached = null;
18041
18564
  function getPackageVersion() {
18042
18565
  if (cached)
18043
18566
  return cached;
18044
18567
  try {
18045
- let dir = dirname6(fileURLToPath(import.meta.url));
18568
+ let dir = dirname7(fileURLToPath(import.meta.url));
18046
18569
  for (let i = 0;i < 8; i++) {
18047
- const pkgPath = join14(dir, "package.json");
18048
- if (existsSync13(pkgPath)) {
18049
- const pkg = JSON.parse(readFileSync10(pkgPath, "utf8"));
18570
+ const pkgPath = join17(dir, "package.json");
18571
+ if (existsSync14(pkgPath)) {
18572
+ const pkg = JSON.parse(readFileSync12(pkgPath, "utf8"));
18050
18573
  if (pkg.name === "@hasna/instructions" && pkg.version) {
18051
18574
  cached = pkg.version;
18052
18575
  return cached;
18053
18576
  }
18054
18577
  }
18055
- const parent = dirname6(dir);
18578
+ const parent = dirname7(dir);
18056
18579
  if (parent === dir)
18057
18580
  break;
18058
18581
  dir = parent;
@@ -18085,7 +18608,7 @@ function countBy(items, getValue) {
18085
18608
  }
18086
18609
  return counts;
18087
18610
  }
18088
- async function getConfigsStatus(store = resolveConfigStore()) {
18611
+ async function getConfigsStatus(store = resolveConfigStore(), options = {}) {
18089
18612
  let databaseReachable = true;
18090
18613
  let configs = [];
18091
18614
  let categoryStats = { total: 0 };
@@ -18109,11 +18632,11 @@ async function getConfigsStatus(store = resolveConfigStore()) {
18109
18632
  continue;
18110
18633
  knownTargets += 1;
18111
18634
  const targetPath = expandPath(config.target_path);
18112
- if (!existsSync14(targetPath)) {
18635
+ if (!existsSync15(targetPath)) {
18113
18636
  missingTargets += 1;
18114
18637
  continue;
18115
18638
  }
18116
- const disk = readFileSync11(targetPath, "utf-8");
18639
+ const disk = readFileSync13(targetPath, "utf-8");
18117
18640
  const { content: redactedDisk } = redactContent(disk, config.format);
18118
18641
  if (redactedDisk !== config.content) {
18119
18642
  driftedTargets += 1;
@@ -18139,7 +18662,11 @@ async function getConfigsStatus(store = resolveConfigStore()) {
18139
18662
  }
18140
18663
  }
18141
18664
  const byCategory = Object.fromEntries(Object.entries(categoryStats).filter(([key]) => key !== "total"));
18142
- const status = databaseReachable && driftedTargets === 0 && missingTargets === 0 && unredactedSecretFindings === 0 && retiredAgentRows === 0 ? "ok" : "warn";
18665
+ const managedSkillRuntimes = inspectManagedSkillRuntimes({
18666
+ homeDir: options.homeDir,
18667
+ conversationsCommand: options.conversationsCommand
18668
+ });
18669
+ const status = databaseReachable && driftedTargets === 0 && missingTargets === 0 && unredactedSecretFindings === 0 && retiredAgentRows === 0 && managedSkillRuntimes.missing === 0 ? "ok" : "warn";
18143
18670
  return {
18144
18671
  service: "configs",
18145
18672
  schemaVersion: "1.0",
@@ -18169,7 +18696,12 @@ async function getConfigsStatus(store = resolveConfigStore()) {
18169
18696
  profileLinks,
18170
18697
  machines,
18171
18698
  snapshots,
18172
- knownTargets
18699
+ knownTargets,
18700
+ managedSkillRuntimes: {
18701
+ skillsPresent: managedSkillRuntimes.skills_present,
18702
+ healthy: managedSkillRuntimes.healthy,
18703
+ missing: managedSkillRuntimes.missing
18704
+ }
18173
18705
  },
18174
18706
  health: {
18175
18707
  status,
@@ -18178,10 +18710,12 @@ async function getConfigsStatus(store = resolveConfigStore()) {
18178
18710
  missingTargets,
18179
18711
  unredactedSecretFindings,
18180
18712
  retiredAgentRows,
18713
+ missingManagedSkillRuntimes: managedSkillRuntimes.missing,
18181
18714
  hasDrift: driftedTargets > 0,
18182
18715
  hasMissingTargets: missingTargets > 0,
18183
18716
  hasUnredactedSecrets: unredactedSecretFindings > 0,
18184
- hasRetiredAgentRows: retiredAgentRows > 0
18717
+ hasRetiredAgentRows: retiredAgentRows > 0,
18718
+ hasMissingManagedSkillRuntimes: managedSkillRuntimes.missing > 0
18185
18719
  },
18186
18720
  safety: {
18187
18721
  includesConfigValues: false,
@@ -18223,6 +18757,17 @@ function printLine(text = "") {
18223
18757
  function printJson(value) {
18224
18758
  printLine(JSON.stringify(value, null, 2));
18225
18759
  }
18760
+ function printManagedSkillRuntimeReport(report) {
18761
+ for (const runtime of report.runtimes) {
18762
+ if (!runtime.skill_present)
18763
+ continue;
18764
+ const prefix = runtime.action === "failed" ? chalk.red("[failed]") : runtime.dry_run ? chalk.yellow("[dry-run]") : runtime.manual_fallback_ready && !runtime.healthy ? chalk.yellow("[degraded]") : runtime.action === "unchanged" ? chalk.dim("=") : chalk.green("\u2713");
18765
+ console.log(`${prefix} ${runtime.skill} via ${runtime.runtime} \u2014 ${runtime.reason}`);
18766
+ if (runtime.action === "update") {
18767
+ console.log(chalk.dim(` skill contracts: ${runtime.skill_contracts_changed}`));
18768
+ }
18769
+ }
18770
+ }
18226
18771
  function fmtConfig(c, format) {
18227
18772
  if (format === "json")
18228
18773
  return JSON.stringify(c, null, 2);
@@ -18289,7 +18834,7 @@ function parseSessionSource(value, order) {
18289
18834
  if (!path)
18290
18835
  throw new Error(`Invalid --source "${value}" (expected path or id=path)`);
18291
18836
  const absPath = resolveSessionPath(path);
18292
- if (!existsSync16(absPath))
18837
+ if (!existsSync17(absPath))
18293
18838
  throw new Error(`Instruction source file not found: ${absPath}`);
18294
18839
  const content = readSessionInstructionSourceFile(absPath);
18295
18840
  const source = sourceFromFilePath(absPath, content, order);
@@ -18333,7 +18878,7 @@ function sessionSourceReplacements(values) {
18333
18878
  return replacements;
18334
18879
  }
18335
18880
  function readSessionInstructionSourceFile(path) {
18336
- const stat = lstatSync5(path);
18881
+ const stat = lstatSync7(path);
18337
18882
  if (stat.isSymbolicLink()) {
18338
18883
  throw new Error("SESSION_SOURCE_SYMLINK_REJECTED: instruction source file must be a regular non-symlink file");
18339
18884
  }
@@ -18343,7 +18888,7 @@ function readSessionInstructionSourceFile(path) {
18343
18888
  if (stat.size > SESSION_MANAGED_INPUT_MAX_BYTES) {
18344
18889
  throw new Error(`SESSION_SOURCE_INPUT_TOO_LARGE: instruction source file exceeds ${SESSION_MANAGED_INPUT_MAX_BYTES} bytes`);
18345
18890
  }
18346
- return readFileSync13(path, "utf-8");
18891
+ return readFileSync15(path, "utf-8");
18347
18892
  }
18348
18893
  function parseLayeredReference(value) {
18349
18894
  const trimmed = value.trim();
@@ -18370,9 +18915,9 @@ async function collectSessionSources(opts, tool, store) {
18370
18915
  }
18371
18916
  for (const value of opts.identityExport ?? []) {
18372
18917
  const path = resolveSessionPath(value);
18373
- if (!existsSync16(path))
18918
+ if (!existsSync17(path))
18374
18919
  throw new Error(`Identity instruction export not found: ${path}`);
18375
- const parsed = JSON.parse(readFileSync13(path, "utf-8"));
18920
+ const parsed = JSON.parse(readFileSync15(path, "utf-8"));
18376
18921
  sources.push(...sourcesFromIdentityExport(parsed, { path, tool, orderOffset: sources.length }));
18377
18922
  }
18378
18923
  return sources.map((source) => {
@@ -18493,19 +19038,19 @@ function readProjectContextBundleOption(value, allowMissing = false) {
18493
19038
  if (value === "-")
18494
19039
  return { json: readBoundedProjectContextStdin() };
18495
19040
  const path = resolveSessionPath(value);
18496
- if (!existsSync16(path)) {
19041
+ if (!existsSync17(path)) {
18497
19042
  if (allowMissing)
18498
19043
  return {};
18499
19044
  throw new ProjectContextError("PROJECT_CONTEXT_INPUT_MISSING", `bundle file not found: ${path}`);
18500
19045
  }
18501
- const stat = lstatSync5(path);
19046
+ const stat = lstatSync7(path);
18502
19047
  if (stat.isSymbolicLink() || !stat.isFile()) {
18503
19048
  throw new ProjectContextError("PROJECT_CONTEXT_SYMLINK_REJECTED", "bundle input must be a regular non-symlink file");
18504
19049
  }
18505
19050
  if (stat.size > PROJECT_CONTEXT_MAX_INPUT_BYTES) {
18506
19051
  throw new ProjectContextError("PROJECT_CONTEXT_INPUT_TOO_LARGE", `bundle exceeds ${PROJECT_CONTEXT_MAX_INPUT_BYTES} bytes`);
18507
19052
  }
18508
- return { json: readFileSync13(path, "utf8"), sourcePath: path };
19053
+ return { json: readFileSync15(path, "utf8"), sourcePath: path };
18509
19054
  }
18510
19055
  function readBoundedProjectContextStdin() {
18511
19056
  const chunks = [];
@@ -18664,15 +19209,15 @@ program.command("tag <id>").description("Add or remove tags on a stored config (
18664
19209
  console.log(chalk.green("\u2713") + ` Tags on ${chalk.bold(updated.name)} ${chalk.dim(`(${updated.slug})`)}: ${nextTags.join(", ") || chalk.dim("(none)")}`);
18665
19210
  });
18666
19211
  program.command("add <path>").description("Ingest a file into the config DB").option("-n, --name <name>", "config name (defaults to filename)").option("-c, --category <cat>", "category override").option("-a, --agent <agent>", "agent override").option("-k, --kind <kind>", "kind: file|reference", "file").option("--template", "mark as template (has {{VAR}} placeholders)").option("--update", "if a config already owns this path, update that row in place instead of refusing").action(async (filePath, opts) => {
18667
- const abs = resolve10(filePath);
18668
- if (!existsSync16(abs)) {
19212
+ const abs = resolve13(filePath);
19213
+ if (!existsSync17(abs)) {
18669
19214
  console.error(chalk.red(`File not found: ${abs}`));
18670
19215
  process.exit(1);
18671
19216
  }
18672
- const rawContent = readFileSync13(abs, "utf-8");
19217
+ const rawContent = readFileSync15(abs, "utf-8");
18673
19218
  const fmt = detectFormat(abs);
18674
19219
  const { content, redacted, isTemplate: isTemplate2 } = redactContent(rawContent, fmt);
18675
- const targetPath = abs.startsWith(homedir8()) ? abs.replace(homedir8(), "~") : abs;
19220
+ const targetPath = abs.startsWith(homedir10()) ? abs.replace(homedir10(), "~") : abs;
18676
19221
  const name = opts.name || filePath.split("/").pop();
18677
19222
  const store = resolveConfigStore();
18678
19223
  const allConfigs = await store.listConfigs();
@@ -18847,7 +19392,7 @@ program.command("sync").description("Sync known AI coding configs from disk into
18847
19392
  for (const entry of entries) {
18848
19393
  if (!entry.isDirectory())
18849
19394
  continue;
18850
- const projDir = join16(absDir, entry.name);
19395
+ const projDir = join19(absDir, entry.name);
18851
19396
  const hasAgentConfig = [
18852
19397
  "CLAUDE.md",
18853
19398
  ".mcp.json",
@@ -18860,7 +19405,7 @@ program.command("sync").description("Sync known AI coding configs from disk into
18860
19405
  ".aicopilot",
18861
19406
  ".cursor",
18862
19407
  ".agents"
18863
- ].some((marker) => existsSync16(join16(projDir, marker)));
19408
+ ].some((marker) => existsSync17(join19(projDir, marker)));
18864
19409
  if (!hasAgentConfig)
18865
19410
  continue;
18866
19411
  const result2 = await syncProject({ projectDir: projDir, dryRun: opts.dryRun, store });
@@ -18911,7 +19456,7 @@ program.command("import <file>").description("Import configs from a tar.gz bundl
18911
19456
  });
18912
19457
  program.command("whoami").description("Show setup summary").action(async () => {
18913
19458
  const store = resolveConfigStore();
18914
- const dbPath = isApiTransport() ? `${process.env["HASNA_INSTRUCTIONS_API_URL"]}/v1` : process.env["HASNA_INSTRUCTIONS_DB_PATH"] || join16(homedir8(), ".hasna", "instructions", "instructions.db");
19459
+ const dbPath = isApiTransport() ? `${process.env["HASNA_INSTRUCTIONS_API_URL"]}/v1` : process.env["HASNA_INSTRUCTIONS_DB_PATH"] || join19(getRawStoreRoot(), "instructions.db");
18915
19460
  const stats = await store.getConfigStats();
18916
19461
  console.log(chalk.bold("@hasna/instructions") + chalk.dim(" v" + pkg.version));
18917
19462
  console.log(chalk.cyan(isApiTransport() ? "API:" : "DB:") + " " + dbPath);
@@ -19134,7 +19679,7 @@ profileCmd.command("binding <profile> <config>").description("Set a config's sch
19134
19679
  process.exit(1);
19135
19680
  }
19136
19681
  });
19137
- profileCmd.command("apply [id]").description("Apply all configs in a profile to disk").option("--dry-run", "preview without writing").option("--auto", "resolve the matching profile for the current machine").option("--hostname <hostname>", "override detected hostname for auto resolution").option("--os <os>", "override detected OS for auto resolution").option("--arch <arch>", "override detected arch for auto resolution").action(async (id, opts) => {
19682
+ profileCmd.command("apply [id]").description("Apply all configs in a profile to disk").option("--dry-run", "preview without writing").option("--from <agent>", "verify the hosted Conversations heartbeat for this agent").option("--delivery-verified", "assert channel and direct-message canaries were observed in this acceptance pass").option("--auto", "resolve the matching profile for the current machine").option("--hostname <hostname>", "override detected hostname for auto resolution").option("--os <os>", "override detected OS for auto resolution").option("--arch <arch>", "override detected arch for auto resolution").action(async (id, opts) => {
19138
19683
  try {
19139
19684
  const store = resolveConfigStore();
19140
19685
  const { machine, profile } = await getMachineProfileContext(opts, store);
@@ -19171,6 +19716,14 @@ profileCmd.command("apply [id]").description("Apply all configs in a profile to
19171
19716
  }
19172
19717
  if (report.failures.length > 0)
19173
19718
  process.exitCode = 1;
19719
+ const runtimeReport = await reconcileManagedSkillRuntimes({
19720
+ dryRun: opts.dryRun,
19721
+ agent: opts.from,
19722
+ deliveryVerified: opts.deliveryVerified
19723
+ });
19724
+ printManagedSkillRuntimeReport(runtimeReport);
19725
+ if (runtimeReport.failed > 0)
19726
+ process.exitCode = 1;
19174
19727
  console.log(chalk.dim(`
19175
19728
  ${changed}/${results.length} changed (${selected.slug} on ${machine.hostname} ${machine.os_family}/${machine.arch})`));
19176
19729
  } catch (e) {
@@ -19302,6 +19855,8 @@ sessionCmd.command("plan").description("Produce a dry-run render plan for profil
19302
19855
  ...planJsonForOutput(plan),
19303
19856
  ...globalCoverage ? { globalSourceCoverage: globalCoverage } : {}
19304
19857
  });
19858
+ if (plan.blocked)
19859
+ process.exitCode = 1;
19305
19860
  return;
19306
19861
  }
19307
19862
  console.log(chalk.bold(`${plan.tool} session render plan`) + chalk.dim(` (${plan.adapter.mode})`));
@@ -19328,6 +19883,8 @@ sessionCmd.command("plan").description("Produce a dry-run render plan for profil
19328
19883
  if (globalCoverage.complete)
19329
19884
  console.log(chalk.dim(`global source coverage: ${globalCoverage.expectedSlugs.length}/${globalCoverage.expectedSlugs.length} complete`));
19330
19885
  }
19886
+ if (plan.blocked)
19887
+ process.exitCode = 1;
19331
19888
  console.log(chalk.dim("Dry run only. No files were written."));
19332
19889
  } catch (e) {
19333
19890
  console.error(chalk.red(formatCliError(e)));
@@ -19654,14 +20211,14 @@ mcpCmd.command("install").alias("add").description("Install configs MCP server i
19654
20211
  } else if (target === "codex") {
19655
20212
  const { appendFileSync, existsSync: ex } = await import("fs");
19656
20213
  const { join: j } = await import("path");
19657
- const configPath = j(homedir8(), ".codex", "config.toml");
20214
+ const configPath = j(homedir10(), ".codex", "config.toml");
19658
20215
  const block = `
19659
20216
  [mcp_servers.configs]
19660
20217
  command = "${mcpBinary}"
19661
20218
  args = []
19662
20219
  `;
19663
20220
  if (ex(configPath)) {
19664
- const content = readFileSync13(configPath, "utf-8");
20221
+ const content = readFileSync15(configPath, "utf-8");
19665
20222
  if (content.includes("[mcp_servers.configs]")) {
19666
20223
  console.log(chalk.dim("= Already installed in Codex"));
19667
20224
  continue;
@@ -19672,7 +20229,7 @@ args = []
19672
20229
  } else if (target === "antigravity") {
19673
20230
  const { mkdirSync: md, readFileSync: rf, writeFileSync: wf, existsSync: ex } = await import("fs");
19674
20231
  const { dirname: dn, join: j } = await import("path");
19675
- const configPath = j(homedir8(), ".gemini", "config", "mcp_config.json");
20232
+ const configPath = j(homedir10(), ".gemini", "config", "mcp_config.json");
19676
20233
  let settings = {};
19677
20234
  if (ex(configPath)) {
19678
20235
  try {
@@ -19756,7 +20313,7 @@ DB stats:`));
19756
20313
  if (count > 0)
19757
20314
  console.log(` ${key.padEnd(18)} ${count}`);
19758
20315
  }
19759
- const location = isApiTransport() ? `${process.env["HASNA_INSTRUCTIONS_API_URL"]}/v1` : process.env["HASNA_INSTRUCTIONS_DB_PATH"] || join16(homedir8(), ".hasna", "instructions", "instructions.db");
20316
+ const location = isApiTransport() ? `${process.env["HASNA_INSTRUCTIONS_API_URL"]}/v1` : process.env["HASNA_INSTRUCTIONS_DB_PATH"] || join19(getRawStoreRoot(), "instructions.db");
19760
20317
  console.log(chalk.dim(`
19761
20318
  ${isApiTransport() ? "API" : "DB"}: ${location}`));
19762
20319
  });
@@ -19774,14 +20331,53 @@ program.command("status").description("Health check: total configs, drift from d
19774
20331
  console.log(chalk.cyan("Missing:") + ` ${status.health.missingTargets === 0 ? chalk.green("0") : chalk.yellow(String(status.health.missingTargets))} (file not on disk)`);
19775
20332
  console.log(chalk.cyan("Secrets:") + ` ${status.health.unredactedSecretFindings === 0 ? chalk.green("0 \u2713") : chalk.red(String(status.health.unredactedSecretFindings) + " \u26A0")} unredacted`);
19776
20333
  console.log(chalk.cyan("Retired agents:") + ` ${status.health.retiredAgentRows === 0 ? chalk.green("0") : chalk.yellow(String(status.health.retiredAgentRows))} row(s)`);
20334
+ console.log(chalk.cyan("Skill runtimes:") + ` ${status.health.missingManagedSkillRuntimes === 0 ? chalk.green(`${status.counts.managedSkillRuntimes.healthy} ready`) : chalk.yellow(`${status.health.missingManagedSkillRuntimes} missing`)} (${status.counts.managedSkillRuntimes.skillsPresent} managed skill(s) present)`);
19777
20335
  console.log(chalk.cyan("Templates:") + ` ${status.counts.configs.templates} (with {{VAR}} placeholders)`);
19778
20336
  });
20337
+ var managedSkillsCmd = program.command("managed-skills").description("Inspect or reconcile package-owned runtime contracts for installed managed skills");
20338
+ managedSkillsCmd.command("status").option("--from <agent>", "verify the hosted Conversations heartbeat for this agent").option("--delivery-verified", "assert channel and direct-message canaries were observed in this acceptance pass").option("--json", "output the full local runtime status as JSON").action((opts) => {
20339
+ const report = inspectManagedSkillRuntimes({
20340
+ agent: opts.from,
20341
+ deliveryVerified: opts.deliveryVerified
20342
+ });
20343
+ if (opts.json) {
20344
+ printJson(report);
20345
+ if (report.missing > 0)
20346
+ process.exitCode = 1;
20347
+ return;
20348
+ }
20349
+ if (report.skills_present === 0) {
20350
+ console.log(chalk.dim("No managed skills with package-owned runtime contracts are installed."));
20351
+ return;
20352
+ }
20353
+ for (const runtime of report.runtimes) {
20354
+ if (!runtime.skill_present)
20355
+ continue;
20356
+ const prefix = runtime.healthy ? chalk.green("\u2713") : chalk.yellow("!");
20357
+ console.log(`${prefix} ${runtime.skill} via ${runtime.runtime} \u2014 ${runtime.reason}`);
20358
+ }
20359
+ if (report.missing > 0)
20360
+ process.exitCode = 1;
20361
+ });
20362
+ managedSkillsCmd.command("apply").option("--dry-run", "preview without writing").option("--from <agent>", "verify the hosted Conversations heartbeat for this agent").option("--delivery-verified", "assert channel and direct-message canaries were observed in this acceptance pass").option("--json", "output the reconcile report as JSON").action(async (opts) => {
20363
+ const report = await reconcileManagedSkillRuntimes({
20364
+ dryRun: opts.dryRun,
20365
+ agent: opts.from,
20366
+ deliveryVerified: opts.deliveryVerified
20367
+ });
20368
+ if (opts.json)
20369
+ printJson(report);
20370
+ else
20371
+ printManagedSkillRuntimeReport(report);
20372
+ if (report.failed > 0)
20373
+ process.exitCode = 1;
20374
+ });
19779
20375
  program.command("backup").description("Export configs to a timestamped backup file").action(async () => {
19780
20376
  const { mkdirSync: mk } = await import("fs");
19781
- const backupDir = join16(homedir8(), ".hasna", "instructions", "backups");
20377
+ const backupDir = join19(getRawStoreRoot(), "backups");
19782
20378
  mk(backupDir, { recursive: true });
19783
20379
  const ts = new Date().toISOString().replace(/[:.]/g, "-").replace("T", "-").slice(0, 19);
19784
- const outPath = join16(backupDir, `configs-${ts}.tar.gz`);
20380
+ const outPath = join19(backupDir, `configs-${ts}.tar.gz`);
19785
20381
  const result = await exportConfigs(outPath, { store: resolveConfigStore() });
19786
20382
  const { statSync: st } = await import("fs");
19787
20383
  const size = st(outPath).size;
@@ -19809,9 +20405,9 @@ program.command("doctor").description("Validate configs: syntax, permissions, mi
19809
20405
  console.log(chalk.cyan("Known files on disk:"));
19810
20406
  for (const k of KNOWN_CONFIGS) {
19811
20407
  if (k.rulesDir) {
19812
- existsSync16(expandPath(k.rulesDir)) ? pass(`${k.rulesDir}/ exists`) : k.optional ? skip(`${k.rulesDir}/ (optional)`) : fail2(`${k.rulesDir}/ not found`);
20408
+ existsSync17(expandPath(k.rulesDir)) ? pass(`${k.rulesDir}/ exists`) : k.optional ? skip(`${k.rulesDir}/ (optional)`) : fail2(`${k.rulesDir}/ not found`);
19813
20409
  } else {
19814
- existsSync16(expandPath(k.path)) ? pass(k.path) : k.optional ? skip(`${k.path} (optional)`) : fail2(`${k.path} not found`);
20410
+ existsSync17(expandPath(k.path)) ? pass(k.path) : k.optional ? skip(`${k.path} (optional)`) : fail2(`${k.path} not found`);
19815
20411
  }
19816
20412
  }
19817
20413
  const allConfigs = await store.listConfigs();
@@ -19964,16 +20560,16 @@ program.command("watch").description("Watch known config files for changes and a
19964
20560
  for (const k of KNOWN_CONFIGS) {
19965
20561
  if (k.rulesDir) {
19966
20562
  const absDir = expandPath2(k.rulesDir);
19967
- if (!existsSync16(absDir))
20563
+ if (!existsSync17(absDir))
19968
20564
  continue;
19969
20565
  const { readdirSync: readdirSync5 } = await import("fs");
19970
20566
  for (const f of readdirSync5(absDir).filter((f2) => f2.endsWith(".md"))) {
19971
- const abs = join16(absDir, f);
20567
+ const abs = join19(absDir, f);
19972
20568
  mtimes.set(abs, st(abs).mtimeMs);
19973
20569
  }
19974
20570
  } else {
19975
20571
  const abs = expandPath2(k.path);
19976
- if (existsSync16(abs))
20572
+ if (existsSync17(abs))
19977
20573
  mtimes.set(abs, st(abs).mtimeMs);
19978
20574
  }
19979
20575
  }
@@ -19981,7 +20577,7 @@ program.command("watch").description("Watch known config files for changes and a
19981
20577
  const tick = async () => {
19982
20578
  let changed = 0;
19983
20579
  for (const [abs, oldMtime] of mtimes) {
19984
- if (!existsSync16(abs))
20580
+ if (!existsSync17(abs))
19985
20581
  continue;
19986
20582
  const newMtime = st(abs).mtimeMs;
19987
20583
  if (newMtime !== oldMtime) {
@@ -19993,10 +20589,10 @@ program.command("watch").description("Watch known config files for changes and a
19993
20589
  for (const k of KNOWN_CONFIGS) {
19994
20590
  if (k.rulesDir) {
19995
20591
  const absDir = expandPath2(k.rulesDir);
19996
- if (!existsSync16(absDir))
20592
+ if (!existsSync17(absDir))
19997
20593
  continue;
19998
20594
  for (const f of rd(absDir).filter((f2) => f2.endsWith(".md"))) {
19999
- const abs = join16(absDir, f);
20595
+ const abs = join19(absDir, f);
20000
20596
  if (!mtimes.has(abs)) {
20001
20597
  mtimes.set(abs, st(abs).mtimeMs);
20002
20598
  changed++;
@@ -20004,7 +20600,7 @@ program.command("watch").description("Watch known config files for changes and a
20004
20600
  }
20005
20601
  } else {
20006
20602
  const abs = expandPath2(k.path);
20007
- if (existsSync16(abs) && !mtimes.has(abs)) {
20603
+ if (existsSync17(abs) && !mtimes.has(abs)) {
20008
20604
  mtimes.set(abs, st(abs).mtimeMs);
20009
20605
  changed++;
20010
20606
  }
@@ -20032,11 +20628,11 @@ program.command("report").description("Summary of stored configs, drift, and eco
20032
20628
  if (!c.target_path)
20033
20629
  continue;
20034
20630
  const abs = expandPath(c.target_path);
20035
- if (!existsSync16(abs)) {
20631
+ if (!existsSync17(abs)) {
20036
20632
  missing++;
20037
20633
  continue;
20038
20634
  }
20039
- const disk = readFileSync13(abs, "utf-8");
20635
+ const disk = readFileSync15(abs, "utf-8");
20040
20636
  const { content: redactedDisk } = redactContent(disk, c.format);
20041
20637
  if (redactedDisk !== c.content)
20042
20638
  drifted++;
@@ -20103,7 +20699,7 @@ program.command("clean").description("Remove configs from DB whose target files
20103
20699
  if (!c.target_path)
20104
20700
  continue;
20105
20701
  const abs = expandPath(c.target_path);
20106
- if (!existsSync16(abs)) {
20702
+ if (!existsSync17(abs)) {
20107
20703
  if (printed < maxPrinted) {
20108
20704
  if (opts.dryRun) {
20109
20705
  console.log(chalk.yellow(" would remove:") + ` ${c.slug} ${chalk.dim(`(${truncateMiddle(c.target_path, 88)})`)}`);
@@ -20127,7 +20723,7 @@ ${removed} orphaned config(s) ${opts.dryRun ? "found" : "removed"}${omitted > 0
20127
20723
  console.log(chalk.dim(`Use --limit ${removed} to print every orphan row.`));
20128
20724
  }
20129
20725
  });
20130
- program.command("bootstrap").description("Install the full @hasna ecosystem: CLI tools + MCP servers + configs").option("--dry-run", "show what would be installed without doing it").option("--skip-mcp", "skip MCP server registration").action(async (opts) => {
20726
+ program.command("bootstrap").description("Install the full @hasna ecosystem: CLI tools + MCP servers + configs").option("--dry-run", "show what would be installed without doing it").option("--from <agent>", "verify the hosted Conversations heartbeat for this agent").option("--delivery-verified", "assert channel and direct-message canaries were observed in this acceptance pass").option("--skip-mcp", "skip MCP server registration").action(async (opts) => {
20131
20727
  const store = resolveConfigStore();
20132
20728
  const packages = [
20133
20729
  { name: "@hasna/todos", bin: "todos", mcp: "todos-mcp" },
@@ -20190,8 +20786,22 @@ Initializing configs:`));
20190
20786
  } else {
20191
20787
  console.log(chalk.dim(" would run: configs init"));
20192
20788
  }
20789
+ console.log(chalk.cyan(`
20790
+ Reconciling managed skill runtimes:`));
20791
+ const runtimeReport = await reconcileManagedSkillRuntimes({
20792
+ dryRun: opts.dryRun,
20793
+ agent: opts.from,
20794
+ deliveryVerified: opts.deliveryVerified
20795
+ });
20796
+ printManagedSkillRuntimeReport(runtimeReport);
20797
+ if (runtimeReport.failed > 0) {
20798
+ console.error(chalk.red(`
20799
+ Bootstrap incomplete: a managed skill runtime could not be reconciled.`));
20800
+ process.exitCode = 1;
20801
+ return;
20802
+ }
20193
20803
  console.log(chalk.bold(`
20194
- \u2713 Bootstrap complete.`) + chalk.dim(" Restart Claude Code for MCP servers to activate."));
20804
+ \u2713 Bootstrap complete.`) + chalk.dim(" Restart agent sessions to load updated integrations."));
20195
20805
  });
20196
20806
  program.command("pull").description("Alias for sync (read from disk into DB)").option("-a, --agent <agent>", "only sync this agent").option("--dry-run", "preview without writing").action(async (opts) => {
20197
20807
  const result = await syncKnown({ dryRun: opts.dryRun, agent: opts.agent, store: resolveConfigStore() });