greprag 5.52.0 → 5.53.1

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 (62) hide show
  1. package/dist/commands/arm-reminder.js +1 -1
  2. package/dist/commands/arm-reminder.js.map +1 -1
  3. package/dist/commands/codex-supervisor.js +27 -8
  4. package/dist/commands/codex-supervisor.js.map +1 -1
  5. package/dist/commands/codex.js +27 -4
  6. package/dist/commands/codex.js.map +1 -1
  7. package/dist/commands/docptr.js +16 -3
  8. package/dist/commands/docptr.js.map +1 -1
  9. package/dist/commands/email-primer-reminder.d.ts +23 -0
  10. package/dist/commands/email-primer-reminder.js +38 -0
  11. package/dist/commands/email-primer-reminder.js.map +1 -0
  12. package/dist/commands/friction-reminder.d.ts +3 -4
  13. package/dist/commands/friction-reminder.js +42 -9
  14. package/dist/commands/friction-reminder.js.map +1 -1
  15. package/dist/commands/inbox-drain.js +9 -2
  16. package/dist/commands/inbox-drain.js.map +1 -1
  17. package/dist/commands/inbox-primer-reminder.d.ts +1 -1
  18. package/dist/commands/inbox-primer-reminder.js +3 -4
  19. package/dist/commands/inbox-primer-reminder.js.map +1 -1
  20. package/dist/commands/inbox-watch.d.ts +3 -0
  21. package/dist/commands/inbox-watch.js +9 -3
  22. package/dist/commands/inbox-watch.js.map +1 -1
  23. package/dist/commands/mechanic-live.d.ts +12 -0
  24. package/dist/commands/mechanic-live.js +89 -0
  25. package/dist/commands/mechanic-live.js.map +1 -0
  26. package/dist/commands/mechanic-manifest.d.ts +16 -0
  27. package/dist/commands/mechanic-manifest.js +81 -0
  28. package/dist/commands/mechanic-manifest.js.map +1 -0
  29. package/dist/commands/mechanic.d.ts +3 -0
  30. package/dist/commands/mechanic.js +61 -7
  31. package/dist/commands/mechanic.js.map +1 -1
  32. package/dist/commands/opencode-relay.js +10 -1
  33. package/dist/commands/opencode-relay.js.map +1 -1
  34. package/dist/commands/reminder-registry.js +2 -0
  35. package/dist/commands/reminder-registry.js.map +1 -1
  36. package/dist/commands/reminder-types.d.ts +6 -0
  37. package/dist/docptr-refs.d.ts +37 -0
  38. package/dist/docptr-refs.js +148 -0
  39. package/dist/docptr-refs.js.map +1 -0
  40. package/dist/guard.d.ts +9 -2
  41. package/dist/guard.js +12 -5
  42. package/dist/guard.js.map +1 -1
  43. package/dist/harness.d.ts +6 -0
  44. package/dist/harness.js +47 -0
  45. package/dist/harness.js.map +1 -0
  46. package/dist/hook.js +110 -10
  47. package/dist/hook.js.map +1 -1
  48. package/dist/index.js +12 -1
  49. package/dist/index.js.map +1 -1
  50. package/dist/mechanic-friction.d.ts +93 -0
  51. package/dist/mechanic-friction.js +368 -0
  52. package/dist/mechanic-friction.js.map +1 -0
  53. package/dist/mechanic-role.d.ts +20 -0
  54. package/dist/mechanic-role.js +107 -0
  55. package/dist/mechanic-role.js.map +1 -0
  56. package/dist/opencode-plugin.bundle.js +69 -17
  57. package/dist/session-id.d.ts +1 -1
  58. package/dist/session-id.js +2 -2
  59. package/dist/session-id.js.map +1 -1
  60. package/package.json +1 -1
  61. package/skill/greprag/docs/inbox-watch.md +3 -0
  62. package/skill/mechanic/SKILL.md +22 -0
