@primitive.ai/prim 0.1.0-alpha.32 → 0.1.0-alpha.33

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 (2) hide show
  1. package/dist/index.js +33 -15
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -342,6 +342,9 @@ function hookShimCommand(bin, args = "") {
342
342
  const invoke = (cmd) => args ? `${cmd} ${args}` : cmd;
343
343
  return `if command -v ${bin} >/dev/null 2>&1; then ${invoke(bin)}; elif [ -f "./node_modules/.bin/${bin}" ]; then ${invoke(`./node_modules/.bin/${bin}`)}; else ${invoke(`${NPX_FALLBACK} ${bin}`)}; fi`;
344
344
  }
345
+ function detachedHookShimCommand(bin, args = "") {
346
+ return `payload=$(cat); { trap '' HUP; export npm_config_fetch_retries=2 npm_config_fetch_retry_mintimeout=10000 npm_config_fetch_retry_maxtimeout=10000 npm_config_fetch_timeout=60000; printf '%s' "$payload" | { ${hookShimCommand(bin, args)}; }; } </dev/null >/dev/null 2>&1 &`;
347
+ }
345
348
  function commandMatchesBin(command, bin) {
346
349
  if (!command) {
347
350
  return false;
@@ -395,12 +398,17 @@ var CAPTURE_EVENTS = [
395
398
  function makeRegistration(event, matcher, bin, args = "") {
396
399
  return { event, matcher, bin, command: hookShimCommand(bin, args) };
397
400
  }
401
+ function makeDetachedRegistration(event, matcher, bin, args = "") {
402
+ return { event, matcher, bin, command: detachedHookShimCommand(bin, args) };
403
+ }
398
404
  var REGISTRATIONS = [
399
- ...CAPTURE_EVENTS.map((event) => makeRegistration(event, "*", CAPTURE_BIN)),
405
+ ...CAPTURE_EVENTS.map(
406
+ (event) => event === "SessionEnd" ? makeDetachedRegistration(event, "*", CAPTURE_BIN) : makeRegistration(event, "*", CAPTURE_BIN)
407
+ ),
400
408
  makeRegistration("PreToolUse", "Edit|Write|MultiEdit", GATE_BIN),
401
409
  makeRegistration("PostToolUse", "Edit|Write|MultiEdit", POST_TOOL_USE_BIN),
402
410
  makeRegistration("SessionStart", "*", SESSION_START_BIN),
403
- makeRegistration("SessionEnd", "*", SESSION_END_BIN)
411
+ makeDetachedRegistration("SessionEnd", "*", SESSION_END_BIN)
404
412
  ];
405
413
  var PRIM_PERMISSION_RULE = "Bash(npx --yes @primitive.ai/prim*)";
406
414
  var LEGACY_PRIM_PERMISSION_RULES = [
@@ -445,10 +453,9 @@ function stripCommand(list, bin) {
445
453
  return out;
446
454
  }
447
455
  function ensureRegistration(list, reg, force) {
448
- const hasCanonical = list.some(
449
- (e) => e.matcher === reg.matcher && e.hooks?.length === 1 && e.hooks[0].command === reg.command
450
- );
451
- if (hasCanonical && !force) {
456
+ const isCanonical = (e) => e.matcher === reg.matcher && e.hooks?.length === 1 && e.hooks[0].command === reg.command;
457
+ const hasStray = (e) => !isCanonical(e) && (e.hooks ?? []).some((h) => commandMatchesBin(h.command, reg.bin));
458
+ if (list.some(isCanonical) && !list.some(hasStray) && !force) {
452
459
  return list;
453
460
  }
454
461
  return [...stripCommand(list, reg.bin), canonicalEntry(reg)];
@@ -2882,7 +2889,7 @@ function planSetupSteps(opts) {
2882
2889
  });
2883
2890
  }
2884
2891
  steps.push({ key: "hooks", label: "Git hooks", args: ["hooks", "install"], required: true });
2885
- const skillArgs = opts.agent === "hermes" ? ["skill", "install", "--target", ".hermes.md"] : ["skill", "install"];
2892
+ const skillArgs = ["skill", "install", "--agent", opts.agent];
2886
2893
  steps.push({ key: "skill", label: "Agent skill", args: skillArgs, required: true });
2887
2894
  return steps;
2888
2895
  }
@@ -2993,6 +3000,11 @@ var TARGET_CANDIDATES = [
2993
3000
  ".github/instructions/primitive.md"
2994
3001
  ];
2995
3002
  var DEFAULT_TARGET = "CLAUDE.md";
3003
+ var AGENT_TARGET = {
3004
+ claude: "CLAUDE.md",
3005
+ codex: "AGENTS.md",
3006
+ hermes: ".hermes.md"
3007
+ };
2996
3008
  function loadSkill() {
2997
3009
  let dir = __dirname;
2998
3010
  while (dir !== dirname5(dir)) {
@@ -3040,8 +3052,14 @@ function atomicWrite2(target, content) {
3040
3052
  }
3041
3053
  renameSync4(tmp, target);
3042
3054
  }
3043
- function resolveTarget(cwd, override) {
3044
- if (override) return resolve2(cwd, override);
3055
+ function resolveTarget(cwd, opts) {
3056
+ if (opts.target) return resolve2(cwd, opts.target);
3057
+ if (opts.agent) {
3058
+ const mapped = AGENT_TARGET[opts.agent];
3059
+ if (typeof mapped === "string") return resolve2(cwd, mapped);
3060
+ console.error(`Unknown --agent "${opts.agent}" (expected claude, codex, or hermes)`);
3061
+ return null;
3062
+ }
3045
3063
  const matches = detectTargets(cwd);
3046
3064
  if (matches.length === 0) return resolve2(cwd, DEFAULT_TARGET);
3047
3065
  if (matches.length === 1) return resolve2(cwd, matches[0]);
@@ -3050,7 +3068,7 @@ function resolveTarget(cwd, override) {
3050
3068
  return null;
3051
3069
  }
3052
3070
  function runInstall(cwd, opts) {
3053
- const target = resolveTarget(cwd, opts.target);
3071
+ const target = resolveTarget(cwd, opts);
3054
3072
  if (target === null) return 1;
3055
3073
  const existing = existsSync10(target) ? readFileSync8(target, "utf-8") : "";
3056
3074
  const eol = existing ? detectNewline(existing) : "\n";
@@ -3069,7 +3087,7 @@ function runInstall(cwd, opts) {
3069
3087
  return 0;
3070
3088
  }
3071
3089
  function runUninstall(cwd, opts) {
3072
- const target = resolveTarget(cwd, opts.target);
3090
+ const target = resolveTarget(cwd, opts);
3073
3091
  if (target === null) return 1;
3074
3092
  if (!existsSync10(target)) {
3075
3093
  console.log(`Skill block not present at ${target}`);
@@ -3086,7 +3104,7 @@ function runUninstall(cwd, opts) {
3086
3104
  return 0;
3087
3105
  }
3088
3106
  function runStatus(cwd, opts) {
3089
- const target = resolveTarget(cwd, opts.target);
3107
+ const target = resolveTarget(cwd, opts);
3090
3108
  if (target === null) return 1;
3091
3109
  const fileExists = existsSync10(target);
3092
3110
  let installed = false;
@@ -3111,7 +3129,7 @@ function runStatus(cwd, opts) {
3111
3129
  }
3112
3130
  function registerSkillCommands(program2) {
3113
3131
  const skill = program2.command("skill").description("Manage the prim skill in your project rules file");
3114
- skill.command("install").description("Install the prim skill block into your project rules file").option("--target <path>", "Path to the rules file (overrides auto-detection)").option("--dry-run", "Print a unified diff without writing").action((opts) => {
3132
+ skill.command("install").description("Install the prim skill block into your project rules file").option("--target <path>", "Path to the rules file (overrides auto-detection)").option("--agent <agent>", "claude, codex, or hermes (selects the default rules file)").option("--dry-run", "Print a unified diff without writing").action((opts) => {
3115
3133
  try {
3116
3134
  process.exit(runInstall(process.cwd(), opts));
3117
3135
  } catch (err) {
@@ -3119,10 +3137,10 @@ function registerSkillCommands(program2) {
3119
3137
  process.exit(2);
3120
3138
  }
3121
3139
  });
3122
- skill.command("uninstall").description("Remove the prim skill block from your project rules file").option("--target <path>", "Path to the rules file (overrides auto-detection)").action((opts) => {
3140
+ skill.command("uninstall").description("Remove the prim skill block from your project rules file").option("--target <path>", "Path to the rules file (overrides auto-detection)").option("--agent <agent>", "claude, codex, or hermes (selects the default rules file)").action((opts) => {
3123
3141
  process.exit(runUninstall(process.cwd(), opts));
3124
3142
  });
3125
- skill.command("status").description("Report whether the prim skill block is installed").option("--target <path>", "Path to the rules file (overrides auto-detection)").option("--json", "Output as JSON").action((opts) => {
3143
+ skill.command("status").description("Report whether the prim skill block is installed").option("--target <path>", "Path to the rules file (overrides auto-detection)").option("--agent <agent>", "claude, codex, or hermes (selects the default rules file)").option("--json", "Output as JSON").action((opts) => {
3126
3144
  process.exit(runStatus(process.cwd(), opts));
3127
3145
  });
3128
3146
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primitive.ai/prim",
3
- "version": "0.1.0-alpha.32",
3
+ "version": "0.1.0-alpha.33",
4
4
  "description": "CLI for Primitive's decision graph — passive decision capture, conflict gate, and team presence",
5
5
  "type": "module",
6
6
  "license": "MIT",