@xmarts/genius-setup 1.7.0 → 1.7.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.
@@ -24,6 +24,7 @@ CFG_PATH = os.path.join(HOME, ".genius", "config.json")
24
24
  TIMEOUT = 3.5
25
25
  SELF_UPDATE_TTL = 86400 # at most once/day
26
26
  SELF_UPDATE_STAMP = os.path.join(HOME, ".genius", ".last_selfupdate")
27
+ FORCE_STAMP = os.path.join(HOME, ".genius", ".last_forced_epoch")
27
28
 
28
29
  SESSION_PRIMER = (
29
30
  "[Xmarts Genius — Brain connected]\n"
@@ -62,7 +63,7 @@ def _inject(cfg, prompt):
62
63
  base = (cfg.get("base_url") or "https://beesmart.digital").rstrip("/")
63
64
  token = cfg.get("token")
64
65
  if not token or not prompt.strip():
65
- return ""
66
+ return "", None, None
66
67
  body = json.dumps({"jsonrpc": "2.0", "method": "call", "id": 1,
67
68
  "params": {"prompt": prompt[:4000], "limit": 4}}).encode()
68
69
  req = urllib.request.Request(base + "/xma/genius/v1/inject", data=body)
@@ -73,17 +74,43 @@ def _inject(cfg, prompt):
73
74
  try:
74
75
  resp = urllib.request.urlopen(req, timeout=TIMEOUT)
75
76
  data = json.loads(resp.read())
76
- result = data.get("result", data)
77
- return (result or {}).get("context", "") or ""
77
+ result = data.get("result", data) or {}
78
+ return ((result.get("context", "") or ""),
79
+ result.get("hook_force_epoch"),
80
+ result.get("hook_pin_version"))
78
81
  except Exception:
79
- return ""
82
+ return "", None, None
80
83
 
81
84
 
82
- def _maybe_self_update(cfg):
83
- """Keep the consultant on the LATEST Genius package with ZERO action: at most
85
+ # M6 (Phase-0 integrity gate): NEVER resolve `@latest`. An unsigned `npx @latest`
86
+ # self-update is a standing fleet-wide RCE channel. We install an EXACT pinned
87
+ # version dictated by the server (xma_genius.hook_pin_version, returned in the
88
+ # inject response) and otherwise fall back to this bundled known-good pin — the
89
+ # client never resolves the mutable `@latest` tag.
90
+ PINNED_FALLBACK = "1.7.2"
91
+
92
+
93
+ def _pkg_spec(pin_version):
94
+ """Resolve the exact package spec to install. Accepts only a plain semver pin
95
+ from the server; anything else falls back to the bundled PINNED_FALLBACK.
96
+ Never returns an `@latest` spec."""
97
+ import re
98
+ v = (pin_version or "").strip()
99
+ if v and re.match(r"^[0-9]+\.[0-9]+\.[0-9]+([.-][0-9A-Za-z.]+)?$", v):
100
+ return "@xmarts/genius-setup@%s" % v
101
+ return "@xmarts/genius-setup@%s" % PINNED_FALLBACK
102
+
103
+
104
+ def _maybe_self_update(cfg, force_epoch=None, pin_version=None):
105
+ """Keep the consultant on the SERVER-PINNED Genius package with ZERO action: at most
84
106
  once/day, silently re-run the installer in the background. New hooks, MCP
85
107
  tools, settings and the CLAUDE.md protocol then flow automatically — the
86
108
  consultant never re-onboards. Detached + fully guarded; never blocks a turn.
109
+
110
+ force_epoch (from the server's inject response) is the admin "push now" lever:
111
+ when the server epoch is newer than the one we last acted on, we upgrade
112
+ IMMEDIATELY, bypassing the daily TTL — and record the epoch so we force at most
113
+ once per bump (never a loop).
87
114
  """
88
115
  import time
89
116
  import subprocess
@@ -91,7 +118,18 @@ def _maybe_self_update(cfg):
91
118
  token = cfg.get("token")
92
119
  if not token:
93
120
  return
94
- if os.path.exists(SELF_UPDATE_STAMP) and (
121
+ forced = False
122
+ if force_epoch:
123
+ try:
124
+ fe = int(force_epoch)
125
+ last = 0
126
+ if os.path.exists(FORCE_STAMP):
127
+ with open(FORCE_STAMP) as fh:
128
+ last = int((fh.read() or "0").strip() or 0)
129
+ forced = fe > last
130
+ except Exception:
131
+ forced = False
132
+ if not forced and os.path.exists(SELF_UPDATE_STAMP) and (
95
133
  time.time() - os.path.getmtime(SELF_UPDATE_STAMP)) < SELF_UPDATE_TTL:
96
134
  return
97
135
  # Stamp FIRST so a failing/slow npx never causes a retry storm.
@@ -99,20 +137,24 @@ def _maybe_self_update(cfg):
99
137
  os.makedirs(os.path.dirname(SELF_UPDATE_STAMP), exist_ok=True)
100
138
  with open(SELF_UPDATE_STAMP, "w") as fh:
101
139
  fh.write(str(int(time.time())))
140
+ if force_epoch:
141
+ with open(FORCE_STAMP, "w") as fh:
142
+ fh.write(str(int(force_epoch)))
102
143
  except Exception:
103
144
  return
104
145
  env = dict(os.environ)
105
146
  env["GENIUS_TOKEN"] = token
106
147
  base = cfg.get("base_url")
148
+ spec = _pkg_spec(pin_version) # exact pinned version — never @latest
107
149
  devnull = open(os.devnull, "w")
108
150
  if os.name == "nt":
109
- cmd = "npx -y @xmarts/genius-setup@latest"
151
+ cmd = "npx -y %s" % spec
110
152
  if base:
111
153
  cmd += ' --base-url "%s"' % base
112
154
  subprocess.Popen(cmd, shell=True, env=env, stdout=devnull, stderr=devnull,
113
155
  stdin=subprocess.DEVNULL, creationflags=0x00000008) # DETACHED_PROCESS
114
156
  else:
115
- args = ["npx", "-y", "@xmarts/genius-setup@latest"]
157
+ args = ["npx", "-y", spec]
116
158
  if base:
117
159
  args += ["--base-url", base]
118
160
  subprocess.Popen(args, env=env, stdout=devnull, stderr=devnull,
@@ -125,14 +167,19 @@ def main():
125
167
  cfg = _cfg()
126
168
  if not cfg.get("token"):
127
169
  return # not configured -> silent no-op
128
- _maybe_self_update(cfg) # background, daily, zero-action upgrades
129
170
  event = _event()
130
171
  name = event.get("hook_event_name") or (
131
172
  "UserPromptSubmit" if event.get("prompt") else "SessionStart")
132
173
  if name == "SessionStart":
174
+ _maybe_self_update(cfg) # TTL-only on priming
133
175
  _emit("SessionStart", SESSION_PRIMER)
134
176
  else:
135
- _emit("UserPromptSubmit", _inject(cfg, event.get("prompt") or ""))
177
+ context, force_epoch, pin_version = _inject(cfg, event.get("prompt") or "")
178
+ # The inject call already round-tripped the server, so honour any
179
+ # admin-pushed force-update epoch here (bypasses the daily TTL) and install
180
+ # the exact server-pinned version (never @latest).
181
+ _maybe_self_update(cfg, force_epoch, pin_version)
182
+ _emit("UserPromptSubmit", context)
136
183
 
137
184
 
138
185
  if __name__ == "__main__":
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xmarts/genius-setup",
3
- "version": "1.7.0",
3
+ "version": "1.7.2",
4
4
  "description": "One-command, self-updating onboarding for Xmarts Genius (Brain MCP + per-turn injection + automatic session/time capture + CLAUDE.md protocol). Secret-free onboarding via single-use setup-token exchange (no Bearer in the GET-able bootstrap). Installs once; self-updates daily so new tools/skills/features arrive with zero action.",
5
5
  "bin": {
6
6
  "genius-setup": "bin/genius-setup.js"