@hasna/instructions 0.5.1 → 0.5.2

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.
package/dist/cli/index.js CHANGED
@@ -20739,7 +20739,7 @@ projectContextCmd.command("apply").description("Atomically write project context
20739
20739
  }
20740
20740
  });
20741
20741
  var sessionCmd = program.command("session").description("Plan and apply session-scoped agent instruction files");
20742
- sessionCmd.command("plan").description("Produce a dry-run render plan for profile-scoped instruction injection").requiredOption("--tool <tool>", `target tool (${SESSION_RENDER_TOOLS.join("|")})`).requiredOption("--profile <profile>", "account/profile name that owns the rendered instruction home").option("--target-home <path>", "override generated profile-scoped target home").option("--project-root <path>", "repository root for project-scoped adapters such as Cursor").option("--session-id <id>", "session id to include in the manifest").option("--source <layer:id=path>", `instruction source file; layers: ${SESSION_SOURCE_LAYER_HELP}`, collectOption, []).option("--config <layer:id-or-slug>", "stored config source by id/slug; repeatable; layer aliases match --source", collectOption, []).option("--identity-export <path>", "OpenIdentities configs instruction export JSON; repeatable", collectOption, []).option("--replace-source <replacer-id>[=<target-source-id>]", "source id that broadly replaces earlier layers, or targets one earlier source", collectOption, []).option("--compile-profile <id-or-slug>", "compile persisted config bindings from this Instructions profile").option("--provider-version <semver>", "installed provider version used for capability matching").option("--provider-variant <variant>", "explicit provider capability variant (for example OpenCode v2-agents)").option("--model <model>", "active model used for model activation").option("--path <path>", "active path recorded in the graph context").option("--manual <config-id-or-slug>", "manually activate a binding; repeatable", collectOption, []).option("--asset-surface <surface>", "explicit provider asset surface (for example cline cli or ide)").option("--asset-scope <scope>", "asset scope (global|project|session)").option("--allow-asset-installers", "opt in to planned provider installers; planning never invokes them").option("--codewith-native-imports", "select the gated Codewith native @ import adapter").option("--allow-empty-sources", "allow an explicit empty render plan").option("--check-global-coverage", "warn (non-fatal) when a registered, non-retired global-* source is absent from this render's --config list; expected is read fresh from the registry, independent of this plan (todos 102d6d0a)").option("--no-station-profile", "do not inject the cached station-profile source").option("--json", "output dry-run JSON").action(async (opts) => {
20742
+ sessionCmd.command("plan").description("Produce a dry-run render plan for profile-scoped instruction injection").requiredOption("--tool <tool>", `target tool (${SESSION_RENDER_TOOLS.join("|")})`).requiredOption("--profile <profile>", "account/profile name that owns the rendered instruction home").option("--target-home <path>", "override generated profile-scoped target home").option("--project-root <path>", "repository root for project-scoped adapters such as Cursor").option("--session-id <id>", "session id to include in the manifest").option("--source <layer:id=path>", `instruction source file; layers: ${SESSION_SOURCE_LAYER_HELP}`, collectOption, []).option("--config <layer:id-or-slug>", "stored config source by id/slug; repeatable; layer aliases match --source", collectOption, []).option("--identity-export <path>", "OpenIdentities configs instruction export JSON; repeatable", collectOption, []).option("--replace-source <replacer-id>[=<target-source-id>]", "source id that broadly replaces earlier layers, or targets one earlier source", collectOption, []).option("--compile-profile <id-or-slug>", "compile persisted config bindings from this Instructions profile").option("--provider-version <semver>", "installed provider version used for capability matching").option("--provider-variant <variant>", "explicit provider capability variant (for example OpenCode v2-agents)").option("--model <model>", "active model used for model activation").option("--path <path>", "active path recorded in the graph context").option("--manual <config-id-or-slug>", "manually activate a binding; repeatable", collectOption, []).option("--asset-surface <surface>", "explicit provider asset surface (for example cline cli or ide)").option("--asset-scope <scope>", "asset scope (global|project|session)").option("--allow-asset-installers", "opt in to planned provider installers; planning never invokes them").option("--codewith-native-imports", "select the gated Codewith native @ import adapter").option("--allow-empty-sources", "allow an explicit empty render plan").option("--check-global-coverage", "verify every registered, non-retired global-* source is in this render (expected read fresh from the registry, independent of this plan); on shortfall warn, exit non-zero, and for apply refuse to write (todos 102d6d0a, O15-00694)").option("--no-station-profile", "do not inject the cached station-profile source").option("--json", "output dry-run JSON").action(async (opts) => {
20743
20743
  try {
20744
20744
  const tool = opts.tool;
20745
20745
  if (!SESSION_RENDER_TOOLS.includes(tool)) {
@@ -20756,6 +20756,8 @@ sessionCmd.command("plan").description("Produce a dry-run render plan for profil
20756
20756
  });
20757
20757
  if (plan.blocked)
20758
20758
  process.exitCode = 1;
20759
+ if (globalCoverage && !globalCoverage.complete)
20760
+ process.exitCode = 1;
20759
20761
  return;
20760
20762
  }
20761
20763
  console.log(chalk.bold(`${plan.tool} session render plan`) + chalk.dim(` (${plan.adapter.mode})`));
@@ -20784,13 +20786,15 @@ sessionCmd.command("plan").description("Produce a dry-run render plan for profil
20784
20786
  }
20785
20787
  if (plan.blocked)
20786
20788
  process.exitCode = 1;
20789
+ if (globalCoverage && !globalCoverage.complete)
20790
+ process.exitCode = 1;
20787
20791
  console.log(chalk.dim("Dry run only. No files were written."));
20788
20792
  } catch (e) {
20789
20793
  console.error(chalk.red(formatCliError(e)));
20790
20794
  process.exit(1);
20791
20795
  }
20792
20796
  });
20793
- sessionCmd.command("apply").description("Write a session render plan to its managed target home or explicit project root").requiredOption("--tool <tool>", `target tool (${SESSION_RENDER_TOOLS.join("|")})`).requiredOption("--profile <profile>", "account/profile name that owns the rendered instruction home").option("--target-home <path>", "override generated profile-scoped target home").option("--project-root <path>", "repository root for project-scoped adapters such as Cursor").option("--session-id <id>", "session id to include in the manifest").option("--source <layer:id=path>", `instruction source file; layers: ${SESSION_SOURCE_LAYER_HELP}`, collectOption, []).option("--config <layer:id-or-slug>", "stored config source by id/slug; repeatable; layer aliases match --source", collectOption, []).option("--identity-export <path>", "OpenIdentities configs instruction export JSON; repeatable", collectOption, []).option("--replace-source <replacer-id>[=<target-source-id>]", "source id that broadly replaces earlier layers, or targets one earlier source", collectOption, []).option("--compile-profile <id-or-slug>", "compile persisted config bindings from this Instructions profile").option("--provider-version <semver>", "installed provider version used for capability matching").option("--provider-variant <variant>", "explicit provider capability variant (for example OpenCode v2-agents)").option("--model <model>", "active model used for model activation").option("--path <path>", "active path recorded in the graph context").option("--manual <config-id-or-slug>", "manually activate a binding; repeatable", collectOption, []).option("--asset-surface <surface>", "explicit provider asset surface (for example cline cli or ide)").option("--asset-scope <scope>", "asset scope (global|project|session)").option("--codewith-native-imports", "select the gated Codewith native @ import adapter").option("--allow-empty-sources", "allow an explicit empty render").option("--check-global-coverage", "warn (non-fatal) when a registered, non-retired global-* source is absent from this render's --config list; expected is read fresh from the registry, independent of this plan (todos 102d6d0a)").option("--no-station-profile", "do not inject the cached station-profile source").option("--dry-run", "preview writes and conflicts without writing").option("--force", "overwrite existing unmanaged files").option("--json", "output apply JSON").action(async (opts) => {
20797
+ sessionCmd.command("apply").description("Write a session render plan to its managed target home or explicit project root").requiredOption("--tool <tool>", `target tool (${SESSION_RENDER_TOOLS.join("|")})`).requiredOption("--profile <profile>", "account/profile name that owns the rendered instruction home").option("--target-home <path>", "override generated profile-scoped target home").option("--project-root <path>", "repository root for project-scoped adapters such as Cursor").option("--session-id <id>", "session id to include in the manifest").option("--source <layer:id=path>", `instruction source file; layers: ${SESSION_SOURCE_LAYER_HELP}`, collectOption, []).option("--config <layer:id-or-slug>", "stored config source by id/slug; repeatable; layer aliases match --source", collectOption, []).option("--identity-export <path>", "OpenIdentities configs instruction export JSON; repeatable", collectOption, []).option("--replace-source <replacer-id>[=<target-source-id>]", "source id that broadly replaces earlier layers, or targets one earlier source", collectOption, []).option("--compile-profile <id-or-slug>", "compile persisted config bindings from this Instructions profile").option("--provider-version <semver>", "installed provider version used for capability matching").option("--provider-variant <variant>", "explicit provider capability variant (for example OpenCode v2-agents)").option("--model <model>", "active model used for model activation").option("--path <path>", "active path recorded in the graph context").option("--manual <config-id-or-slug>", "manually activate a binding; repeatable", collectOption, []).option("--asset-surface <surface>", "explicit provider asset surface (for example cline cli or ide)").option("--asset-scope <scope>", "asset scope (global|project|session)").option("--codewith-native-imports", "select the gated Codewith native @ import adapter").option("--allow-empty-sources", "allow an explicit empty render").option("--check-global-coverage", "verify every registered, non-retired global-* source is in this render (expected read fresh from the registry, independent of this plan); on shortfall warn, exit non-zero, and for apply refuse to write (todos 102d6d0a, O15-00694)").option("--no-station-profile", "do not inject the cached station-profile source").option("--dry-run", "preview writes and conflicts without writing").option("--force", "overwrite existing unmanaged files").option("--json", "output apply JSON").action(async (opts) => {
20794
20798
  try {
20795
20799
  const tool = opts.tool;
20796
20800
  if (!SESSION_RENDER_TOOLS.includes(tool)) {
@@ -20800,6 +20804,21 @@ sessionCmd.command("apply").description("Write a session render plan to its mana
20800
20804
  const store = resolveConfigStore();
20801
20805
  const plan = await buildSessionRenderPlan(opts, tool, store, "apply");
20802
20806
  const globalCoverage = opts.checkGlobalCoverage ? await checkGlobalSourceCoverage(plan, store) : null;
20807
+ if (globalCoverage && !globalCoverage.complete) {
20808
+ if (opts.json) {
20809
+ printJson({
20810
+ ...planJsonForOutput(plan),
20811
+ globalSourceCoverage: globalCoverage
20812
+ });
20813
+ } else {
20814
+ for (const warning of formatGlobalSourceCoverageWarnings(globalCoverage)) {
20815
+ console.error(chalk.red(`refused: ${warning}`));
20816
+ }
20817
+ console.error(chalk.red(`Refusing to apply: ${globalCoverage.missingSlugs.length} registered global-* source(s) absent from this render. Wire them into --config or tag them retired-global-source.`));
20818
+ }
20819
+ process.exitCode = 1;
20820
+ return;
20821
+ }
20803
20822
  const ownedClaudeAuthorities = tool === "claude" ? await loadOwnedClaudeAuthorities(store) : undefined;
20804
20823
  const result = applySessionRender(plan, { dryRun: opts.dryRun, force: opts.force, ownedClaudeAuthorities });
20805
20824
  if (opts.json) {
package/dist/mcp/index.js CHANGED
@@ -8062,7 +8062,7 @@ var init_sync_dir = __esm(() => {
8062
8062
  var require_package = __commonJS((exports, module) => {
8063
8063
  module.exports = {
8064
8064
  name: "@hasna/instructions",
8065
- version: "0.5.1",
8065
+ version: "0.5.2",
8066
8066
  description: "AI coding agent instruction & configuration manager \u2014 store, version, apply, and share all your AI coding configs. CLI + MCP + HTTP API (instructions-serve) + generated SDK + Dashboard.",
8067
8067
  type: "module",
8068
8068
  main: "dist/index.js",
@@ -16,7 +16,7 @@ var __export = (target, all) => {
16
16
  };
17
17
  var __require = import.meta.require;
18
18
 
19
- // ../../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/compose.js
19
+ // ../../node_modules/.bun/hono@4.13.3/node_modules/hono/dist/compose.js
20
20
  var compose = (middleware, onError, onNotFound) => {
21
21
  return (context, next) => {
22
22
  let index = -1;
@@ -60,10 +60,10 @@ var compose = (middleware, onError, onNotFound) => {
60
60
  };
61
61
  };
62
62
 
63
- // ../../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/request/constants.js
63
+ // ../../node_modules/.bun/hono@4.13.3/node_modules/hono/dist/request/constants.js
64
64
  var GET_MATCH_RESULT = /* @__PURE__ */ Symbol();
65
65
 
66
- // ../../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/utils/buffer.js
66
+ // ../../node_modules/.bun/hono@4.13.3/node_modules/hono/dist/utils/buffer.js
67
67
  var bufferToFormData = (arrayBuffer, contentType) => {
68
68
  const response = new Response(arrayBuffer, {
69
69
  headers: {
@@ -73,7 +73,7 @@ var bufferToFormData = (arrayBuffer, contentType) => {
73
73
  return response.formData();
74
74
  };
75
75
 
76
- // ../../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/utils/body.js
76
+ // ../../node_modules/.bun/hono@4.13.3/node_modules/hono/dist/utils/body.js
77
77
  var isRawRequest = (request) => ("headers" in request);
78
78
  var parseBody = async (request, options = /* @__PURE__ */ Object.create(null)) => {
79
79
  const { all = false, dot = false } = options;
@@ -155,7 +155,7 @@ var handleParsingNestedValues = (form, key, value) => {
155
155
  });
156
156
  };
157
157
 
158
- // ../../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/utils/url.js
158
+ // ../../node_modules/.bun/hono@4.13.3/node_modules/hono/dist/utils/url.js
159
159
  var splitPath = (path) => {
160
160
  const paths = path.split("/");
161
161
  if (paths[0] === "") {
@@ -353,7 +353,7 @@ var getQueryParams = (url, key) => {
353
353
  };
354
354
  var decodeURIComponent_ = decodeURIComponent;
355
355
 
356
- // ../../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/request.js
356
+ // ../../node_modules/.bun/hono@4.13.3/node_modules/hono/dist/request.js
357
357
  var HonoRequest = class {
358
358
  raw;
359
359
  #validatedData;
@@ -464,7 +464,7 @@ var HonoRequest = class {
464
464
  }
465
465
  };
466
466
 
467
- // ../../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/utils/html.js
467
+ // ../../node_modules/.bun/hono@4.13.3/node_modules/hono/dist/utils/html.js
468
468
  var HtmlEscapedCallbackPhase = {
469
469
  Stringify: 1,
470
470
  BeforeStream: 2,
@@ -502,7 +502,7 @@ var resolveCallback = async (str, phase, preserveCallbacks, context, buffer) =>
502
502
  }
503
503
  };
504
504
 
505
- // ../../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/context.js
505
+ // ../../node_modules/.bun/hono@4.13.3/node_modules/hono/dist/context.js
506
506
  var TEXT_PLAIN = "text/plain; charset=UTF-8";
507
507
  var setDefaultContentType = (contentType, headers) => {
508
508
  return {
@@ -684,7 +684,7 @@ var Context = class {
684
684
  };
685
685
  };
686
686
 
687
- // ../../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/router.js
687
+ // ../../node_modules/.bun/hono@4.13.3/node_modules/hono/dist/router.js
688
688
  var METHOD_NAME_ALL = "ALL";
689
689
  var METHOD_NAME_ALL_LOWERCASE = "all";
690
690
  var METHODS = ["get", "post", "put", "delete", "options", "patch", "query"];
@@ -692,10 +692,10 @@ var MESSAGE_MATCHER_IS_ALREADY_BUILT = "Can not add a route since the matcher is
692
692
  var UnsupportedPathError = class extends Error {
693
693
  };
694
694
 
695
- // ../../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/utils/constants.js
695
+ // ../../node_modules/.bun/hono@4.13.3/node_modules/hono/dist/utils/constants.js
696
696
  var COMPOSED_HANDLER = "__COMPOSED_HANDLER";
697
697
 
698
- // ../../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/hono-base.js
698
+ // ../../node_modules/.bun/hono@4.13.3/node_modules/hono/dist/hono-base.js
699
699
  var notFoundHandler = (c) => {
700
700
  return c.text("404 Not Found", 404);
701
701
  };
@@ -920,7 +920,7 @@ var Hono = class _Hono {
920
920
  };
921
921
  };
922
922
 
923
- // ../../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/router/reg-exp-router/matcher.js
923
+ // ../../node_modules/.bun/hono@4.13.3/node_modules/hono/dist/router/reg-exp-router/matcher.js
924
924
  var emptyParam = [];
925
925
  function match(method, path) {
926
926
  const matchers = this.buildAllMatchers();
@@ -941,7 +941,7 @@ function match(method, path) {
941
941
  return match2(method, path);
942
942
  }
943
943
 
944
- // ../../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/router/reg-exp-router/node.js
944
+ // ../../node_modules/.bun/hono@4.13.3/node_modules/hono/dist/router/reg-exp-router/node.js
945
945
  var LABEL_REG_EXP_STR = "[^/]+";
946
946
  var ONLY_WILDCARD_REG_EXP_STR = ".*";
947
947
  var TAIL_WILDCARD_REG_EXP_STR = "(?:|/.*)";
@@ -1044,7 +1044,7 @@ var Node = class _Node {
1044
1044
  }
1045
1045
  };
1046
1046
 
1047
- // ../../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/router/reg-exp-router/trie.js
1047
+ // ../../node_modules/.bun/hono@4.13.3/node_modules/hono/dist/router/reg-exp-router/trie.js
1048
1048
  var Trie = class {
1049
1049
  #context = { varIndex: 0 };
1050
1050
  #root = new Node;
@@ -1107,7 +1107,7 @@ var Trie = class {
1107
1107
  }
1108
1108
  };
1109
1109
 
1110
- // ../../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/router/reg-exp-router/router.js
1110
+ // ../../node_modules/.bun/hono@4.13.3/node_modules/hono/dist/router/reg-exp-router/router.js
1111
1111
  var wildcardRegExpCache = /* @__PURE__ */ Object.create(null);
1112
1112
  function buildWildcardRegExp(path) {
1113
1113
  return wildcardRegExpCache[path] ??= new RegExp(path === "*" ? "" : `^${path.replace(/\/\*$|([.\\+*[^\]$()])/g, (_, metaChar) => metaChar ? `\\${metaChar}` : "(?:|/.*)")}$`);
@@ -1258,7 +1258,7 @@ var RegExpRouter = class {
1258
1258
  }
1259
1259
  };
1260
1260
 
1261
- // ../../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/router/reg-exp-router/prepared-router.js
1261
+ // ../../node_modules/.bun/hono@4.13.3/node_modules/hono/dist/router/reg-exp-router/prepared-router.js
1262
1262
  var PreparedRegExpRouter = class {
1263
1263
  name = "PreparedRegExpRouter";
1264
1264
  #matchers;
@@ -1330,7 +1330,7 @@ var PreparedRegExpRouter = class {
1330
1330
  match = match;
1331
1331
  };
1332
1332
 
1333
- // ../../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/router/smart-router/router.js
1333
+ // ../../node_modules/.bun/hono@4.13.3/node_modules/hono/dist/router/smart-router/router.js
1334
1334
  var SmartRouter = class {
1335
1335
  name = "SmartRouter";
1336
1336
  #routers = [];
@@ -1385,78 +1385,53 @@ var SmartRouter = class {
1385
1385
  }
1386
1386
  };
1387
1387
 
1388
- // ../../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/router/trie-router/node.js
1388
+ // ../../node_modules/.bun/hono@4.13.3/node_modules/hono/dist/router/trie-router/node.js
1389
1389
  var emptyParams = /* @__PURE__ */ Object.create(null);
1390
- var hasChildren = (children) => {
1391
- for (const _ in children) {
1392
- return true;
1393
- }
1394
- return false;
1395
- };
1390
+ var order = 0;
1396
1391
  var Node2 = class _Node2 {
1397
- #methods;
1398
- #children;
1399
- #patterns;
1400
- #order = 0;
1392
+ #methods = [];
1393
+ #children = /* @__PURE__ */ Object.create(null);
1394
+ #patterns = [];
1395
+ #pattern;
1401
1396
  #params = emptyParams;
1402
- constructor(method, handler, children) {
1403
- this.#children = children || /* @__PURE__ */ Object.create(null);
1404
- this.#methods = [];
1405
- if (method && handler) {
1406
- const m = /* @__PURE__ */ Object.create(null);
1407
- m[method] = { handler, possibleKeys: [], score: 0 };
1408
- this.#methods = [m];
1409
- }
1410
- this.#patterns = [];
1411
- }
1412
1397
  insert(method, path, handler) {
1413
- this.#order = ++this.#order;
1414
1398
  let curNode = this;
1415
1399
  const parts = splitRoutingPath(path);
1416
- const possibleKeys = [];
1417
- for (let i = 0, len = parts.length;i < len; i++) {
1418
- const p = parts[i];
1419
- const nextP = parts[i + 1];
1420
- const pattern = getPattern(p, nextP);
1421
- const key = Array.isArray(pattern) ? pattern[0] : p;
1422
- if (key in curNode.#children) {
1423
- curNode = curNode.#children[key];
1424
- if (pattern) {
1425
- possibleKeys.push(pattern[1]);
1426
- }
1427
- continue;
1400
+ const possibleKeys = /* @__PURE__ */ new Set;
1401
+ let i = 0;
1402
+ for (const p of parts) {
1403
+ const nextP = parts[++i];
1404
+ const pattern = getPattern(p, nextP) || (nextP === undefined && p && p.indexOf("*") === p.length - 1 ? p : null);
1405
+ const isParam = Array.isArray(pattern);
1406
+ const key = isParam ? pattern[0] : pattern || p;
1407
+ const child = curNode.#children[key] ||= new _Node2;
1408
+ if (pattern && !child.#pattern) {
1409
+ child.#pattern = pattern;
1410
+ curNode.#patterns.push(child);
1428
1411
  }
1429
- curNode.#children[key] = new _Node2;
1430
- if (pattern) {
1431
- curNode.#patterns.push(pattern);
1432
- possibleKeys.push(pattern[1]);
1412
+ curNode = child;
1413
+ if (isParam) {
1414
+ possibleKeys.add(pattern[1]);
1433
1415
  }
1434
- curNode = curNode.#children[key];
1435
1416
  }
1436
1417
  curNode.#methods.push({
1437
1418
  [method]: {
1438
1419
  handler,
1439
- possibleKeys: possibleKeys.filter((v, i, a) => a.indexOf(v) === i),
1440
- score: this.#order
1420
+ possibleKeys: [...possibleKeys],
1421
+ score: ++order
1441
1422
  }
1442
1423
  });
1443
- return curNode;
1444
1424
  }
1445
1425
  #pushHandlerSets(handlerSets, node, method, nodeParams, params) {
1446
1426
  for (let i = 0, len = node.#methods.length;i < len; i++) {
1447
1427
  const m = node.#methods[i];
1448
1428
  const handlerSet = m[method] || m[METHOD_NAME_ALL];
1449
- const processedSet = {};
1450
- if (handlerSet !== undefined) {
1429
+ if (handlerSet) {
1451
1430
  handlerSet.params = /* @__PURE__ */ Object.create(null);
1452
1431
  handlerSets.push(handlerSet);
1453
- if (nodeParams !== emptyParams || params && params !== emptyParams) {
1454
- for (let i2 = 0, len2 = handlerSet.possibleKeys.length;i2 < len2; i2++) {
1455
- const key = handlerSet.possibleKeys[i2];
1456
- const processed = processedSet[handlerSet.score];
1457
- handlerSet.params[key] = params?.[key] && !processed ? params[key] : nodeParams[key] ?? params?.[key];
1458
- processedSet[handlerSet.score] = true;
1459
- }
1432
+ for (let i2 = 0, len2 = handlerSet.possibleKeys.length;i2 < len2; i2++) {
1433
+ const key = handlerSet.possibleKeys[i2];
1434
+ handlerSet.params[key] = params?.[key] && !i2 ? params[key] : nodeParams[key] ?? params?.[key];
1460
1435
  }
1461
1436
  }
1462
1437
  }
@@ -1488,33 +1463,33 @@ var Node2 = class _Node2 {
1488
1463
  tempNodes.push(nextNode);
1489
1464
  }
1490
1465
  }
1491
- for (let k = 0, len3 = node.#patterns.length;k < len3; k++) {
1492
- const pattern = node.#patterns[k];
1466
+ for (const child of node.#patterns) {
1467
+ const pattern = child.#pattern;
1493
1468
  const params = node.#params === emptyParams ? {} : { ...node.#params };
1494
- if (pattern === "*") {
1495
- const astNode = node.#children["*"];
1496
- if (astNode) {
1497
- this.#pushHandlerSets(handlerSets, astNode, method, node.#params);
1498
- astNode.#params = params;
1499
- tempNodes.push(astNode);
1469
+ if (typeof pattern === "string") {
1470
+ if (pattern === "*" || part.startsWith(pattern.slice(0, -1))) {
1471
+ this.#pushHandlerSets(handlerSets, child, method, node.#params);
1472
+ if (pattern === "*") {
1473
+ child.#params = params;
1474
+ tempNodes.push(child);
1475
+ }
1500
1476
  }
1501
1477
  continue;
1502
1478
  }
1503
- const [key, name, matcher] = pattern;
1504
- if (!part && !(matcher instanceof RegExp)) {
1479
+ const [, name, matcher] = pattern;
1480
+ if (!part && matcher === true) {
1505
1481
  continue;
1506
1482
  }
1507
- const child = node.#children[key];
1508
- if (matcher instanceof RegExp) {
1509
- if (partOffsets === null) {
1510
- partOffsets = new Array(len);
1483
+ if (matcher !== true) {
1484
+ if (!partOffsets) {
1485
+ partOffsets = [];
1511
1486
  let offset = path[0] === "/" ? 1 : 0;
1512
1487
  for (let p = 0;p < len; p++) {
1513
1488
  partOffsets[p] = offset;
1514
1489
  offset += parts[p].length + 1;
1515
1490
  }
1516
1491
  }
1517
- const restPathString = path.substring(partOffsets[i]);
1492
+ const restPathString = path.slice(partOffsets[i]);
1518
1493
  const m = matcher.exec(restPathString);
1519
1494
  if (m) {
1520
1495
  params[name] = m[0];
@@ -1522,11 +1497,12 @@ var Node2 = class _Node2 {
1522
1497
  if (m[0].length === restPathString.length && child.#children["*"]) {
1523
1498
  this.#pushHandlerSets(handlerSets, child.#children["*"], method, node.#params, params);
1524
1499
  }
1525
- if (hasChildren(child.#children)) {
1500
+ for (const _ in child.#children) {
1526
1501
  child.#params = params;
1527
1502
  const componentCount = m[0].match(/\//g)?.length ?? 0;
1528
1503
  const targetCurNodes = curNodesQueue[componentCount] ||= [];
1529
1504
  targetCurNodes.push(child);
1505
+ break;
1530
1506
  }
1531
1507
  continue;
1532
1508
  }
@@ -1548,7 +1524,7 @@ var Node2 = class _Node2 {
1548
1524
  const shifted = curNodesQueue.shift();
1549
1525
  curNodes = shifted ? tempNodes.concat(shifted) : tempNodes;
1550
1526
  }
1551
- if (handlerSets.length > 1) {
1527
+ if (handlerSets[1]) {
1552
1528
  handlerSets.sort((a, b) => {
1553
1529
  return a.score - b.score;
1554
1530
  });
@@ -1557,29 +1533,21 @@ var Node2 = class _Node2 {
1557
1533
  }
1558
1534
  };
1559
1535
 
1560
- // ../../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/router/trie-router/router.js
1536
+ // ../../node_modules/.bun/hono@4.13.3/node_modules/hono/dist/router/trie-router/router.js
1561
1537
  var TrieRouter = class {
1562
1538
  name = "TrieRouter";
1563
- #node;
1564
- constructor() {
1565
- this.#node = new Node2;
1566
- }
1539
+ #node = new Node2;
1567
1540
  add(method, path, handler) {
1568
- const results = checkOptionalParameter(path);
1569
- if (results) {
1570
- for (let i = 0, len = results.length;i < len; i++) {
1571
- this.#node.insert(method, results[i], handler);
1572
- }
1573
- return;
1541
+ for (const result of checkOptionalParameter(path) || [path]) {
1542
+ this.#node.insert(method, result, handler);
1574
1543
  }
1575
- this.#node.insert(method, path, handler);
1576
1544
  }
1577
1545
  match(method, path) {
1578
1546
  return this.#node.search(method, path);
1579
1547
  }
1580
1548
  };
1581
1549
 
1582
- // ../../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/hono.js
1550
+ // ../../node_modules/.bun/hono@4.13.3/node_modules/hono/dist/hono.js
1583
1551
  var Hono2 = class extends Hono {
1584
1552
  constructor(options = {}) {
1585
1553
  super(options);
@@ -1589,7 +1557,7 @@ var Hono2 = class extends Hono {
1589
1557
  }
1590
1558
  };
1591
1559
 
1592
- // ../../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/middleware/cors/index.js
1560
+ // ../../node_modules/.bun/hono@4.13.3/node_modules/hono/dist/middleware/cors/index.js
1593
1561
  var cors = (options) => {
1594
1562
  const opts = {
1595
1563
  origin: "*",
@@ -1639,7 +1607,7 @@ var cors = (options) => {
1639
1607
  }
1640
1608
  if (c.req.method === "OPTIONS") {
1641
1609
  if (opts.origin !== "*") {
1642
- set("Vary", "Origin");
1610
+ c.res.headers.append("Vary", "Origin");
1643
1611
  }
1644
1612
  if (opts.maxAge != null) {
1645
1613
  set("Access-Control-Max-Age", opts.maxAge.toString());
@@ -1747,7 +1715,7 @@ class ProfileNotFoundError extends Error {
1747
1715
  }
1748
1716
  }
1749
1717
 
1750
- // ../contracts/dist/auth/index.js
1718
+ // ../../node_modules/.bun/@hasna+contracts@0.14.0+e8014c875821e0be/node_modules/@hasna/contracts/dist/auth/index.js
1751
1719
  import { createHash, createHmac, randomBytes, timingSafeEqual } from "crypto";
1752
1720
  var MAX_TENANT_ID_LENGTH = 64;
1753
1721
  var TENANT_ID_PATTERN = new RegExp(`^[A-Za-z0-9][A-Za-z0-9._-]{0,${MAX_TENANT_ID_LENGTH - 1}}$`);
@@ -8132,9 +8100,9 @@ async function deleteProfile2(client, idOrSlug) {
8132
8100
  async function addConfigToProfile2(client, profileIdOrSlug, configId) {
8133
8101
  const profile = await getProfile2(client, profileIdOrSlug);
8134
8102
  const maxRow = await client.get("SELECT MAX(sort_order) AS max_order FROM profile_configs WHERE profile_id = $1", [profile.id]);
8135
- const order = (maxRow?.max_order ?? -1) + 1;
8103
+ const order2 = (maxRow?.max_order ?? -1) + 1;
8136
8104
  await client.execute(`INSERT INTO profile_configs (profile_id, config_id, sort_order)
8137
- VALUES ($1,$2,$3) ON CONFLICT (profile_id, config_id) DO NOTHING`, [profile.id, configId, order]);
8105
+ VALUES ($1,$2,$3) ON CONFLICT (profile_id, config_id) DO NOTHING`, [profile.id, configId, order2]);
8138
8106
  }
8139
8107
  async function getProfileConfigBindings2(client, profileIdOrSlug) {
8140
8108
  const profile = await getProfile2(client, profileIdOrSlug);
@@ -8166,8 +8134,8 @@ async function addAssetToProfile2(client, profileIdOrSlug, sourceConfigId, bindi
8166
8134
  await getConfig2(client, sourceConfigId);
8167
8135
  const normalized = normalizeProfileAssetBinding(binding);
8168
8136
  const maxRow = await client.get("SELECT MAX(sort_order) AS max_order FROM profile_assets WHERE profile_id = $1", [profile.id]);
8169
- const order = (maxRow?.max_order ?? -1) + 1;
8170
- await client.execute("INSERT INTO profile_assets (profile_id, source_config_id, asset_key, sort_order, binding) VALUES ($1,$2,$3,$4,$5::jsonb)", [profile.id, sourceConfigId, normalized.assetKey, order, JSON.stringify(normalized)]);
8137
+ const order2 = (maxRow?.max_order ?? -1) + 1;
8138
+ await client.execute("INSERT INTO profile_assets (profile_id, source_config_id, asset_key, sort_order, binding) VALUES ($1,$2,$3,$4,$5::jsonb)", [profile.id, sourceConfigId, normalized.assetKey, order2, JSON.stringify(normalized)]);
8171
8139
  return (await getProfileAssetBindings2(client, profile.id)).find((row) => row.binding.assetKey === normalized.assetKey);
8172
8140
  }
8173
8141
  async function setProfileAssetBinding2(client, profileIdOrSlug, assetKey, binding) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/instructions",
3
- "version": "0.5.1",
3
+ "version": "0.5.2",
4
4
  "description": "AI coding agent instruction & configuration manager — store, version, apply, and share all your AI coding configs. CLI + MCP + HTTP API (instructions-serve) + generated SDK + Dashboard.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",