@fidacy/openclaw-plugin 0.2.9 → 0.2.11
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 +6 -0
- package/dist/index.js +50 -9
- package/openclaw.plugin.json +6 -2
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.10
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 01f0734: Two fixes proven against a real OpenClaw host. Install/active telemetry now flushes immediately at plugin load instead of on a 2s timer that died with short-lived CLI commands (openclaw plugins install/list), which is why the plugin channel reported zero despite real installs. And the manifest now declares every registered tool (spend_summary, list_decisions, sentinel_alerts, explain_decision were missing, tripping openclaw plugins doctor); the build stamps contracts.tools from the source so it can never drift again.
|
|
8
|
+
|
|
3
9
|
## 0.2.9
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
package/dist/index.js
CHANGED
|
@@ -4308,10 +4308,23 @@ function lookalikePayee(payee, allowed) {
|
|
|
4308
4308
|
}
|
|
4309
4309
|
return null;
|
|
4310
4310
|
}
|
|
4311
|
+
function validateMandateCaps(mandate) {
|
|
4312
|
+
const bad = (v) => typeof v !== "number" || !Number.isFinite(v) || v <= 0;
|
|
4313
|
+
if (!mandate.allow || typeof mandate.allow !== "object")
|
|
4314
|
+
return "invalid_mandate:missing_allow";
|
|
4315
|
+
if (bad(mandate.allow.perTxMax))
|
|
4316
|
+
return `invalid_mandate_cap:perTxMax=${String(mandate.allow.perTxMax)}`;
|
|
4317
|
+
if (bad(mandate.allow.maxTotal))
|
|
4318
|
+
return `invalid_mandate_cap:maxTotal=${String(mandate.allow.maxTotal)}`;
|
|
4319
|
+
return null;
|
|
4320
|
+
}
|
|
4311
4321
|
function evaluate(mandate, req, spentSoFar) {
|
|
4312
4322
|
const now = Date.now();
|
|
4313
4323
|
if (mandate.revoked)
|
|
4314
4324
|
return "mandate_revoked";
|
|
4325
|
+
const badCap = validateMandateCaps(mandate);
|
|
4326
|
+
if (badCap)
|
|
4327
|
+
return badCap;
|
|
4315
4328
|
if (now < Date.parse(mandate.window.notBefore))
|
|
4316
4329
|
return "before_mandate_window";
|
|
4317
4330
|
if (now > Date.parse(mandate.window.notAfter))
|
|
@@ -4638,6 +4651,9 @@ import {
|
|
|
4638
4651
|
readFileSync,
|
|
4639
4652
|
writeFileSync
|
|
4640
4653
|
} from "node:fs";
|
|
4654
|
+
function hasEngineKey(keyOverride) {
|
|
4655
|
+
return Boolean((keyOverride ?? process.env.FIDACY_ENGINE_API_KEY ?? "").trim());
|
|
4656
|
+
}
|
|
4641
4657
|
function configDir() {
|
|
4642
4658
|
return process.env.FIDACY_CONFIG_DIR ?? join(homedir(), ".fidacy");
|
|
4643
4659
|
}
|
|
@@ -4698,18 +4714,29 @@ function ensureState() {
|
|
|
4698
4714
|
function resolveMandateRules(cfg) {
|
|
4699
4715
|
const m = cfg?.mandate ?? {};
|
|
4700
4716
|
const envList = (v) => v === void 0 ? void 0 : v.split(",").map((s) => s.trim()).filter(Boolean);
|
|
4701
|
-
const envNum = (v) =>
|
|
4717
|
+
const envNum = (name, v) => {
|
|
4718
|
+
if (v === void 0 || v.trim() === "") return void 0;
|
|
4719
|
+
const n = Number(v);
|
|
4720
|
+
if (!Number.isFinite(n) || n <= 0) {
|
|
4721
|
+
console.error(
|
|
4722
|
+
`[fidacy] ${name}="${v}" is not a positive number, so it cannot be enforced as a cap. Ignoring it and using the safe default. Write digits only, with no thousands separator, currency symbol or unit (e.g. ${name}=2500).`
|
|
4723
|
+
);
|
|
4724
|
+
return void 0;
|
|
4725
|
+
}
|
|
4726
|
+
return n;
|
|
4727
|
+
};
|
|
4728
|
+
const fileNum = (v) => typeof v === "number" && Number.isFinite(v) && v > 0 ? v : void 0;
|
|
4702
4729
|
return {
|
|
4703
4730
|
payees: envList(process.env.FIDACY_ALLOW_PAYEES) ?? m.payees ?? [],
|
|
4704
4731
|
categories: envList(process.env.FIDACY_ALLOW_CATEGORIES) ?? m.categories ?? ["*"],
|
|
4705
4732
|
currency: process.env.FIDACY_CURRENCY ?? m.currency ?? "USD",
|
|
4706
|
-
perTxMax: envNum(process.env.FIDACY_PER_TX_MAX) ?? m.perTxMax ?? 2500,
|
|
4707
|
-
maxTotal: envNum(process.env.FIDACY_MAX_TOTAL) ?? m.maxTotal ?? 1e4
|
|
4733
|
+
perTxMax: envNum("FIDACY_PER_TX_MAX", process.env.FIDACY_PER_TX_MAX) ?? fileNum(m.perTxMax) ?? 2500,
|
|
4734
|
+
maxTotal: envNum("FIDACY_MAX_TOTAL", process.env.FIDACY_MAX_TOTAL) ?? fileNum(m.maxTotal) ?? 1e4
|
|
4708
4735
|
};
|
|
4709
4736
|
}
|
|
4710
4737
|
|
|
4711
4738
|
// ../mcp/src/telemetry.ts
|
|
4712
|
-
var CLIENT_VERSION = true ? "0.2.
|
|
4739
|
+
var CLIENT_VERSION = true ? "0.2.11" : "dev";
|
|
4713
4740
|
function bandOf(amount) {
|
|
4714
4741
|
if (typeof amount !== "number" || !Number.isFinite(amount) || amount <= 0) return void 0;
|
|
4715
4742
|
if (amount < 10) return "lt10";
|
|
@@ -4748,6 +4775,14 @@ function anonId() {
|
|
|
4748
4775
|
}
|
|
4749
4776
|
var buffer = [];
|
|
4750
4777
|
var flushTimer = null;
|
|
4778
|
+
var exitHookArmed = false;
|
|
4779
|
+
function armExitFlush() {
|
|
4780
|
+
if (exitHookArmed || typeof process === "undefined" || typeof process.once !== "function") return;
|
|
4781
|
+
exitHookArmed = true;
|
|
4782
|
+
process.once("beforeExit", () => {
|
|
4783
|
+
if (buffer.length > 0) void flush();
|
|
4784
|
+
});
|
|
4785
|
+
}
|
|
4751
4786
|
function resultOf(status, violatedRule) {
|
|
4752
4787
|
if (status === "ALLOW") return "allow";
|
|
4753
4788
|
const r = violatedRule ?? "";
|
|
@@ -4762,6 +4797,7 @@ function resultOf(status, violatedRule) {
|
|
|
4762
4797
|
}
|
|
4763
4798
|
function record(type, result, band, capRatio, action) {
|
|
4764
4799
|
if (!telemetryEnabled()) return;
|
|
4800
|
+
armExitFlush();
|
|
4765
4801
|
buffer.push({
|
|
4766
4802
|
type,
|
|
4767
4803
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -4888,7 +4924,7 @@ function requestUpgrade() {
|
|
|
4888
4924
|
}
|
|
4889
4925
|
|
|
4890
4926
|
// ../mcp/src/provision.ts
|
|
4891
|
-
var CLIENT_VERSION2 = true ? "0.2.
|
|
4927
|
+
var CLIENT_VERSION2 = true ? "0.2.11" : "dev";
|
|
4892
4928
|
function provisionEnabled() {
|
|
4893
4929
|
const v = (process.env.FIDACY_DISABLE_PROVISION ?? "").trim().toLowerCase();
|
|
4894
4930
|
return !(v === "1" || v === "true" || v === "yes");
|
|
@@ -4985,9 +5021,6 @@ function noKeyCta() {
|
|
|
4985
5021
|
|
|
4986
5022
|
// ../mcp/src/activation.ts
|
|
4987
5023
|
var FREE_DECISIONS = 20;
|
|
4988
|
-
function hasEngineKey(keyOverride) {
|
|
4989
|
-
return Boolean((keyOverride ?? process.env.FIDACY_ENGINE_API_KEY ?? "").trim());
|
|
4990
|
-
}
|
|
4991
5024
|
function decisionsUsed() {
|
|
4992
5025
|
return Math.max(readConfig()?.decisions_count ?? 0, sessionDecisionCount());
|
|
4993
5026
|
}
|
|
@@ -5220,6 +5253,7 @@ var AssessError = class extends Error {
|
|
|
5220
5253
|
status;
|
|
5221
5254
|
details;
|
|
5222
5255
|
rejection_reasons;
|
|
5256
|
+
billing;
|
|
5223
5257
|
constructor(opts) {
|
|
5224
5258
|
super(`Fidacy assess error (${opts.type}, HTTP ${opts.status})`);
|
|
5225
5259
|
this.name = "AssessError";
|
|
@@ -5227,6 +5261,7 @@ var AssessError = class extends Error {
|
|
|
5227
5261
|
this.status = opts.status;
|
|
5228
5262
|
this.details = opts.details;
|
|
5229
5263
|
this.rejection_reasons = opts.rejection_reasons;
|
|
5264
|
+
this.billing = opts.billing;
|
|
5230
5265
|
}
|
|
5231
5266
|
};
|
|
5232
5267
|
var DEFAULT_TIMEOUT = 1e4;
|
|
@@ -5322,7 +5357,12 @@ async function postOnce(fetchImpl, url, headers, payload, timeoutMs) {
|
|
|
5322
5357
|
const type = isRecord(parsed) && typeof parsed.error === "string" && parsed.error || `http_${res.status}`;
|
|
5323
5358
|
const details = isRecord(parsed) ? parsed.details : void 0;
|
|
5324
5359
|
const rejection_reasons = isRecord(parsed) && Array.isArray(parsed.rejection_reasons) ? parsed.rejection_reasons : void 0;
|
|
5325
|
-
|
|
5360
|
+
const billing = res.status === 402 && isRecord(parsed) ? {
|
|
5361
|
+
reason: typeof parsed.reason === "string" ? parsed.reason : void 0,
|
|
5362
|
+
detail: typeof parsed.detail === "string" ? parsed.detail : void 0,
|
|
5363
|
+
billingUrl: typeof parsed.billing_url === "string" ? parsed.billing_url : void 0
|
|
5364
|
+
} : void 0;
|
|
5365
|
+
throw new AssessError({ type, status: res.status, details, rejection_reasons, billing });
|
|
5326
5366
|
}
|
|
5327
5367
|
if (!isRecord(parsed)) {
|
|
5328
5368
|
throw new AssessError({ type: "invalid_response", status: res.status });
|
|
@@ -5404,6 +5444,7 @@ function onPluginLoad() {
|
|
|
5404
5444
|
const state = ensureState();
|
|
5405
5445
|
if (state.firstRun) recordInstall();
|
|
5406
5446
|
recordAgentActive();
|
|
5447
|
+
void flush();
|
|
5407
5448
|
void autoProvision();
|
|
5408
5449
|
}
|
|
5409
5450
|
var core;
|
package/openclaw.plugin.json
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "fidacy",
|
|
3
|
-
"name": "Fidacy
|
|
3
|
+
"name": "Fidacy AI Agent Firewall",
|
|
4
4
|
"description": "A signed, independently-verifiable verdict on every money-moving agent action. Blocks wrong/lookalike payee, over-cap, and duplicate-invoice fraud before money moves. Non-custodial, local-first, deny-by-default.",
|
|
5
5
|
"icon": "https://fidacy.com/logo.png",
|
|
6
|
-
"version": "0.2.
|
|
6
|
+
"version": "0.2.11",
|
|
7
7
|
"contracts": {
|
|
8
8
|
"tools": [
|
|
9
9
|
"request_payment",
|
|
10
10
|
"verify_mandate",
|
|
11
11
|
"get_audit_proof",
|
|
12
|
+
"spend_summary",
|
|
13
|
+
"list_decisions",
|
|
14
|
+
"sentinel_alerts",
|
|
15
|
+
"explain_decision",
|
|
12
16
|
"assess_action",
|
|
13
17
|
"anchor_artifact",
|
|
14
18
|
"check_artifact",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fidacy/openclaw-plugin",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.11",
|
|
4
4
|
"description": "Fidacy payment firewall as a native OpenClaw plugin: signed, verifiable verdicts on every money-moving agent action, in-process (no MCP subprocess).",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Fidacy (ZeepCode Group Technology LLC) <hello@fidacy.com> (https://fidacy.com)",
|
|
@@ -56,8 +56,8 @@
|
|
|
56
56
|
"openclaw": "2026.6.11",
|
|
57
57
|
"typebox": "1.1.39",
|
|
58
58
|
"typescript": "^5.6.3",
|
|
59
|
-
"@fidacy/
|
|
60
|
-
"@fidacy/
|
|
59
|
+
"@fidacy/firewall": "0.1.1",
|
|
60
|
+
"@fidacy/mcp": "0.3.3"
|
|
61
61
|
},
|
|
62
62
|
"scripts": {
|
|
63
63
|
"build": "node scripts/bundle.mjs",
|