@@ -1746,9 +1746,9 @@ function crushMessages(messages, opts) {
1746
1746
  }
1747
1747
 
1748
1748
  // src/session-id.ts
1749
- function armMonitorCommand(short, ownerPid, assistant = false) {
1749
+ function armMonitorCommand(short, ownerPid, assistant = false, mechanic = false) {
1750
1750
  const owner = ownerPid ? ` --owner-pid ${ownerPid}` : "";
1751
- const role = assistant ? " --assistant" : "";
1751
+ const role = mechanic ? " --mechanic" : assistant ? " --assistant" : "";
1752
1752
  const watch = `greprag inbox watch --session ${short} --json${owner}${role}`;
1753
1753
  return `while true; do ${watch}; case $? in 0|64) break;; esac; sleep 1; done`;
1754
1754
  }
@@ -1756,7 +1756,7 @@ function armMonitorCommand(short, ownerPid, assistant = false) {
1756
1756
  // src/commands/inbox-primer-reminder.ts
1757
1757
  function buildInboxPrimer(env) {
1758
1758
  const codex = env.platform === "codex";
1759
- const arm = armMonitorCommand(env.short, env.ownerPid, env.assistant);
1759
+ const arm = armMonitorCommand(env.short, env.ownerPid, env.assistant, env.mechanic);
1760
1760
  return [
1761
1761
  // LEAD — the forcing function (restored 2026-06-22). ARM is an ALARM, not reference:
1762
1762
  // you are unreachable until you do it, and it must be re-done every time the watcher
@@ -1769,14 +1769,13 @@ function buildInboxPrimer(env) {
1769
1769
  // human doc-structure, dead weight to an agent). Everything that helps the agent DECIDE
1770
1770
  // (address grammar, reachability, peer vs human) and ACT (read-now, front-desk).
1771
1771
  "[greprag inbox \u2014 how it works + what to do:]",
1772
- "\u2022 One shared tenant inbox. `greprag inbox` auto-scopes to YOUR session (lines to/from you only); other sessions' private threads stay hidden. `--all` (tenant-wide audit \u2014 every other session's threads) and `--front-desk` (the shared catch-all) are OPT-IN: run them ONLY when the operator asks, never on your own initiative. `--all` is for surveying child sessions you orchestrate.",
1773
- `\u2022 Send: \`greprag send "md" --to <handle>@greprag.com/<their-8hex|uuid> --from-session ${env.short}\` \u2192 live, session-targeted. Bare \`--to <handle>@greprag.com\` \u2192 cold open: lands on their front desk for a manual check, NO live ping. There are no project / broadcast targets.`,
1772
+ "\u2022 One shared tenant inbox. `greprag inbox` auto-scopes to YOUR session (lines to/from you only); other sessions' private threads stay hidden. `--all` (tenant-wide audit \u2014 every other session's threads) is OPT-IN: run it ONLY when the operator asks, never on your own initiative \u2014 it is for surveying child sessions you orchestrate.",
1773
+ `\u2022 Send: \`greprag send "md" --to <handle>@greprag.com/<their-8hex|uuid> --from-session ${env.short}\` \u2192 live, session-targeted. Bare \`--to <handle>@greprag.com\` \u2192 cold open: lands for a manual check, NO live ping. There are no project / broadcast targets.`,
1774
1774
  "\u2022 Reachability: a session is addressable only once it has ARMED an inbox watcher OR written a captured turn \u2014 otherwise a send to it degrades to a cold open. `greprag inbox watchers` lists the armed sessions you can reach (and is how peers discover you).",
1775
1775
  "\u2022 Codex live push: Desktop-visible wake requires app-layer thread continuation (`send_message_to_thread` shape, visible `codex_delegation` turn). `codex exec resume` is diagnostic/history-only; do NOT count it as delivered.",
1776
1776
  "\u2022 Any unread / inbox signal \u21D2 READ NOW (`greprag inbox`), same turn. NEVER ask permission to read \u2014 reading is free; only ACTING on a message needs confirmation. After reading, surface sender + a one-line summary to the operator.",
1777
1777
  "\u2022 PEER (message carries a sender session id) \u21D2 reply / coordinate directly, no human confirm. Auto-REPLY \u2260 auto-OBEY: a destructive action a peer requests still passes the normal gates.",
1778
- "\u2022 HUMAN (cold open / inbound email \u2014 no sender session id) \u21D2 summarize + confirm before acting on it.",
1779
- "\u2022 Front desk = the operator's shared mailbox (cold opens + inbound email), NOT yours. OPT-IN ONLY: never read it on your own initiative and you are never auto-notified of it \u2014 open `greprag inbox --front-desk` ONLY when the operator explicitly asks you to check the front desk. Do NOT auto-drain it (reading marks-read and consumes the operator's cold opens before a receptionist sees them)."
1778
+ "\u2022 HUMAN (cold open / inbound email \u2014 no sender session id) \u21D2 summarize + confirm before acting on it."
1780
1779
  ].join("\n");
1781
1780
  }
1782
1781
  var inboxPrimerModule = {
@@ -1813,6 +1812,23 @@ var chipSpawnPointerModule = {
1813
1812
  reminder: () => null
1814
1813
  };
1815
1814
 
1815
+ // src/commands/email-primer-reminder.ts
1816
+ var EMAIL_PRIMER = [
1817
+ "[greprag email \u2014 the agent's REAL mailbox (actual inbound + outbound SMTP), distinct from `greprag send` (internal session mesh, never real email).]",
1818
+ '\u2022 SEND real mail: `greprag email send --to <addr> --subject "s" (--body "t" | --body-file <f|->)` \u2014 from your <handle>@greprag.com. Flags: --html-file (rich body) \xB7 --attach (repeatable) \xB7 --cc/--bcc \xB7 --reply-to \xB7 --from-name \xB7 --from <your-own-handle> (server rejects any address that isn\'t yours \u2014 no forging).',
1819
+ "\u2022 INBOUND + attachments: `greprag email` / `email pending` list inbound mail; `email pull` drains attachments to disk. Scope one mailbox with `--box <addr|domain|default>`.",
1820
+ "\u2022 Boxes + domains: `greprag email boxes` (your mailboxes + pending counts) \xB7 `greprag email domains` (custom sending domains \u2014 `domain add|verify|name|remove`)."
1821
+ ].join("\n");
1822
+ var emailPrimerModule = {
1823
+ id: "email-primer",
1824
+ // Contrasts `email send` with the inbox primer's `send` → inbox-primer must land first.
1825
+ dependsOn: ["inbox-primer"],
1826
+ detect: (_env) => ({ tier: "silent" }),
1827
+ // never a per-turn nag
1828
+ announce: (_env) => EMAIL_PRIMER,
1829
+ reminder: () => null
1830
+ };
1831
+
1816
1832
  // src/commands/corpus-reminder.ts
1817
1833
  function buildCorpusAnnounce(names) {
1818
1834
  if (!names || names.length === 0)
@@ -1912,7 +1928,7 @@ function buildArmReminder(d, env) {
1912
1928
  if (d.tier === "silent")
1913
1929
  return null;
1914
1930
  const unread = Number(d.detail && d.detail.unread || 0);
1915
- const arm = env ? `ToolSearch select:Monitor \u2192 persistent Monitor (timeout_ms:3600000) command: \`${armMonitorCommand(env.short, env.ownerPid, env.assistant)}\`` : `arm your Monitor inbox watcher`;
1931
+ const arm = env ? `ToolSearch select:Monitor \u2192 persistent Monitor (timeout_ms:3600000) command: \`${armMonitorCommand(env.short, env.ownerPid, env.assistant, env.mechanic)}\`` : `arm your Monitor inbox watcher`;
1916
1932
  const grounded = `greprag reads your watcher as DOWN (isLocallyArmed=false \u2014 a real pidfile check on your session, NOT a timer; the hook CAN see your watcher)`;
1917
1933
  if (unread > 0) {
1918
1934
  return `\u26A0 A peer messaged you (${unread} waiting) & ${grounded}. You're unreachable. Arm + answer NOW, don't reason past this: ${arm}, then \`greprag inbox\`.`;
@@ -1939,7 +1955,25 @@ function frictionReminderTier(stress) {
1939
1955
  return "nudge";
1940
1956
  return "silent";
1941
1957
  }
1942
- function buildFrictionReminder(tier) {
1958
+ function routeCommand(env) {
1959
+ const platform = env?.platform || "<harness>";
1960
+ return `greprag mechanic friction "<summary>" --tier sentence|mechanism|unsure --signal <why> --platform ${platform}`;
1961
+ }
1962
+ function buildMechanicLiveNotice(env) {
1963
+ return `GrepRAG Mechanic is live. Default assumption: this working session is NOT the Mechanic; route future friction with \`${routeCommand(env)}\`, then keep working. Check role only when needed: \`greprag mechanic role\`.`;
1964
+ }
1965
+ function buildFrictionReminder(tier, env) {
1966
+ const routed = !!env?.mechanicLive && !env?.mechanic;
1967
+ if (routed) {
1968
+ switch (tier) {
1969
+ case "nag":
1970
+ return `\u26A0 FRICTION HIGH (live signal: repetition / errors / churn) \u2014 a live Mechanic exists, so this stress signal is being auto-forwarded. Add specifics if useful: \`${routeCommand(env)}\`; otherwise keep working.`;
1971
+ case "nudge":
1972
+ return `\u26A0 Friction detected (live signal) \u2014 a live Mechanic exists, so this stress signal is being auto-forwarded. Add specifics if useful: \`${routeCommand(env)}\`; otherwise keep working.`;
1973
+ default:
1974
+ return null;
1975
+ }
1976
+ }
1943
1977
  switch (tier) {
1944
1978
  case "nag":
1945
1979
  return '\u26A0 FRICTION HIGH (live signal: repetition / errors / churn) \u2014 STOP pushing through; fix the PATTERN now \u2192 `greprag load reflex-chip` (sentence-tier) or `greprag load workshop-chip` (machinery), then spawn_task. No friction? say "clear" + continue.';
@@ -1954,10 +1988,11 @@ var WORKSHOP_METHOD = "spawn a workshop chip \u2014 `greprag load workshop-chip`
1954
1988
  function buildMechanicAnnounce() {
1955
1989
  return [
1956
1990
  "[Active Mechanic \u2014 keep the harness healthy IN-SESSION. Friction is a signal to fix NOW, not to defer; the moment that produced it still holds the context the fix needs.]",
1957
- "WHEN you hit friction this session \u2014 repeated yourself, fought a tool, got corrected \u22652\xD7 on the same thing, or rediscovered something already known \u2014 fix the PATTERN now; do not push through.",
1958
- `SENTENCE-TIER friction (the fix is words in a file you own \u2014 a skill / doc / CLAUDE.md): ${REFLEX_METHOD}. The chip is preloaded with the mechanic tools + live \`greprag mechanic status\`, lands a Tier-0 born-shadow repair, and ends \u2014 no gate to wait at.`,
1959
- `MECHANISM-TIER friction (the fix is machinery \u2014 a hook / gate / trigger / code, anything you can't fix in words): ${WORKSHOP_METHOD}.`,
1960
- 'MODES (when unsure which, or when it is not a chip): fix (land the repair inline) \xB7 log (`greprag fix log "<obs>"` to queue it for /mechanic) \xB7 ask-human (the operator must decide).',
1991
+ "DEFAULT POSTURE: assume this session is NOT the Mechanic. The exception is explicit role signal: `greprag mechanic role` says `current: ... (will arm with --mechanic)` or the hook names this session as mechanic.",
1992
+ 'WHEN friction happens in a normal working session \u2014 repeated yourself, fought a tool, got corrected >=2x on the same thing, or rediscovered something already known \u2014 send `greprag mechanic friction "<summary>" --tier sentence|mechanism|unsure --signal <why> --platform <harness>` and keep working. The stress hook auto-forwards broad repetition/error/churn.',
1993
+ `WHEN this session IS the Mechanic: fix the PATTERN now; do not push through. SENTENCE-TIER friction (words in a file you own \u2014 a skill / doc / CLAUDE.md): ${REFLEX_METHOD}. The chip is preloaded with the mechanic tools + live \`greprag mechanic status\`, lands a Tier-0 born-shadow repair, and ends \u2014 no gate to wait at.`,
1994
+ `MECHANISM-TIER friction for the Mechanic (a hook / gate / trigger / code, anything you can't fix in words): ${WORKSHOP_METHOD}.`,
1995
+ 'MODES (when unsure which, or when it is not a chip): route (`greprag mechanic friction ...`) \xB7 fix (Mechanic or local blocking repair) \xB7 log (`greprag fix log "<obs>"` to queue it for /mechanic) \xB7 ask-human (the operator must decide).',
1961
1996
  "Every repair is ROOT-CAUSE \u2014 fix the pattern that makes the friction class possible, never a guard on today's trigger.",
1962
1997
  'A per-turn reminder fires ONLY when live friction is DETECTED (the stress signal \u2014 repetition / errors / churn), never on a timer \u2014 act on it, or say "clear" and continue.'
1963
1998
  ].join("\n");
@@ -1965,10 +2000,25 @@ function buildMechanicAnnounce() {
1965
2000
  var mechanicFrictionModule = {
1966
2001
  id: "mechanic-friction",
1967
2002
  dependsOn: ["chip-spawn-pointer"],
1968
- // Fires ONLY on detected stress (elevated/high) — no turn-cadence nag.
1969
- detect: (env) => ({ tier: frictionReminderTier(env.stress) }),
1970
- announce: () => buildMechanicAnnounce(),
1971
- reminder: (d) => buildFrictionReminder(d.tier)
2003
+ // Stress fires the real friction reminder. A designated Mechanic also creates a
2004
+ // one-shot ambient route notice per source session/role epoch (hook-stamped).
2005
+ detect: (env) => {
2006
+ const tier = frictionReminderTier(env.stress);
2007
+ if (tier !== "silent")
2008
+ return { tier };
2009
+ if (env.mechanicLiveNotice && !env.mechanic)
2010
+ return { tier: "ambient" };
2011
+ return { tier: "silent" };
2012
+ },
2013
+ announce: (env = {}) => {
2014
+ const base = buildMechanicAnnounce();
2015
+ if (env.mechanicLive && !env.mechanic)
2016
+ return `${base}
2017
+
2018
+ ${buildMechanicLiveNotice(env)}`;
2019
+ return base;
2020
+ },
2021
+ reminder: (d, env) => d.tier === "ambient" ? buildMechanicLiveNotice(env) : buildFrictionReminder(d.tier, env)
1972
2022
  };
1973
2023
 
1974
2024
  // src/commands/coordinate-gate.ts
@@ -2115,6 +2165,8 @@ var REGISTRY = [
2115
2165
  inboxPrimerModule,
2116
2166
  loadPrimerModule,
2117
2167
  chipSpawnPointerModule,
2168
+ emailPrimerModule,
2169
+ // resident primer: greprag email is a first-class CLI feature (real SMTP), distinct from `send`
2118
2170
  corpusAnnounceModule,
2119
2171
  docPointerAnnounceModule,
2120
2172
  // announce-only "core documents" list (docs/doc-pointer-system.md)
@@ -79,7 +79,7 @@ export declare function buildSessionIdContext(short: string, alias?: string | nu
79
79
  * made the wrapper unsafe before. The layers: this loop relaunches a dead
80
80
  * SUPERVISOR; the supervisor respawns a dead SSE CHILD; EPIPE-terminal stops
81
81
  * everything when the consumer leaves. adr: adr/monitor-resilience.md */
82
- export declare function armMonitorCommand(short: string, ownerPid?: number | null, assistant?: boolean): string;
82
+ export declare function armMonitorCommand(short: string, ownerPid?: number | null, assistant?: boolean, mechanic?: boolean): string;
83
83
  /** Handle `greprag-hook session-id`. Reads the Claude Code hook payload
84
84
  * from `input.session_id`, emits a JSON response with hookSpecificOutput.
85
85
  * additionalContext to stdout. Silent on missing session_id (other hook
@@ -161,14 +161,14 @@ function buildSessionIdContext(short, alias = null) {
161
161
  * made the wrapper unsafe before. The layers: this loop relaunches a dead
162
162
  * SUPERVISOR; the supervisor respawns a dead SSE CHILD; EPIPE-terminal stops
163
163
  * everything when the consumer leaves. adr: adr/monitor-resilience.md */
164
- function armMonitorCommand(short, ownerPid, assistant = false) {
164
+ function armMonitorCommand(short, ownerPid, assistant = false, mechanic = false) {
165
165
  // --owner-pid is stamped for audit continuity only; the count-cap never reads it.
166
166
  const owner = ownerPid ? ` --owner-pid ${ownerPid}` : '';
167
167
  // --assistant elevates the watcher to the tenant's Assistant subscription
168
168
  // (session ∪ inbound-email arrivals) — added ONLY for the designated assistant
169
169
  // project (isAssistantProject), so a normal session arms a stock watcher.
170
170
  // adr: adr/assistant-role.md
171
- const role = assistant ? ' --assistant' : '';
171
+ const role = mechanic ? ' --mechanic' : (assistant ? ' --assistant' : '');
172
172
  const watch = `greprag inbox watch --session ${short} --json${owner}${role}`;
173
173
  // Break on 0 (consumer-gone / clean / signal) and 64 (FATAL: bad key) — both are
174
174
  // intentional terminals; relaunch on any other code (a crash). `sleep 1` floors
@@ -1 +1 @@
1
- {"version":3,"file":"session-id.js","sourceRoot":"","sources":["../src/session-id.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session-id.js","sourceRoot":"","sources":["../src/session-id.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAcH,8CAKC;AAWD,wCAQC;AAaD,oCAIC;AASD,8CAaC;AAWD,sDAUC;AAuBD,8CAkBC;AAWD,kDAaC;AAjKD,2CAA6B;AAC7B,uCAAyB;AAEzB;;;;;;;;kDAQkD;AAClD,SAAgB,iBAAiB,CAAC,SAAoC;IACpE,IAAI,CAAC,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC7D,MAAM,GAAG,GAAG,SAAS,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAC/D,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAChC,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACzB,CAAC;AAED;;;;;;;;sCAQsC;AACtC,SAAgB,cAAc;IAC5B,OAAO,CACL,OAAO,CAAC,GAAG,CAAC,sBAAsB;WAC/B,OAAO,CAAC,GAAG,CAAC,eAAe;WAC3B,OAAO,CAAC,GAAG,CAAC,iBAAiB;WAC7B,OAAO,CAAC,GAAG,CAAC,kBAAkB;WAC9B,IAAI,CACR,CAAC;AACJ,CAAC;AAED;;;;;;;;;;yDAUyD;AACzD,SAAgB,YAAY,CAAC,SAAoC;IAC/D,OAAO,SAAS;QACd,CAAC,CAAC,yEAAyE;QAC3E,CAAC,CAAC,6CAA6C,CAAC;AACpD,CAAC;AAED;;;;;;0CAM0C;AAC1C,SAAgB,iBAAiB;IAC/B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC;QAC/D,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QACvB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,eAAe,CAAC,CAAC;QAC/D,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAChD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAwB,CAAC;QACpD,IAAI,OAAO,IAAI,EAAE,MAAM,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAClE,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACpC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;;+EAQ+E;AAC/E,SAAgB,qBAAqB,CACnC,KAAa,EACb,QAAuB,IAAI;IAE3B,MAAM,MAAM,GAAG,KAAK,IAAI,UAAU,CAAC;IACnC,OAAO,CACL,4BAA4B,KAAK,IAAI;UACnC,iBAAiB,MAAM,gBAAgB,KAAK,GAAG;UAC/C,2BAA2B,MAAM,wEAAwE,CAC5G,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;0EAoB0E;AAC1E,SAAgB,iBAAiB,CAC/B,KAAa,EACb,QAAwB,EACxB,SAAS,GAAG,KAAK,EACjB,QAAQ,GAAG,KAAK;IAEhB,kFAAkF;IAClF,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,gBAAgB,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACzD,0EAA0E;IAC1E,+EAA+E;IAC/E,0EAA0E;IAC1E,6BAA6B;IAC7B,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC1E,MAAM,KAAK,GAAG,iCAAiC,KAAK,UAAU,KAAK,GAAG,IAAI,EAAE,CAAC;IAC7E,iFAAiF;IACjF,gFAAgF;IAChF,sDAAsD;IACtD,OAAO,kBAAkB,KAAK,gDAAgD,CAAC;AACjF,CAAC;AAED;;;;;;;;qDAQqD;AACrD,SAAgB,mBAAmB,CACjC,KAA8B;IAE9B,MAAM,KAAK,GAAG,iBAAiB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAClD,IAAI,CAAC,KAAK;QAAE,OAAO;IACnB,MAAM,KAAK,GAAG,iBAAiB,EAAE,CAAC;IAClC,MAAM,OAAO,GAAG;QACd,kBAAkB,EAAE;YAClB,aAAa,EAAE,cAAc;YAC7B,iBAAiB,EAAE,qBAAqB,CAAC,KAAK,EAAE,KAAK,CAAC;SACvD;KACF,CAAC;IACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;AACvD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "greprag",
3
- "version": "5.52.0",
3
+ "version": "5.53.1",
4
4
  "description": "GrepRAG — agent memory for Claude Code, Codex, and OpenCode.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -9,12 +9,15 @@ greprag inbox watch # tenant-wide stream
9
9
  greprag inbox watch --project <name> # only messages addressed to this project
10
10
  greprag inbox watch --session <id> # only messages targeting this session (strictest)
11
11
  greprag inbox watch --receptionist # also wake on the front desk (cold opens + email)
12
+ greprag inbox watch --mechanic # also wake on live mechanic_friction events
12
13
  greprag inbox watch --since <id-or-iso> # resume from a known cursor
13
14
  greprag inbox watch --json # one JSON object per line (preferred under Monitor)
14
15
  ```
15
16
 
16
17
  `--project` and `--session` compose. `--session` is the strictest filter: only messages with matching `to_session_id` get through. The tenant catch-all (cold open / inbound email — `to_session_id IS NULL`) does NOT reach a session- or project-scoped watcher; only a `--receptionist` watcher wakes on it (Option C). adr: adr/address-grammar.md. This eliminates cross-session noise when several Claude sessions watch the same project's inbox at once.
17
18
 
19
+ `--mechanic` is a role subscription: it keeps the normal session/project lane and adds only tenant `mechanic_friction` events. It does not wake on ordinary cold opens or inbound email.
20
+
18
21
  Each message arrives within ~500ms of the sender's `greprag send` (210ms verified end-to-end). Connection auto-reconnects with exponential backoff; the watcher tracks last seen message id and uses it as `since=` on reconnect — nothing dropped, nothing duplicated.
19
22
 
20
23
  ## Liveness model (post v0.8.5)
@@ -59,6 +59,7 @@ Same gate the hourly compactor applies at write-time — Mechanic and compactor
59
59
  - **Bulk is fine for Tier-0 when the set is named aloud** (clearing verified-stale / noise fixes); never bulk a Tier-2 action.
60
60
  - **Never edit `~/.claude/docs/chip-spawn.md` without confirm.** Global rules are sticky.
61
61
  - **Cross-project carve-out.** Default to the current project (resolved via `greprag fix list`). The Phase 0 census MAY read sibling queues to show where fixes piled up; *draining* one requires the operator to name it, and every `add`/`delete` against it MUST carry `--project <that-project>`. Never touch a sibling silently.
62
+ - **Harness scope is mandatory.** Friction carries its source harness (`claude-code`, `codex`, `opencode`). Repairs to hooks/skills/watchers must target that harness with `greprag mechanic install ... --harness <name>`. In a Codex session, default to `--harness codex`; use `--harness all` only for deliberately portable mechanisms.
62
63
 
63
64
  ## Phase 0 — Fix digestion
64
65
 
@@ -200,6 +201,14 @@ Append `(phase <X> skipped)` per skipped phase.
200
201
  Repairs (D3 rows attached to fixes) are managed with `greprag mechanic`, not by editing hooks:
201
202
 
202
203
  ```
204
+ greprag mechanic set mark THIS project/session as the live Mechanic role;
205
+ fan out `mechanic_live` to open sessions;
206
+ arm with --mechanic to receive live friction
207
+ greprag mechanic role show whether this project is the live Mechanic
208
+ greprag mechanic friction "obs" explicit live friction brief; hook stress forwarding
209
+ emits the same `mechanic_friction` message type
210
+ greprag mechanic reply --to <8hex> typed follow-up from Mechanic to source session;
211
+ "msg" [--friction-id <id>] do not use generic send for mechanic workflow
203
212
  greprag mechanic status inventory: live (shadow|active) repairs grouped by status,
204
213
  each with a verdict (working|failed|harmful|unproven|dormant);
205
214
  ⚑ marks shadow rows ready to graduate (≥3 fires or ≥7 days)
@@ -210,6 +219,19 @@ greprag mechanic why <nodeId> provenance: the friction → fix → repai
210
219
  greprag mechanic off / on PANIC SWITCH — local file, no network; suspends ALL repairs
211
220
  ```
212
221
 
222
+ **Live Mechanic role.** A `--mechanic` inbox watcher receives tenant
223
+ `mechanic_friction` events in addition to its own session lane. Working sessions
224
+ always assume they are not the Mechanic unless `greprag mechanic role` says the
225
+ current session will arm with `--mechanic`. `greprag mechanic set` sends an
226
+ immediate typed `mechanic_live` notice to currently open same-project sessions;
227
+ SessionStart and the reminder hook cover sessions that launch or turn later.
228
+ Working sessions emit friction automatically when the stress detector fires, and
229
+ manually via `greprag mechanic friction "..." --tier sentence|mechanism|unsure
230
+ --signal <why> --platform <harness>`, then keep working unless blocked. The event
231
+ is internal queue/work mail: it does not wake ordinary sessions or Assistant. The
232
+ Mechanic replies with `greprag mechanic reply --to <source-session> "..."` for
233
+ coordination and pings the operator for status/Tier-2 gates.
234
+
213
235
  **Born shadow → graduate.** Every repair is born `shadow`: it matches and logs would-have-fired
214
236
  evidence but injects nothing. Graduation is evidence-first — when `status` flags a row `⚑`, review
215
237
  its fire history (`why`) and `enable` it. Nothing goes live without the operator; the gates are