@fidacy/mcp 0.3.4 → 0.4.0
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 +10 -0
- package/dist/config.d.ts +7 -0
- package/dist/core.js +3 -2
- package/dist/index.js +88 -9
- package/dist/lib.js +4 -3
- package/dist/protection.d.ts +64 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Every block is now credited, and every gap is now felt. A denied payment answers with `🛡 Fidacy AI Agent Firewall blocked this payment. Your agent was protected.` — the product's most valuable moment, said in the operator's language, with no upsell attached to it. Around that, the install now reports one honest protection state at boot and on the responses that matter: covered, about to halt, halted, or blocking-but-no-longer-provable. Each state names the brand, states the consequence, and gives one route forward: the free rung (free key, 300 signed verdicts a month) before the paid one (pay-as-you-go from $0.04).
|
|
8
|
+
|
|
9
|
+
What it deliberately does NOT do is tell you your agent is unprotected while the local firewall is still denying payments. This product blocks or halts; it never quietly stops defending. When the anonymous trial runs out the copy says the true and more urgent thing — your agent cannot pay, it is frozen, not exposed — and when a paid allowance runs out it says that your blocks continue but stop being provable to an auditor, insurer or counterparty. A security tool that inflates its own alarm is the one thing we cannot ship.
|
|
10
|
+
|
|
11
|
+
An install that lapses and stays wired in keeps being told, across restarts, that its blocks are no longer provable and how to restore them.
|
|
12
|
+
|
|
3
13
|
## 0.3.4
|
|
4
14
|
|
|
5
15
|
### Patch Changes
|
package/dist/config.d.ts
CHANGED
|
@@ -36,6 +36,13 @@ export interface FidacyConfig {
|
|
|
36
36
|
nudges?: Partial<Record<string, boolean>>;
|
|
37
37
|
/** Payment-gate decisions taken on this install (milestone nudges). */
|
|
38
38
|
decisions_count?: number;
|
|
39
|
+
/**
|
|
40
|
+
* ISO timestamp of when the hosted allowance last ran out. Persisted so the
|
|
41
|
+
* "your blocks are no longer provable" warning survives restarts: an install
|
|
42
|
+
* that lapsed but is still wired in is the highest-intent audience we have.
|
|
43
|
+
* Cleared as soon as a hosted call succeeds again.
|
|
44
|
+
*/
|
|
45
|
+
hosted_lapsed_at?: string;
|
|
39
46
|
}
|
|
40
47
|
/**
|
|
41
48
|
* True when the install carries an operator-set engine key (env, or the plugin's
|
package/dist/core.js
CHANGED
|
@@ -454,7 +454,8 @@ function readConfig() {
|
|
|
454
454
|
// reset every once-per-install nudge into an every-time nag.
|
|
455
455
|
created_at: typeof raw.created_at === "string" ? raw.created_at : void 0,
|
|
456
456
|
nudges: raw.nudges && typeof raw.nudges === "object" ? raw.nudges : void 0,
|
|
457
|
-
decisions_count: typeof raw.decisions_count === "number" ? raw.decisions_count : void 0
|
|
457
|
+
decisions_count: typeof raw.decisions_count === "number" ? raw.decisions_count : void 0,
|
|
458
|
+
hosted_lapsed_at: typeof raw.hosted_lapsed_at === "string" ? raw.hosted_lapsed_at : void 0
|
|
458
459
|
};
|
|
459
460
|
} catch {
|
|
460
461
|
return null;
|
|
@@ -485,7 +486,7 @@ function resolveMandateRules(cfg) {
|
|
|
485
486
|
}
|
|
486
487
|
|
|
487
488
|
// src/telemetry.ts
|
|
488
|
-
var CLIENT_VERSION = true ? "0.
|
|
489
|
+
var CLIENT_VERSION = true ? "0.4.0" : "dev";
|
|
489
490
|
function bandOf(amount) {
|
|
490
491
|
if (typeof amount !== "number" || !Number.isFinite(amount) || amount <= 0) return void 0;
|
|
491
492
|
if (amount < 10) return "lt10";
|
package/dist/index.js
CHANGED
|
@@ -465,7 +465,8 @@ function readConfig() {
|
|
|
465
465
|
// reset every once-per-install nudge into an every-time nag.
|
|
466
466
|
created_at: typeof raw.created_at === "string" ? raw.created_at : void 0,
|
|
467
467
|
nudges: raw.nudges && typeof raw.nudges === "object" ? raw.nudges : void 0,
|
|
468
|
-
decisions_count: typeof raw.decisions_count === "number" ? raw.decisions_count : void 0
|
|
468
|
+
decisions_count: typeof raw.decisions_count === "number" ? raw.decisions_count : void 0,
|
|
469
|
+
hosted_lapsed_at: typeof raw.hosted_lapsed_at === "string" ? raw.hosted_lapsed_at : void 0
|
|
469
470
|
};
|
|
470
471
|
} catch {
|
|
471
472
|
return null;
|
|
@@ -517,7 +518,7 @@ function resolveMandateRules(cfg) {
|
|
|
517
518
|
}
|
|
518
519
|
|
|
519
520
|
// src/telemetry.ts
|
|
520
|
-
var CLIENT_VERSION = true ? "0.
|
|
521
|
+
var CLIENT_VERSION = true ? "0.4.0" : "dev";
|
|
521
522
|
function bandOf(amount) {
|
|
522
523
|
if (typeof amount !== "number" || !Number.isFinite(amount) || amount <= 0) return void 0;
|
|
523
524
|
if (amount < 10) return "lt10";
|
|
@@ -879,7 +880,7 @@ async function findArtifacts(sha2562, cfg) {
|
|
|
879
880
|
}
|
|
880
881
|
|
|
881
882
|
// src/provision.ts
|
|
882
|
-
var CLIENT_VERSION2 = true ? "0.
|
|
883
|
+
var CLIENT_VERSION2 = true ? "0.4.0" : "dev";
|
|
883
884
|
function provisionEnabled() {
|
|
884
885
|
const v = (process.env.FIDACY_DISABLE_PROVISION ?? "").trim().toLowerCase();
|
|
885
886
|
return !(v === "1" || v === "true" || v === "yes");
|
|
@@ -989,9 +990,9 @@ function decisionNudge(status, violatedRule, upgradeToolName) {
|
|
|
989
990
|
function hostedWallCta(feature, billing) {
|
|
990
991
|
const noun = feature === "anchor" ? "Bitcoin-anchored proofs" : "server-signed verdicts";
|
|
991
992
|
if (hasEngineKey()) {
|
|
992
|
-
const
|
|
993
|
+
const where2 = billing?.billingUrl ?? "https://app.fidacy.com/billing";
|
|
993
994
|
const what = billing?.reason === "spending_cap_reached" ? `This account hit the monthly spending cap you set, so ${noun} are paused.` : billing?.detail ?? `This account's included ${noun} for the month are used up.`;
|
|
994
|
-
return `${what} The local firewall keeps deciding and blocking as normal \u2014 this only pauses ${noun}. For your operator: resolve it at ${
|
|
995
|
+
return `${what} The local firewall keeps deciding and blocking as normal \u2014 this only pauses ${noun}. For your operator: resolve it at ${where2}. Pay-as-you-go needs no plan and starts at $0.04 per verdict, dropping to $0.025 past 50k and $0.015 past 250k; committed plans price below that curve.`;
|
|
995
996
|
}
|
|
996
997
|
const url = claimUrl();
|
|
997
998
|
const cta = url ? `open ${url} \u2014 free account, this install's history migrates` : `call the upgrade tool \u2014 free account, your history migrates`;
|
|
@@ -1044,6 +1045,74 @@ function trialCountdownLine(keyOverride) {
|
|
|
1044
1045
|
return ` [fidacy] ${left} free anonymous decision${left === 1 ? "" : "s"} left on this install before the firewall requires activation. For your operator: free API key at ${url} (history migrates), then set FIDACY_ENGINE_API_KEY.`;
|
|
1045
1046
|
}
|
|
1046
1047
|
|
|
1048
|
+
// src/protection.ts
|
|
1049
|
+
var BRAND = "Fidacy AI Agent Firewall";
|
|
1050
|
+
var FREE_MONTHLY_VERDICTS = 300;
|
|
1051
|
+
function markHostedLapsed() {
|
|
1052
|
+
const cfg = readConfig();
|
|
1053
|
+
if (!cfg || cfg.hosted_lapsed_at) return;
|
|
1054
|
+
cfg.hosted_lapsed_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
1055
|
+
try {
|
|
1056
|
+
writeConfig(cfg);
|
|
1057
|
+
} catch {
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
function clearHostedLapsed() {
|
|
1061
|
+
const cfg = readConfig();
|
|
1062
|
+
if (!cfg?.hosted_lapsed_at) return;
|
|
1063
|
+
delete cfg.hosted_lapsed_at;
|
|
1064
|
+
try {
|
|
1065
|
+
writeConfig(cfg);
|
|
1066
|
+
} catch {
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
function isHostedLapsed() {
|
|
1070
|
+
return Boolean(readConfig()?.hosted_lapsed_at);
|
|
1071
|
+
}
|
|
1072
|
+
function protectionState(decisionsUsed2, keyOverride) {
|
|
1073
|
+
if (hasEngineKey(keyOverride)) return isHostedLapsed() ? "unproven" : "protected_keyed";
|
|
1074
|
+
if (decisionsUsed2 >= FREE_DECISIONS) return "halted";
|
|
1075
|
+
return FREE_DECISIONS - decisionsUsed2 <= 5 ? "protected_low" : "protected_trial";
|
|
1076
|
+
}
|
|
1077
|
+
function where() {
|
|
1078
|
+
return claimUrl() ?? "https://fidacy.com/claim";
|
|
1079
|
+
}
|
|
1080
|
+
function protectionBadge() {
|
|
1081
|
+
return `\u{1F6E1} ${BRAND} blocked this payment. Your agent was protected.`;
|
|
1082
|
+
}
|
|
1083
|
+
function protectionWarning(decisionsUsed2, keyOverride) {
|
|
1084
|
+
const state2 = protectionState(decisionsUsed2, keyOverride);
|
|
1085
|
+
const left = Math.max(0, FREE_DECISIONS - decisionsUsed2);
|
|
1086
|
+
switch (state2) {
|
|
1087
|
+
case "protected_trial":
|
|
1088
|
+
return null;
|
|
1089
|
+
// working and nothing is expiring soon: silence is the respect.
|
|
1090
|
+
case "protected_low":
|
|
1091
|
+
return `\u26A0 ${BRAND}: ${left} free decision${left === 1 ? "" : "s"} left on this install. When they run out the firewall fails closed and your agent STOPS being able to pay \u2014 it does not quietly go unprotected, it halts. Keep it running free at ${where()} (free key, ~2 minutes, no card; this install's block history moves with you, plus ${FREE_MONTHLY_VERDICTS} signed verdicts every month).`;
|
|
1092
|
+
case "halted":
|
|
1093
|
+
return `\u26D4 ${BRAND} is NOT ACTIVATED and your agent can no longer pay. The firewall failed closed after ${FREE_DECISIONS} free decisions, which is the safe direction \u2014 no money moves because a trial expired. Your agent is frozen, not exposed. Activate free in ~2 minutes at ${where()}: no card, this install's block history moves with you, and you get ${FREE_MONTHLY_VERDICTS} signed verdicts every month.`;
|
|
1094
|
+
case "unproven":
|
|
1095
|
+
return `\u26A0 ${BRAND}: your agent is still being blocked locally, but its blocks are no longer PROVABLE \u2014 the monthly signed-verdict allowance is spent, so nothing new can be shown to an auditor, insurer or counterparty. Restore proof at https://app.fidacy.com/billing (pay-as-you-go, no plan, from $0.04 per verdict).`;
|
|
1096
|
+
case "protected_keyed":
|
|
1097
|
+
return null;
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
function protectionBootLine(decisionsUsed2) {
|
|
1101
|
+
const state2 = protectionState(decisionsUsed2);
|
|
1102
|
+
switch (state2) {
|
|
1103
|
+
case "halted":
|
|
1104
|
+
return ` \u26D4 NOT ACTIVATED \u2014 your agent cannot pay until you activate at ${where()} (free, no card).`;
|
|
1105
|
+
case "protected_low":
|
|
1106
|
+
return ` \u26A0 ${Math.max(0, FREE_DECISIONS - decisionsUsed2)} free decisions left, then this agent's payments halt. Free key: ${where()}`;
|
|
1107
|
+
case "unproven":
|
|
1108
|
+
return ` \u26A0 Blocking locally, but blocks are no longer provable \u2014 allowance spent. Restore at https://app.fidacy.com/billing`;
|
|
1109
|
+
case "protected_trial":
|
|
1110
|
+
return ` ${BRAND} active \u2014 ${decisionsUsed2}/${FREE_DECISIONS} free decisions used.`;
|
|
1111
|
+
case "protected_keyed":
|
|
1112
|
+
return ` ${BRAND} active and signing \u2014 blocks are provable to third parties.`;
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1047
1116
|
// src/reporting.ts
|
|
1048
1117
|
function withinDays(records, days, now = Date.now()) {
|
|
1049
1118
|
if (!Number.isFinite(days) || days <= 0) return [...records];
|
|
@@ -1312,7 +1381,7 @@ function renderAlertLine(alerts) {
|
|
|
1312
1381
|
var state = ensureState();
|
|
1313
1382
|
var core = makeCore();
|
|
1314
1383
|
var subject = process.env.FIDACY_SUBJECT ?? "agent:demo";
|
|
1315
|
-
var SERVER_VERSION = true ? "0.
|
|
1384
|
+
var SERVER_VERSION = true ? "0.4.0" : "dev";
|
|
1316
1385
|
var bootClaim = claimUrl();
|
|
1317
1386
|
var server = new McpServer(
|
|
1318
1387
|
// The commercial identity. `name` is the stable slug hosts key on; `title` is
|
|
@@ -1354,7 +1423,8 @@ server.registerTool(
|
|
|
1354
1423
|
const gate = activationGate();
|
|
1355
1424
|
if (gate) {
|
|
1356
1425
|
const out2 = { status: "DENY", decisionId: "activation_required", violatedRule: "activation_required" };
|
|
1357
|
-
|
|
1426
|
+
const halted = protectionWarning(decisionsUsed()) ?? gate.message;
|
|
1427
|
+
return { content: [{ type: "text", text: halted }], structuredContent: out2 };
|
|
1358
1428
|
}
|
|
1359
1429
|
const req = args;
|
|
1360
1430
|
let sentinelAlerts = [];
|
|
@@ -1368,9 +1438,11 @@ server.registerTool(
|
|
|
1368
1438
|
const sentinelLine = d.status === "ALLOW" ? renderAlertLine(sentinelAlerts) : "";
|
|
1369
1439
|
const base = d.status === "ALLOW" ? `ALLOW (decision ${d.decisionId})${req.invoiceRef ? ` for invoice ${req.invoiceRef}` : ""}.${sentinelLine} To settle, call execute_payment with the SAME payee, amount, currency, and idempotencyKey, and set "grant" to EXACTLY this signed value:
|
|
1370
1440
|
${d.grant}` : `DENY (decision ${d.decisionId}). Rule violated: ${d.violatedRule}. No grant issued, this payment cannot proceed. The denial itself is recorded in the tamper-evident, hash-chained audit: call get_audit_proof with decisionId ${d.decisionId} for the proof of what was blocked.${d.violatedRule?.startsWith("payee_not_in_allowlist") ? ` If the user trusts this payee, add "${req.payee}" to mandate.payees in ~/.fidacy/config.json and retry: the firewall picks the change up on the next call, no restart needed.` : d.violatedRule?.startsWith("category_not_allowed") ? ` If the user considers "${req.category}" a legitimate purpose for this agent, add it to mandate.categories in ~/.fidacy/config.json and retry: the firewall picks the change up on the next call, no restart needed.` : d.violatedRule?.startsWith("currency_not_allowed") ? ` The mandate is single-currency and set to another one (mandate.currency in ~/.fidacy/config.json, default USD). If this agent legitimately pays in ${req.currency}, update it there and retry: hot-reloaded, no restart.` : ""}`;
|
|
1441
|
+
const badge = d.status === "DENY" ? protectionBadge() : "";
|
|
1371
1442
|
const nudge = decisionNudge(d.status, d.violatedRule, "upgrade");
|
|
1372
1443
|
const countdown = trialCountdownLine();
|
|
1373
|
-
const
|
|
1444
|
+
const lapse = isHostedLapsed() ? protectionWarning(decisionsUsed()) : "";
|
|
1445
|
+
const human = [badge, base, nudge, countdown, lapse].filter(Boolean).join(" ");
|
|
1374
1446
|
return { content: [{ type: "text", text: human }], structuredContent: out };
|
|
1375
1447
|
}
|
|
1376
1448
|
);
|
|
@@ -1537,6 +1609,7 @@ server.registerTool(
|
|
|
1537
1609
|
{ kind, mandate, mandateType, idempotencyKey, spendingMandate, a2a },
|
|
1538
1610
|
{ engineUrl, apiKey }
|
|
1539
1611
|
);
|
|
1612
|
+
clearHostedLapsed();
|
|
1540
1613
|
return {
|
|
1541
1614
|
content: [{ type: "text", text: `${r.decision} (score ${r.score}) signed by ${r.signingKeyId}` }],
|
|
1542
1615
|
structuredContent: r
|
|
@@ -1544,6 +1617,7 @@ server.registerTool(
|
|
|
1544
1617
|
} catch (e) {
|
|
1545
1618
|
if (e instanceof AssessError) {
|
|
1546
1619
|
if (e.status === 402) {
|
|
1620
|
+
markHostedLapsed();
|
|
1547
1621
|
return { content: [{ type: "text", text: hostedWallCta("verdict", e.billing) }], isError: true };
|
|
1548
1622
|
}
|
|
1549
1623
|
const reasons = e.rejection_reasons?.length ? " (" + e.rejection_reasons.map((x) => x.key).join(",") + ")" : "";
|
|
@@ -1609,6 +1683,7 @@ server.registerTool(
|
|
|
1609
1683
|
} catch (e) {
|
|
1610
1684
|
if (e instanceof AssessError) {
|
|
1611
1685
|
if (e.status === 402) {
|
|
1686
|
+
markHostedLapsed();
|
|
1612
1687
|
return { content: [{ type: "text", text: hostedWallCta("anchor", e.billing) }], isError: true };
|
|
1613
1688
|
}
|
|
1614
1689
|
return { content: [{ type: "text", text: `ANCHOR ${e.status}: ${e.type}` }], isError: true };
|
|
@@ -1704,7 +1779,11 @@ async function main() {
|
|
|
1704
1779
|
tier: state.config.tier,
|
|
1705
1780
|
firstRun: state.firstRun,
|
|
1706
1781
|
claim: claimUrl(),
|
|
1707
|
-
|
|
1782
|
+
// The protection state leads the banner nudge slot: an operator who reads
|
|
1783
|
+
// one line of our output should learn whether this agent is covered, about
|
|
1784
|
+
// to halt, or blocking without being able to prove it. The week-one note
|
|
1785
|
+
// only shows when there is no protection gap worth naming.
|
|
1786
|
+
weekNudge: protectionBootLine(decisionsUsed()) ?? weekOneBootNudge("upgrade") ?? ""
|
|
1708
1787
|
})
|
|
1709
1788
|
);
|
|
1710
1789
|
}
|
package/dist/lib.js
CHANGED
|
@@ -588,7 +588,8 @@ function readConfig() {
|
|
|
588
588
|
// reset every once-per-install nudge into an every-time nag.
|
|
589
589
|
created_at: typeof raw.created_at === "string" ? raw.created_at : void 0,
|
|
590
590
|
nudges: raw.nudges && typeof raw.nudges === "object" ? raw.nudges : void 0,
|
|
591
|
-
decisions_count: typeof raw.decisions_count === "number" ? raw.decisions_count : void 0
|
|
591
|
+
decisions_count: typeof raw.decisions_count === "number" ? raw.decisions_count : void 0,
|
|
592
|
+
hosted_lapsed_at: typeof raw.hosted_lapsed_at === "string" ? raw.hosted_lapsed_at : void 0
|
|
592
593
|
};
|
|
593
594
|
} catch {
|
|
594
595
|
return null;
|
|
@@ -640,7 +641,7 @@ function resolveMandateRules(cfg) {
|
|
|
640
641
|
}
|
|
641
642
|
|
|
642
643
|
// src/telemetry.ts
|
|
643
|
-
var CLIENT_VERSION = true ? "0.
|
|
644
|
+
var CLIENT_VERSION = true ? "0.4.0" : "dev";
|
|
644
645
|
function bandOf(amount) {
|
|
645
646
|
if (typeof amount !== "number" || !Number.isFinite(amount) || amount <= 0) return void 0;
|
|
646
647
|
if (amount < 10) return "lt10";
|
|
@@ -828,7 +829,7 @@ function requestUpgrade() {
|
|
|
828
829
|
}
|
|
829
830
|
|
|
830
831
|
// src/provision.ts
|
|
831
|
-
var CLIENT_VERSION2 = true ? "0.
|
|
832
|
+
var CLIENT_VERSION2 = true ? "0.4.0" : "dev";
|
|
832
833
|
function provisionEnabled() {
|
|
833
834
|
const v = (process.env.FIDACY_DISABLE_PROVISION ?? "").trim().toLowerCase();
|
|
834
835
|
return !(v === "1" || v === "true" || v === "yes");
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PROTECTION STATE — the one place that decides what the operator is told about
|
|
3
|
+
* the state of their agent's defence, and the only place allowed to name the
|
|
4
|
+
* product to them.
|
|
5
|
+
*
|
|
6
|
+
* Doctrine (the commercial engine, 2026-07-24): every free thing is a lure to
|
|
7
|
+
* the paid thing, so every save must be ATTRIBUTED and every gap must be FELT.
|
|
8
|
+
* A block the operator never hears about buys us nothing; a lapse they never
|
|
9
|
+
* notice converts nobody.
|
|
10
|
+
*
|
|
11
|
+
* The one line we will not cross: this product never silently stops protecting.
|
|
12
|
+
* It either blocks the payment or it halts the agent. So we never claim "your
|
|
13
|
+
* agent is unprotected" while the local firewall is still denying — that would
|
|
14
|
+
* contradict the boot banner two lines above it, and a security vendor caught
|
|
15
|
+
* inflating its own alarm loses the only thing it sells. The states below are
|
|
16
|
+
* written to be maximally urgent AND literally true, which is also the version
|
|
17
|
+
* that survives a customer reading the source (ours is public).
|
|
18
|
+
*
|
|
19
|
+
* protected_trial local firewall on, anonymous, trial decisions remain
|
|
20
|
+
* protected_low same, but 5 or fewer left — the wall is announced
|
|
21
|
+
* halted anonymous trial spent: the firewall FAILS CLOSED, so the
|
|
22
|
+
* agent cannot pay at all until it is activated
|
|
23
|
+
* protected_keyed activated: local blocking + the monthly signed-verdict
|
|
24
|
+
* allowance
|
|
25
|
+
* unproven activated but the hosted allowance is gone: the agent is
|
|
26
|
+
* STILL blocked locally, and its blocks stopped being
|
|
27
|
+
* provable to anyone outside this machine
|
|
28
|
+
*/
|
|
29
|
+
/** The commercial name. Coined on every surface an operator can read. */
|
|
30
|
+
export declare const BRAND = "Fidacy AI Agent Firewall";
|
|
31
|
+
/** Free signed verdicts included every month on a (free) account. */
|
|
32
|
+
export declare const FREE_MONTHLY_VERDICTS = 300;
|
|
33
|
+
export type ProtectionState = "protected_trial" | "protected_low" | "halted" | "protected_keyed" | "unproven";
|
|
34
|
+
/**
|
|
35
|
+
* Remember that the hosted allowance ran out, so the warning survives restarts.
|
|
36
|
+
* "Stopped paying but still installed" is precisely the state that must keep
|
|
37
|
+
* nagging — it is the highest-intent audience there is: they already wired us in.
|
|
38
|
+
*/
|
|
39
|
+
export declare function markHostedLapsed(): void;
|
|
40
|
+
/** A hosted call succeeded again — the gap closed, so stop warning about it. */
|
|
41
|
+
export declare function clearHostedLapsed(): void;
|
|
42
|
+
export declare function isHostedLapsed(): boolean;
|
|
43
|
+
export declare function protectionState(decisionsUsed: number, keyOverride?: string): ProtectionState;
|
|
44
|
+
/**
|
|
45
|
+
* The attribution line that rides EVERY block. This is the product's single most
|
|
46
|
+
* valuable sentence: the moment it just earned its keep, said in the operator's
|
|
47
|
+
* language, with the name we want them to repeat. It is never a nag — a save is
|
|
48
|
+
* not the moment to sell, it is the moment to be credited.
|
|
49
|
+
*/
|
|
50
|
+
export declare function protectionBadge(): string;
|
|
51
|
+
/**
|
|
52
|
+
* The gap warning, escalating by state. Null when there is nothing true to warn
|
|
53
|
+
* about (an activated install inside its allowance is simply working).
|
|
54
|
+
*
|
|
55
|
+
* Every branch names the brand, states the CONSEQUENCE in the operator's terms,
|
|
56
|
+
* and gives exactly one route forward — free first, paid second, in that order,
|
|
57
|
+
* because the free rung is what makes the paid rung legible.
|
|
58
|
+
*/
|
|
59
|
+
export declare function protectionWarning(decisionsUsed: number, keyOverride?: string): string | null;
|
|
60
|
+
/**
|
|
61
|
+
* One line for the boot banner: what state this install is in, before anything
|
|
62
|
+
* happens. An operator who reads nothing else reads this.
|
|
63
|
+
*/
|
|
64
|
+
export declare function protectionBootLine(decisionsUsed: number): string | null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fidacy/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Fidacy action firewall for AI agents. Mandate-gated payment authorization as an MCP server.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Fidacy (ZeepCode Group Technology LLC) <hello@fidacy.com> (https://fidacy.com)",
|