@compr/opscontext-mcp 2.0.0 → 2.0.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/CHANGELOG.md CHANGED
@@ -2,6 +2,36 @@
2
2
 
3
3
  All notable changes to OpsContext for AI Agents (previously ContextEngine — MCP server + CLI) are documented here.
4
4
 
5
+ ## [2.0.2] — 2026-06-11 — HTML score report browser tab title → OpsContext
6
+
7
+ Tiny patch release. One change:
8
+ - `src/agents.ts` `generateScoreHTML()` — `<title>` tag changed from `ContextEngine Score Report` to `OpsContext Score Report`. Visible in the browser tab when a paying user (or the `score --html` CLI flag) generates the report. No functional change.
9
+
10
+ Why patch: cosmetic-only rename of a user-visible string. No new APIs, no contract changes, no behavior change for any caller.
11
+
12
+ Paired with the VS Code extension `0.8.1` release that adds the `OpsContext: Generate HTML Score Report (PRO)` command — together they close the visible-paid-feature gap from the 2.0.0 rebrand (advertised "HTML score reports — ✓" but no clickable path).
13
+
14
+ ## [2.0.1] — 2026-06-11 — Flag day reached early + pricing href fix
15
+
16
+ ### Changed
17
+ - **Legacy SHA-256 license signatures are now REJECTED** (the "flag day" originally scheduled for 2026-08-15). Brought forward to today because the production licence DB analysis showed the customer base is effectively empty — the only real active license belongs to the maintainer, who has already re-activated to Ed25519. Three other "active" rows in the DB are licenses that expired 2026-04-27 and are already failing the expiry check on every load. Bringing the flag day forward by ~10 weeks costs nothing real and removes the half-open security loophole sooner.
18
+ - `src/license-sig.ts` `verifyLicenseSignature()` — the 64-char hex branch now returns `{ ok: false, reason: "Legacy SHA-256 ... reactivate at ..." }` instead of `{ ok: true, mode: "legacy-grandfathered" }`.
19
+ - LOCK comment on the file updated: the flag-day-reached marker replaces the warning-about-grandfathering text.
20
+ - `src/activation.ts` `loadLicense()` — the `if (verify.mode === "legacy-grandfathered")` branch is now defensive dead code (kept since the union type still carries the variant for backward compat with audit-log records).
21
+ - `tests/license-sig.test.ts` — the test that previously asserted `mode: "legacy-grandfathered"` now asserts `ok: false` with a reactivation pointer in the reason. Test renamed `REJECTS legacy SHA-256 hex signature (flag day reached 2026-06-11)`.
22
+ - **Pricing URL href fix** in 5 source files. The user-facing strings referenced `https://compr.ch/contextengine/pricing` which returns 404; only `https://api.compr.ch/contextengine/pricing` resolves. Files: `src/activation.ts:145, 450`, `src/cli.ts:1882`, `src/index.ts:1132, 1170`.
23
+ - **`docs/deploy/ED25519_FLAG_DAY.md`** can now be archived — the action it scheduled was completed today. Leaving the file in place as a historical record.
24
+ - **`server/deploy.sh` hardened** (this was committed earlier as `bbeffe8`, but tying it to the release for context): pre-flight builds locally, smoke-tests `/health` after deploy and dies on broken state, uses the full PM2 path that actually works in non-interactive ssh shells. Supports `--dry-run`.
25
+
26
+ ### Why this is patch-level, not minor
27
+ The behaviour change is a tightening of a check that was documented as temporary from day one. The semver contract said legacy signatures would be rejected after the flag day; the date moved up because the situation allowed it. No new features. No removed APIs.
28
+
29
+ ### Notes
30
+ - 4 paying-customer rows in the activation DB; 1 is real and active (maintainer's enterprise license, already re-activated). The other 3 already expired April 27 and are non-active per the client's expiry check.
31
+ - Customer notification email (originally scheduled for 2026-08-08) skipped — would have been a no-op or a re-engagement note to the two `gmail.com` addresses whose licenses expired. Yannick can send re-engagement separately if he wants.
32
+
33
+
34
+
5
35
  ## [2.0.0] — 2026-06-10 — Strategic pivot + Claude Code native integration (A+B+C)
6
36
 
7
37
  ### Added (Claude Code integration — A + B + C from the rebrand backlog)
@@ -98,7 +98,7 @@ export function loadLicense() {
98
98
  const verify = verifyLicenseSignature(data);
99
99
  if (!verify.ok) {
100
100
  console.error(`[ContextEngine] ⛔ License signature rejected — ${verify.reason}. Premium features disabled. ` +
101
- `Reactivate at https://compr.ch/contextengine/pricing if this surprises you.`);
101
+ `Reactivate at https://api.compr.ch/contextengine/pricing if this surprises you.`);
102
102
  safeAppend("activation.signature_reject", {
103
103
  plan: data.plan,
104
104
  machine_id: data.machineId,
@@ -106,6 +106,10 @@ export function loadLicense() {
106
106
  });
107
107
  return null;
108
108
  }
109
+ // The legacy-grandfathered branch is no longer reachable since the
110
+ // 2026-06-11 flag day — legacy SHA-256 signatures now return ok:false
111
+ // and are rejected above. Branch kept defensively in case the type
112
+ // union ever changes (zero cost; dead in 2.0.1+).
109
113
  if (verify.mode === "legacy-grandfathered") {
110
114
  console.error(`[ContextEngine] ⚠ ${verify.warning}`);
111
115
  safeAppend("activation.legacy_signature", {
@@ -350,7 +354,7 @@ export function gateCheck(toolName) {
350
354
  if (!license) {
351
355
  return `🔒 "${toolName}" requires a ContextEngine Pro license.\n\n` +
352
356
  `Activate with: npx contextengine activate <license-key> <email>\n` +
353
- `Get a license: https://compr.ch/contextengine/pricing\n\n` +
357
+ `Get a license: https://api.compr.ch/contextengine/pricing\n\n` +
354
358
  `Free tools available: search_context, list_sources, read_source, reindex, ` +
355
359
  `save_session, load_session, list_sessions, end_session, save_learning, ` +
356
360
  `list_learnings, import_learnings`;
package/dist/agents.js CHANGED
@@ -1546,7 +1546,7 @@ export function generateScoreHTML(scores) {
1546
1546
  <head>
1547
1547
  <meta charset="UTF-8">
1548
1548
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
1549
- <title>ContextEngine Score Report</title>
1549
+ <title>OpsContext Score Report</title>
1550
1550
  <style>
1551
1551
  :root {
1552
1552
  --bg: #0f172a; --surface: #1e293b; --border: #334155;
package/dist/cli.js CHANGED
@@ -1782,7 +1782,7 @@ else if (command === "activate") {
1782
1782
  const email = process.argv[4];
1783
1783
  if (!key || !email) {
1784
1784
  console.error("Usage: contextengine activate <license-key> <email>");
1785
- console.error("Get a license: https://compr.ch/contextengine/pricing");
1785
+ console.error("Get a license: https://api.compr.ch/contextengine/pricing");
1786
1786
  process.exit(1);
1787
1787
  }
1788
1788
  activate(key, email).then((result) => {
package/dist/index.js CHANGED
@@ -887,7 +887,7 @@ server.tool("import_learnings", "Bulk-import learnings from a Markdown or JSON f
887
887
  // ---------------------------------------------------------------------------
888
888
  // Tool: activate (License Activation)
889
889
  // ---------------------------------------------------------------------------
890
- server.tool("activate", "Activate a ContextEngine Pro license to unlock premium tools (score_project, run_audit, check_ports, list_projects, HTML reports). Get a license at https://compr.ch/contextengine/pricing", {
890
+ server.tool("activate", "Activate a ContextEngine Pro license to unlock premium tools (score_project, run_audit, check_ports, list_projects, HTML reports). Get a license at https://api.compr.ch/contextengine/pricing", {
891
891
  license_key: z.string().describe("Your ContextEngine license key"),
892
892
  email: z.string().describe("Email associated with the license"),
893
893
  }, async ({ license_key, email }) => {
@@ -918,7 +918,7 @@ server.tool("activation_status", "Check current ContextEngine license status, pl
918
918
  lines.push(`### 🔒 Premium Tools (requires activation)`);
919
919
  lines.push(`- score_project, run_audit, check_ports, list_projects`);
920
920
  lines.push(``);
921
- lines.push(`Get a license: https://compr.ch/contextengine/pricing`);
921
+ lines.push(`Get a license: https://api.compr.ch/contextengine/pricing`);
922
922
  lines.push(`Activate: \`npx contextengine activate <key> <email>\``);
923
923
  }
924
924
  return respond("activation_status", lines.join("\n"));
@@ -1,4 +1,4 @@
1
- // 🔒 LOCKED [LICENSE-SIG] — 2026-06-10
1
+ // 🔒 LOCKED [LICENSE-SIG] — 2026-06-10 (flag day reached 2026-06-11)
2
2
  // ⛔ NEVER change canonicalPayload()'s key order or field set without
3
3
  // bumping a new "sig_v":2 marker AND keeping v1 verification working
4
4
  // forever. The byte output of this function is what the Ed25519
@@ -8,10 +8,11 @@
8
8
  // that pins the client to the production activation server.
9
9
  // Self-hosters override via CE_LICENSE_PUBLIC_KEY env var, which
10
10
  // is the documented escape hatch.
11
- // ⛔ NEVER reject legacy SHA-256 signatures silently. Today they're
12
- // grandfathered with a one-line warning + audit event. The flag
13
- // day for rejection is a SEPARATE commit, called out in CHANGELOG,
14
- // and gives existing licensees 30+ days to reactivate.
11
+ // ⛔ Legacy SHA-256 signatures are NOW REJECTED (flag day reached
12
+ // 2026-06-11 earlier than the originally scheduled 2026-08-15
13
+ // because the customer base is effectively empty and no one would
14
+ // be impacted). The 64-char hex shape returns ok:false with a
15
+ // reactivation pointer.
15
16
  // WHY: Audit identified that loadLicense() did NOT verify the
16
17
  // signature field — anyone could write ~/.contextengine/license.json
17
18
  // with plan:"enterprise" and unlock all PRO tools. Security bug +
@@ -74,11 +75,16 @@ export function verifyLicenseSignature(license, publicKeyPem = process.env.CE_LI
74
75
  }
75
76
  // Legacy detection: pre-Ed25519 signatures were SHA-256 hex (64 chars).
76
77
  // Real Ed25519 signatures are 64 raw bytes → 88-char base64.
78
+ // Flag day reached 2026-06-11: legacy signatures are now REJECTED.
79
+ // The mode "legacy-grandfathered" + the activation.legacy_signature
80
+ // audit event are kept in the type union for backward compatibility
81
+ // with existing audit log records but are no longer emitted.
77
82
  if (/^[a-f0-9]{64}$/.test(license.signature)) {
78
83
  return {
79
- ok: true,
80
- mode: "legacy-grandfathered",
81
- warning: "Legacy SHA-256 license signature accepted (grandfathered). Reactivate to get an Ed25519-signed license pre-flag-day licenses will be rejected after the cutover.",
84
+ ok: false,
85
+ reason: "Legacy SHA-256 license signature is no longer accepted (flag day 2026-06-11). " +
86
+ "Run `npx @compr/opscontext-mcp activate <key> <email>` to refresh to an Ed25519-signed license, " +
87
+ "or see https://api.compr.ch/contextengine/pricing if you need a key.",
82
88
  };
83
89
  }
84
90
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@compr/opscontext-mcp",
3
- "version": "2.0.0",
3
+ "version": "2.0.2",
4
4
  "description": "OpsContext for AI Agents — read-only fleet visibility (PM2/nginx/Docker/git/cron) + tamper-evident audit log + policy-as-code hooks. The ops + compliance layer Claude Code can't grow natively.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",