ai-trust 0.2.3 → 0.2.4
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/dist/commands/audit.d.ts.map +1 -1
- package/dist/commands/audit.js +13 -38
- package/dist/commands/audit.js.map +1 -1
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +12 -35
- package/dist/commands/check.js.map +1 -1
- package/dist/telemetry/contribute.d.ts +60 -6
- package/dist/telemetry/contribute.d.ts.map +1 -1
- package/dist/telemetry/contribute.js +197 -44
- package/dist/telemetry/contribute.js.map +1 -1
- package/dist/telemetry/index.d.ts +2 -2
- package/dist/telemetry/index.d.ts.map +1 -1
- package/dist/telemetry/index.js +2 -2
- package/dist/telemetry/index.js.map +1 -1
- package/dist/telemetry/opt-in.d.ts +20 -13
- package/dist/telemetry/opt-in.d.ts.map +1 -1
- package/dist/telemetry/opt-in.js +87 -112
- package/dist/telemetry/opt-in.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/commands/audit.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/commands/audit.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwBzC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuH3D"}
|
package/dist/commands/audit.js
CHANGED
|
@@ -8,7 +8,7 @@ import { parseDependencyFile } from "../utils/parser.js";
|
|
|
8
8
|
import { formatBatchResults, formatJson, } from "../output/formatter.js";
|
|
9
9
|
import { isHmaAvailable, scanPackage } from "../scanner/index.js";
|
|
10
10
|
import { confirm } from "../utils/prompt.js";
|
|
11
|
-
import { isContributeEnabled,
|
|
11
|
+
import { isContributeEnabled, queueScanResult, flushQueue, recordScanAndMaybeShowTip, } from "../telemetry/index.js";
|
|
12
12
|
export function registerAuditCommand(program) {
|
|
13
13
|
program
|
|
14
14
|
.command("audit <file>")
|
|
@@ -130,49 +130,24 @@ async function scanMissingPackages(notFound, allResults, opts, registryUrl) {
|
|
|
130
130
|
}
|
|
131
131
|
/**
|
|
132
132
|
* Handle community contribution after audit scanning.
|
|
133
|
-
* Follows the same opt-in flow as check:
|
|
133
|
+
* Follows the same opt-in flow as check: queue + flush.
|
|
134
134
|
*/
|
|
135
135
|
async function handleAuditContribution(scannedResults, opts, registryUrl) {
|
|
136
|
-
//
|
|
137
|
-
|
|
138
|
-
|
|
136
|
+
// Show tip after 3rd scan (non-blocking, replaces old interactive prompt)
|
|
137
|
+
const tip = recordScanAndMaybeShowTip();
|
|
138
|
+
if (tip) {
|
|
139
|
+
process.stderr.write(tip + "\n");
|
|
139
140
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
await submitAnonymizedTelemetry(name, scanResult, registryUrl);
|
|
143
|
-
}
|
|
141
|
+
const shouldContribute = opts.contribute || isContributeEnabled() === true;
|
|
142
|
+
if (!shouldContribute)
|
|
144
143
|
return;
|
|
145
|
-
|
|
146
|
-
const configEnabled = isContributeEnabled();
|
|
147
|
-
if (configEnabled === true) {
|
|
148
|
-
// Already opted in: auto-contribute anonymized telemetry
|
|
144
|
+
try {
|
|
149
145
|
for (const { name, scanResult } of scannedResults) {
|
|
150
|
-
|
|
146
|
+
queueScanResult(name, scanResult.scan.findings);
|
|
151
147
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
// Not yet configured: check if we should prompt
|
|
158
|
-
if (shouldPromptContribute()) {
|
|
159
|
-
const enabled = await showContributePrompt();
|
|
160
|
-
if (enabled) {
|
|
161
|
-
for (const { name, scanResult } of scannedResults) {
|
|
162
|
-
await submitAnonymizedTelemetry(name, scanResult, registryUrl);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* Submit anonymized telemetry to the registry (opt-in contribution).
|
|
169
|
-
*/
|
|
170
|
-
async function submitAnonymizedTelemetry(name, scanResult, registryUrl) {
|
|
171
|
-
try {
|
|
172
|
-
const payload = buildContributionPayload(name, scanResult.scan.findings);
|
|
173
|
-
const result = await submitContribution(payload, registryUrl);
|
|
174
|
-
if (result.success) {
|
|
175
|
-
console.error(chalk.green(` Anonymized scan data shared: ${name}`));
|
|
148
|
+
const ok = await flushQueue(registryUrl);
|
|
149
|
+
if (ok) {
|
|
150
|
+
console.error(chalk.green(` Anonymized scan data shared: ${scannedResults.length} package(s)`));
|
|
176
151
|
}
|
|
177
152
|
}
|
|
178
153
|
catch {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/commands/audit.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EACL,kBAAkB,EAClB,UAAU,GACX,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElE,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EACL,mBAAmB,EACnB,
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/commands/audit.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA2BzC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA2E3D"}
|
package/dist/commands/check.js
CHANGED
|
@@ -10,7 +10,7 @@ import { formatCheckResult, formatScanResult, formatJson, } from "../output/form
|
|
|
10
10
|
import { resolveAndLog } from "../utils/resolve.js";
|
|
11
11
|
import { isHmaAvailable, scanPackage } from "../scanner/index.js";
|
|
12
12
|
import { confirm } from "../utils/prompt.js";
|
|
13
|
-
import { isContributeEnabled,
|
|
13
|
+
import { isContributeEnabled, queueScanResult, flushQueue, recordScanAndMaybeShowTip, } from "../telemetry/index.js";
|
|
14
14
|
export function registerCheckCommand(program) {
|
|
15
15
|
program
|
|
16
16
|
.command("check <name>")
|
|
@@ -123,47 +123,24 @@ async function handleScanFlow(name, client, globalOpts, opts, statusMessage) {
|
|
|
123
123
|
await handleContribute(name, scanResult, globalOpts, opts);
|
|
124
124
|
}
|
|
125
125
|
async function handleContribute(name, scanResult, globalOpts, opts) {
|
|
126
|
-
//
|
|
127
|
-
|
|
126
|
+
// Show tip after 3rd scan (non-blocking, replaces old interactive prompt)
|
|
127
|
+
const tip = recordScanAndMaybeShowTip();
|
|
128
|
+
if (tip) {
|
|
129
|
+
process.stderr.write(tip + "\n");
|
|
130
|
+
}
|
|
128
131
|
// Determine contribution mode:
|
|
129
132
|
// 1. --contribute flag: always contribute anonymized telemetry
|
|
130
133
|
// 2. Config enabled: auto-contribute anonymized telemetry
|
|
131
|
-
// 3. Not configured:
|
|
132
|
-
|
|
133
|
-
if (
|
|
134
|
-
await submitAnonymizedTelemetry(name, scanResult, globalOpts.registryUrl);
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
const configEnabled = isContributeEnabled();
|
|
138
|
-
if (configEnabled === true) {
|
|
139
|
-
// Already opted in: auto-contribute anonymized telemetry
|
|
140
|
-
await submitAnonymizedTelemetry(name, scanResult, globalOpts.registryUrl);
|
|
134
|
+
// 3. Not configured or disabled: skip
|
|
135
|
+
const shouldContribute = opts.contribute || isContributeEnabled() === true;
|
|
136
|
+
if (!shouldContribute)
|
|
141
137
|
return;
|
|
142
|
-
}
|
|
143
|
-
if (configEnabled === false) {
|
|
144
|
-
// Explicitly opted out: skip
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
|
-
// Not yet configured: check if we should prompt
|
|
148
|
-
if (shouldPromptContribute()) {
|
|
149
|
-
const enabled = await showContributePrompt();
|
|
150
|
-
if (enabled) {
|
|
151
|
-
await submitAnonymizedTelemetry(name, scanResult, globalOpts.registryUrl);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
/**
|
|
156
|
-
* Submit anonymized telemetry to the registry (opt-in contribution).
|
|
157
|
-
* Only sends checkId, pass/fail, and severity. No file paths, descriptions, or code.
|
|
158
|
-
*/
|
|
159
|
-
async function submitAnonymizedTelemetry(name, scanResult, registryUrl) {
|
|
160
138
|
try {
|
|
161
|
-
|
|
162
|
-
const
|
|
163
|
-
if (
|
|
139
|
+
queueScanResult(name, scanResult.scan.findings);
|
|
140
|
+
const ok = await flushQueue(globalOpts.registryUrl);
|
|
141
|
+
if (ok) {
|
|
164
142
|
console.error(chalk.green("Anonymized scan data shared with the community."));
|
|
165
143
|
}
|
|
166
|
-
// Silent on failure -- non-blocking
|
|
167
144
|
}
|
|
168
145
|
catch {
|
|
169
146
|
// Non-fatal: telemetry submission should never crash the scan
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,GACX,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElE,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EACL,mBAAmB,EACnB,
|
|
1
|
+
{"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Community Contribution Module
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Queue-based contribution of anonymized ai-trust scan summaries to the
|
|
5
|
+
* OpenA2A Registry. Compatible with @opena2a/contribute queue format:
|
|
6
|
+
* events queued by ai-trust are flushed by opena2a-cli, HMA, and vice versa.
|
|
7
|
+
*
|
|
8
|
+
* Queue file: ~/.opena2a/contribute-queue.json
|
|
9
|
+
* Endpoint: POST api.oa2a.org/api/v1/contribute
|
|
10
|
+
*
|
|
11
|
+
* PRIVACY: Only summary statistics are sent (totalChecks, passed,
|
|
12
|
+
* severity counts, score, verdict). No file paths, no source code,
|
|
13
|
+
* no raw finding descriptions, no PII.
|
|
6
14
|
*/
|
|
7
15
|
import type { HmaFinding } from "../scanner/hma.js";
|
|
8
16
|
/** Anonymized finding sent to the registry. Only check ID, result, and severity. */
|
|
@@ -11,7 +19,7 @@ export interface ContributionFinding {
|
|
|
11
19
|
result: "pass" | "fail";
|
|
12
20
|
severity: string;
|
|
13
21
|
}
|
|
14
|
-
/**
|
|
22
|
+
/** Legacy payload type. Callers should migrate to queueScanResult(). */
|
|
15
23
|
export interface ContributionPayload {
|
|
16
24
|
contributorToken: string;
|
|
17
25
|
packageName: string;
|
|
@@ -28,6 +36,35 @@ export interface ContributionResult {
|
|
|
28
36
|
scanId?: string;
|
|
29
37
|
error?: string;
|
|
30
38
|
}
|
|
39
|
+
/** Matches ContributionEvent from @opena2a/contribute/types. */
|
|
40
|
+
export interface ContributionEvent {
|
|
41
|
+
type: "scan_result" | "detection" | "behavior" | "interaction" | "adoption";
|
|
42
|
+
tool: string;
|
|
43
|
+
toolVersion: string;
|
|
44
|
+
timestamp: string;
|
|
45
|
+
package?: {
|
|
46
|
+
name: string;
|
|
47
|
+
version?: string;
|
|
48
|
+
ecosystem?: string;
|
|
49
|
+
};
|
|
50
|
+
scanSummary?: {
|
|
51
|
+
totalChecks: number;
|
|
52
|
+
passed: number;
|
|
53
|
+
critical: number;
|
|
54
|
+
high: number;
|
|
55
|
+
medium: number;
|
|
56
|
+
low: number;
|
|
57
|
+
score: number;
|
|
58
|
+
verdict: string;
|
|
59
|
+
durationMs: number;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/** Matches ContributionBatch from @opena2a/contribute/types. */
|
|
63
|
+
export interface ContributionBatch {
|
|
64
|
+
contributorToken: string;
|
|
65
|
+
events: ContributionEvent[];
|
|
66
|
+
submittedAt: string;
|
|
67
|
+
}
|
|
31
68
|
/**
|
|
32
69
|
* Generate a stable per-device contributor token.
|
|
33
70
|
*
|
|
@@ -36,19 +73,36 @@ export interface ContributionResult {
|
|
|
36
73
|
* Shared with hackmyagent so the same device gets the same token.
|
|
37
74
|
*/
|
|
38
75
|
export declare function generateContributorToken(): string;
|
|
76
|
+
/**
|
|
77
|
+
* Queue a scan result as a ContributionEvent.
|
|
78
|
+
*
|
|
79
|
+
* Converts the detailed finding list into an anonymized summary:
|
|
80
|
+
* only counts and severity distribution, no file paths or descriptions.
|
|
81
|
+
*/
|
|
82
|
+
export declare function queueScanResult(packageName: string, findings: HmaFinding[], durationMs?: number): void;
|
|
83
|
+
/**
|
|
84
|
+
* Flush queued events to the OpenA2A Registry.
|
|
85
|
+
* Returns true if submission succeeded (or queue was empty).
|
|
86
|
+
*/
|
|
87
|
+
export declare function flushQueue(registryUrl?: string, verbose?: boolean): Promise<boolean>;
|
|
39
88
|
/**
|
|
40
89
|
* Build an anonymized contribution payload from scan findings.
|
|
41
90
|
*
|
|
91
|
+
* @deprecated Use queueScanResult() + flushQueue() instead. Kept for
|
|
92
|
+
* backward compatibility. The per-finding payload format is superseded
|
|
93
|
+
* by the summary-based ContributionEvent format.
|
|
94
|
+
*
|
|
42
95
|
* PRIVACY: This function intentionally strips all sensitive fields.
|
|
43
96
|
* The output contains ONLY: checkId, pass/fail result, and severity.
|
|
44
97
|
* No file paths, line numbers, descriptions, fix text, or code content.
|
|
45
98
|
*/
|
|
46
99
|
export declare function buildContributionPayload(packageName: string, findings: HmaFinding[]): ContributionPayload;
|
|
47
100
|
/**
|
|
48
|
-
* Submit
|
|
101
|
+
* Submit a contribution payload to the registry.
|
|
49
102
|
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
103
|
+
* @deprecated Use queueScanResult() + flushQueue() instead. This legacy
|
|
104
|
+
* function now queues the event internally and flushes, rather than
|
|
105
|
+
* posting per-finding payloads directly.
|
|
52
106
|
*/
|
|
53
107
|
export declare function submitContribution(payload: ContributionPayload, registryUrl?: string): Promise<ContributionResult>;
|
|
54
108
|
//# sourceMappingURL=contribute.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contribute.d.ts","sourceRoot":"","sources":["../../src/telemetry/contribute.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"contribute.d.ts","sourceRoot":"","sources":["../../src/telemetry/contribute.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAOH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAkCpD,oFAAoF;AACpF,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wEAAwE;AACxE,MAAM,WAAW,mBAAmB;IAClC,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAC;IACrC,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;CACvC;AAED,2CAA2C;AAC3C,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAMD,gEAAgE;AAChE,MAAM,WAAW,iBAAiB;IAChC,IAAI,EACA,aAAa,GACb,WAAW,GACX,UAAU,GACV,aAAa,GACb,UAAU,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,WAAW,CAAC,EAAE;QACZ,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAED,gEAAgE;AAChE,MAAM,WAAW,iBAAiB;IAChC,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;CACrB;AAWD;;;;;;GAMG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CAejD;AAsFD;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,UAAU,EAAE,EACtB,UAAU,SAAI,GACb,IAAI,CA4BN;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAC9B,WAAW,CAAC,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,OAAO,GAChB,OAAO,CAAC,OAAO,CAAC,CAqClB;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,UAAU,EAAE,GACrB,mBAAmB,CAiBrB;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,mBAAmB,EAC5B,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,kBAAkB,CAAC,CA0C7B"}
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Community Contribution Module
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Queue-based contribution of anonymized ai-trust scan summaries to the
|
|
5
|
+
* OpenA2A Registry. Compatible with @opena2a/contribute queue format:
|
|
6
|
+
* events queued by ai-trust are flushed by opena2a-cli, HMA, and vice versa.
|
|
7
|
+
*
|
|
8
|
+
* Queue file: ~/.opena2a/contribute-queue.json
|
|
9
|
+
* Endpoint: POST api.oa2a.org/api/v1/contribute
|
|
10
|
+
*
|
|
11
|
+
* PRIVACY: Only summary statistics are sent (totalChecks, passed,
|
|
12
|
+
* severity counts, score, verdict). No file paths, no source code,
|
|
13
|
+
* no raw finding descriptions, no PII.
|
|
6
14
|
*/
|
|
7
15
|
import { createHash, randomBytes } from "crypto";
|
|
8
16
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
@@ -12,6 +20,13 @@ import { createRequire } from "node:module";
|
|
|
12
20
|
const require = createRequire(import.meta.url);
|
|
13
21
|
const pkg = require("../../package.json");
|
|
14
22
|
const VERSION = pkg.version;
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
// Paths and constants
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
const REGISTRY_URL = "https://api.oa2a.org";
|
|
27
|
+
const FLUSH_THRESHOLD = 10;
|
|
28
|
+
const MAX_QUEUE_SIZE = 100;
|
|
29
|
+
const TIMEOUT_MS = 10_000;
|
|
15
30
|
/**
|
|
16
31
|
* Resolve the path to the OpenA2A home directory.
|
|
17
32
|
* Respects the OPENA2A_HOME env var, defaults to ~/.opena2a.
|
|
@@ -19,6 +34,14 @@ const VERSION = pkg.version;
|
|
|
19
34
|
function getOpena2aHome() {
|
|
20
35
|
return (process.env.OPENA2A_HOME || join(require("os").homedir(), ".opena2a"));
|
|
21
36
|
}
|
|
37
|
+
function ensureDir() {
|
|
38
|
+
const dir = getOpena2aHome();
|
|
39
|
+
if (!existsSync(dir))
|
|
40
|
+
mkdirSync(dir, { recursive: true });
|
|
41
|
+
}
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
// Contributor token (stable per-device, SHA256-hashed)
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
22
45
|
/**
|
|
23
46
|
* Generate a stable per-device contributor token.
|
|
24
47
|
*
|
|
@@ -41,9 +64,9 @@ export function generateContributorToken() {
|
|
|
41
64
|
const input = `${hostname()}|${userInfo().username}|${salt}`;
|
|
42
65
|
return createHash("sha256").update(input).digest("hex");
|
|
43
66
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
// OS type resolution
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
47
70
|
function resolveOsType() {
|
|
48
71
|
const t = osType();
|
|
49
72
|
if (t === "Darwin")
|
|
@@ -52,9 +75,145 @@ function resolveOsType() {
|
|
|
52
75
|
return "windows";
|
|
53
76
|
return "linux";
|
|
54
77
|
}
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
// Queue operations (compatible with @opena2a/contribute queue format)
|
|
80
|
+
// ---------------------------------------------------------------------------
|
|
81
|
+
function queuePath() {
|
|
82
|
+
return join(getOpena2aHome(), "contribute-queue.json");
|
|
83
|
+
}
|
|
84
|
+
function loadQueue() {
|
|
85
|
+
const path = queuePath();
|
|
86
|
+
if (!existsSync(path))
|
|
87
|
+
return { events: [] };
|
|
88
|
+
try {
|
|
89
|
+
return JSON.parse(readFileSync(path, "utf-8"));
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return { events: [] };
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function saveQueue(queue) {
|
|
96
|
+
ensureDir();
|
|
97
|
+
writeFileSync(queuePath(), JSON.stringify(queue), { mode: 0o600 });
|
|
98
|
+
}
|
|
99
|
+
function queueEvent(event) {
|
|
100
|
+
const queue = loadQueue();
|
|
101
|
+
queue.events.push(event);
|
|
102
|
+
if (queue.events.length > MAX_QUEUE_SIZE) {
|
|
103
|
+
queue.events = queue.events.slice(-MAX_QUEUE_SIZE);
|
|
104
|
+
}
|
|
105
|
+
saveQueue(queue);
|
|
106
|
+
}
|
|
107
|
+
function shouldFlush() {
|
|
108
|
+
return loadQueue().events.length >= FLUSH_THRESHOLD;
|
|
109
|
+
}
|
|
110
|
+
function buildBatch() {
|
|
111
|
+
const events = loadQueue().events;
|
|
112
|
+
if (events.length === 0)
|
|
113
|
+
return null;
|
|
114
|
+
return {
|
|
115
|
+
contributorToken: generateContributorToken(),
|
|
116
|
+
events,
|
|
117
|
+
submittedAt: new Date().toISOString(),
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
function clearQueue() {
|
|
121
|
+
saveQueue({ events: [] });
|
|
122
|
+
}
|
|
123
|
+
// ---------------------------------------------------------------------------
|
|
124
|
+
// Verdict computation
|
|
125
|
+
// ---------------------------------------------------------------------------
|
|
126
|
+
function computeVerdict(findings) {
|
|
127
|
+
const critical = findings.filter((f) => !f.passed && f.severity === "critical").length;
|
|
128
|
+
const high = findings.filter((f) => !f.passed && f.severity === "high").length;
|
|
129
|
+
if (critical > 0)
|
|
130
|
+
return "fail";
|
|
131
|
+
if (high > 0)
|
|
132
|
+
return "warn";
|
|
133
|
+
return "pass";
|
|
134
|
+
}
|
|
135
|
+
// ---------------------------------------------------------------------------
|
|
136
|
+
// Build contribution event from scan findings (summary, not per-finding)
|
|
137
|
+
// ---------------------------------------------------------------------------
|
|
138
|
+
/**
|
|
139
|
+
* Queue a scan result as a ContributionEvent.
|
|
140
|
+
*
|
|
141
|
+
* Converts the detailed finding list into an anonymized summary:
|
|
142
|
+
* only counts and severity distribution, no file paths or descriptions.
|
|
143
|
+
*/
|
|
144
|
+
export function queueScanResult(packageName, findings, durationMs = 0) {
|
|
145
|
+
const total = findings.length;
|
|
146
|
+
const passed = findings.filter((f) => f.passed).length;
|
|
147
|
+
const failed = findings.filter((f) => !f.passed);
|
|
148
|
+
const event = {
|
|
149
|
+
type: "scan_result",
|
|
150
|
+
tool: "ai-trust",
|
|
151
|
+
toolVersion: VERSION,
|
|
152
|
+
timestamp: new Date().toISOString(),
|
|
153
|
+
package: {
|
|
154
|
+
name: packageName,
|
|
155
|
+
ecosystem: "npm",
|
|
156
|
+
},
|
|
157
|
+
scanSummary: {
|
|
158
|
+
totalChecks: total,
|
|
159
|
+
passed,
|
|
160
|
+
critical: failed.filter((f) => f.severity === "critical").length,
|
|
161
|
+
high: failed.filter((f) => f.severity === "high").length,
|
|
162
|
+
medium: failed.filter((f) => f.severity === "medium").length,
|
|
163
|
+
low: failed.filter((f) => f.severity === "low").length,
|
|
164
|
+
score: total > 0 ? Math.round((passed / total) * 100) : 0,
|
|
165
|
+
verdict: computeVerdict(findings),
|
|
166
|
+
durationMs,
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
queueEvent(event);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Flush queued events to the OpenA2A Registry.
|
|
173
|
+
* Returns true if submission succeeded (or queue was empty).
|
|
174
|
+
*/
|
|
175
|
+
export async function flushQueue(registryUrl, verbose) {
|
|
176
|
+
const batch = buildBatch();
|
|
177
|
+
if (!batch)
|
|
178
|
+
return true;
|
|
179
|
+
const url = `${(registryUrl || REGISTRY_URL).replace(/\/+$/, "")}/api/v1/contribute`;
|
|
180
|
+
try {
|
|
181
|
+
const controller = new AbortController();
|
|
182
|
+
const timer = setTimeout(() => controller.abort(), TIMEOUT_MS);
|
|
183
|
+
const response = await fetch(url, {
|
|
184
|
+
method: "POST",
|
|
185
|
+
headers: {
|
|
186
|
+
"Content-Type": "application/json",
|
|
187
|
+
"User-Agent": `ai-trust/${VERSION}`,
|
|
188
|
+
},
|
|
189
|
+
body: JSON.stringify(batch),
|
|
190
|
+
signal: controller.signal,
|
|
191
|
+
});
|
|
192
|
+
clearTimeout(timer);
|
|
193
|
+
if (response.ok) {
|
|
194
|
+
clearQueue();
|
|
195
|
+
if (verbose) {
|
|
196
|
+
process.stderr.write(` Shared: anonymized results for ${batch.events.length} scan(s) (community trust)\n`);
|
|
197
|
+
}
|
|
198
|
+
return true;
|
|
199
|
+
}
|
|
200
|
+
return false;
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
// Offline or unreachable -- events stay in queue for next time
|
|
204
|
+
return false;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
// ---------------------------------------------------------------------------
|
|
208
|
+
// Legacy API (kept for backward compatibility with existing callers/tests)
|
|
209
|
+
// ---------------------------------------------------------------------------
|
|
55
210
|
/**
|
|
56
211
|
* Build an anonymized contribution payload from scan findings.
|
|
57
212
|
*
|
|
213
|
+
* @deprecated Use queueScanResult() + flushQueue() instead. Kept for
|
|
214
|
+
* backward compatibility. The per-finding payload format is superseded
|
|
215
|
+
* by the summary-based ContributionEvent format.
|
|
216
|
+
*
|
|
58
217
|
* PRIVACY: This function intentionally strips all sensitive fields.
|
|
59
218
|
* The output contains ONLY: checkId, pass/fail result, and severity.
|
|
60
219
|
* No file paths, line numbers, descriptions, fix text, or code content.
|
|
@@ -77,47 +236,41 @@ export function buildContributionPayload(packageName, findings) {
|
|
|
77
236
|
};
|
|
78
237
|
}
|
|
79
238
|
/**
|
|
80
|
-
* Submit
|
|
239
|
+
* Submit a contribution payload to the registry.
|
|
81
240
|
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
241
|
+
* @deprecated Use queueScanResult() + flushQueue() instead. This legacy
|
|
242
|
+
* function now queues the event internally and flushes, rather than
|
|
243
|
+
* posting per-finding payloads directly.
|
|
84
244
|
*/
|
|
85
245
|
export async function submitContribution(payload, registryUrl) {
|
|
86
|
-
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
const message = err instanceof Error ? err.message : "Unknown error";
|
|
116
|
-
// AbortError means timeout
|
|
117
|
-
if (message.includes("abort") || message.includes("Abort")) {
|
|
118
|
-
return { success: false, error: "Request timed out (10s)" };
|
|
119
|
-
}
|
|
120
|
-
return { success: false, error: message };
|
|
121
|
-
}
|
|
246
|
+
// Convert legacy payload into a queue event and flush
|
|
247
|
+
const event = {
|
|
248
|
+
type: "scan_result",
|
|
249
|
+
tool: "ai-trust",
|
|
250
|
+
toolVersion: payload.aiTrustVersion,
|
|
251
|
+
timestamp: payload.scanTimestamp,
|
|
252
|
+
package: {
|
|
253
|
+
name: payload.packageName,
|
|
254
|
+
ecosystem: payload.ecosystem,
|
|
255
|
+
},
|
|
256
|
+
scanSummary: {
|
|
257
|
+
totalChecks: payload.findings.length,
|
|
258
|
+
passed: payload.findings.filter((f) => f.result === "pass").length,
|
|
259
|
+
critical: payload.findings.filter((f) => f.result === "fail" && f.severity === "critical").length,
|
|
260
|
+
high: payload.findings.filter((f) => f.result === "fail" && f.severity === "high").length,
|
|
261
|
+
medium: payload.findings.filter((f) => f.result === "fail" && f.severity === "medium").length,
|
|
262
|
+
low: payload.findings.filter((f) => f.result === "fail" && f.severity === "low").length,
|
|
263
|
+
score: payload.findings.length > 0
|
|
264
|
+
? Math.round((payload.findings.filter((f) => f.result === "pass").length /
|
|
265
|
+
payload.findings.length) *
|
|
266
|
+
100)
|
|
267
|
+
: 0,
|
|
268
|
+
verdict: "pass",
|
|
269
|
+
durationMs: 0,
|
|
270
|
+
},
|
|
271
|
+
};
|
|
272
|
+
queueEvent(event);
|
|
273
|
+
const ok = await flushQueue(registryUrl);
|
|
274
|
+
return { success: ok };
|
|
122
275
|
}
|
|
123
276
|
//# sourceMappingURL=contribute.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contribute.js","sourceRoot":"","sources":["../../src/telemetry/contribute.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"contribute.js","sourceRoot":"","sources":["../../src/telemetry/contribute.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Telemetry module -- community contribution of anonymized scan findings.
|
|
3
3
|
*/
|
|
4
|
-
export { generateContributorToken, buildContributionPayload, submitContribution, type ContributionFinding, type ContributionPayload, type ContributionResult, } from "./contribute.js";
|
|
5
|
-
export { isContributeEnabled, shouldPromptContribute, incrementScanCount, saveContributeChoice, showContributePrompt, } from "./opt-in.js";
|
|
4
|
+
export { generateContributorToken, buildContributionPayload, submitContribution, queueScanResult, flushQueue, type ContributionFinding, type ContributionPayload, type ContributionResult, type ContributionEvent, type ContributionBatch, } from "./contribute.js";
|
|
5
|
+
export { isContributeEnabled, shouldPromptContribute, incrementScanCount, saveContributeChoice, showContributePrompt, recordScanAndMaybeShowTip, } from "./opt-in.js";
|
|
6
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/telemetry/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/telemetry/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,eAAe,EACf,UAAU,EACV,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,GACvB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,EACpB,yBAAyB,GAC1B,MAAM,aAAa,CAAC"}
|
package/dist/telemetry/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Telemetry module -- community contribution of anonymized scan findings.
|
|
3
3
|
*/
|
|
4
|
-
export { generateContributorToken, buildContributionPayload, submitContribution, } from "./contribute.js";
|
|
5
|
-
export { isContributeEnabled, shouldPromptContribute, incrementScanCount, saveContributeChoice, showContributePrompt, } from "./opt-in.js";
|
|
4
|
+
export { generateContributorToken, buildContributionPayload, submitContribution, queueScanResult, flushQueue, } from "./contribute.js";
|
|
5
|
+
export { isContributeEnabled, shouldPromptContribute, incrementScanCount, saveContributeChoice, showContributePrompt, recordScanAndMaybeShowTip, } from "./opt-in.js";
|
|
6
6
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/telemetry/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/telemetry/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,eAAe,EACf,UAAU,GAMX,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,EACpB,yBAAyB,GAC1B,MAAM,aAAa,CAAC"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Contribution
|
|
2
|
+
* Contribution Consent and Scan Counting
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* with the OpenA2A Registry.
|
|
4
|
+
* Manages the user's consent to share anonymized scan findings
|
|
5
|
+
* with the OpenA2A Registry. Uses a delayed consent tip shown
|
|
6
|
+
* after the 3rd scan (non-interactive, no blocking prompts).
|
|
6
7
|
*
|
|
7
8
|
* Config/counting is delegated to @opena2a/shared (the canonical
|
|
8
9
|
* source for ~/.opena2a/config.json). If @opena2a/shared is not
|
|
@@ -14,33 +15,39 @@
|
|
|
14
15
|
* Returns:
|
|
15
16
|
* true - user explicitly opted in
|
|
16
17
|
* false - user explicitly opted out (or default in shared backend)
|
|
17
|
-
* undefined - not yet configured
|
|
18
|
-
* defaults to false, so callers should rely on
|
|
19
|
-
* shouldPromptContribute() for prompt logic)
|
|
18
|
+
* undefined - not yet configured
|
|
20
19
|
*/
|
|
21
20
|
export declare function isContributeEnabled(): boolean | undefined;
|
|
22
21
|
/**
|
|
23
|
-
* Check whether we should show the contribution
|
|
22
|
+
* Check whether we should show the contribution tip.
|
|
24
23
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* and cooldown/dismiss logic.
|
|
24
|
+
* Returns true after the 3rd scan if the user hasn't opted in,
|
|
25
|
+
* opted out, or dismissed the tip within the last 30 days.
|
|
28
26
|
*/
|
|
29
27
|
export declare function shouldPromptContribute(): boolean;
|
|
30
28
|
/**
|
|
31
29
|
* Increment the scan count. Called after each scan completes,
|
|
32
30
|
* regardless of contribution setting.
|
|
33
31
|
*/
|
|
34
|
-
export declare function incrementScanCount():
|
|
32
|
+
export declare function incrementScanCount(): number;
|
|
35
33
|
/**
|
|
36
34
|
* Save the user's contribution choice to the config file.
|
|
37
35
|
*/
|
|
38
36
|
export declare function saveContributeChoice(enabled: boolean): void;
|
|
37
|
+
/**
|
|
38
|
+
* Record a scan and return a consent tip string if the threshold is reached.
|
|
39
|
+
*
|
|
40
|
+
* After the 3rd scan, returns a non-interactive tip encouraging the user
|
|
41
|
+
* to enable contribution. Returns null if tip should not be shown.
|
|
42
|
+
* This replaces the previous interactive Y/N prompt.
|
|
43
|
+
*/
|
|
44
|
+
export declare function recordScanAndMaybeShowTip(): string | null;
|
|
39
45
|
/**
|
|
40
46
|
* Display the contribution opt-in prompt and return the user's choice.
|
|
41
47
|
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
48
|
+
* @deprecated Use recordScanAndMaybeShowTip() instead. This is kept
|
|
49
|
+
* for backward compatibility but now shows a non-interactive tip
|
|
50
|
+
* rather than blocking for input.
|
|
44
51
|
*/
|
|
45
52
|
export declare function showContributePrompt(): Promise<boolean>;
|
|
46
53
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opt-in.d.ts","sourceRoot":"","sources":["../../src/telemetry/opt-in.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"opt-in.d.ts","sourceRoot":"","sources":["../../src/telemetry/opt-in.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAoKH;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,GAAG,SAAS,CAEzD;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAEhD;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAK3D;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,GAAG,IAAI,CAezD;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,OAAO,CAAC,CAM7D;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,UAAU,UAAQ,GAAG,IAAI,CAKtD"}
|
package/dist/telemetry/opt-in.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Contribution
|
|
2
|
+
* Contribution Consent and Scan Counting
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* with the OpenA2A Registry.
|
|
4
|
+
* Manages the user's consent to share anonymized scan findings
|
|
5
|
+
* with the OpenA2A Registry. Uses a delayed consent tip shown
|
|
6
|
+
* after the 3rd scan (non-interactive, no blocking prompts).
|
|
6
7
|
*
|
|
7
8
|
* Config/counting is delegated to @opena2a/shared (the canonical
|
|
8
9
|
* source for ~/.opena2a/config.json). If @opena2a/shared is not
|
|
@@ -15,30 +16,31 @@ let _backend;
|
|
|
15
16
|
function resolveBackend() {
|
|
16
17
|
if (_backend)
|
|
17
18
|
return _backend;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
typeof shared.
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
19
|
+
// When OPENA2A_HOME is set, always use local backend so the custom
|
|
20
|
+
// home directory is respected (important for testing and isolation).
|
|
21
|
+
if (!process.env.OPENA2A_HOME) {
|
|
22
|
+
try {
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
24
|
+
const shared = require("@opena2a/shared");
|
|
25
|
+
if (typeof shared.isContributeEnabled === "function" &&
|
|
26
|
+
typeof shared.setContributeEnabled === "function" &&
|
|
27
|
+
typeof shared.incrementScanCount === "function" &&
|
|
28
|
+
typeof shared.shouldPromptContribute === "function" &&
|
|
29
|
+
typeof shared.dismissContributePrompt === "function") {
|
|
30
|
+
_backend = {
|
|
31
|
+
isContributeEnabled: shared.isContributeEnabled,
|
|
32
|
+
setContributeEnabled: shared.setContributeEnabled,
|
|
33
|
+
incrementScanCount: shared.incrementScanCount,
|
|
34
|
+
getScanCount: shared.getScanCount || (() => 0),
|
|
35
|
+
shouldPromptContribute: shared.shouldPromptContribute,
|
|
36
|
+
dismissContributePrompt: shared.dismissContributePrompt,
|
|
37
|
+
};
|
|
38
|
+
return _backend;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// @opena2a/shared not installed -- fall through to local backend
|
|
38
43
|
}
|
|
39
|
-
}
|
|
40
|
-
catch {
|
|
41
|
-
// @opena2a/shared not installed -- fall through to local backend
|
|
42
44
|
}
|
|
43
45
|
_backend = createLocalBackend();
|
|
44
46
|
return _backend;
|
|
@@ -67,58 +69,63 @@ function writeConfig(config) {
|
|
|
67
69
|
mode: 0o600,
|
|
68
70
|
});
|
|
69
71
|
}
|
|
72
|
+
/** Cooldown for the consent tip: 30 days after dismissal. */
|
|
73
|
+
const TIP_COOLDOWN_MS = 30 * 24 * 60 * 60 * 1000;
|
|
70
74
|
function createLocalBackend() {
|
|
71
75
|
return {
|
|
72
76
|
isContributeEnabled() {
|
|
73
77
|
const config = readConfig();
|
|
74
|
-
|
|
75
|
-
return true;
|
|
76
|
-
if (config.contribute?.enabled === false)
|
|
77
|
-
return false;
|
|
78
|
-
return undefined;
|
|
78
|
+
return config.contribute?.enabled === true;
|
|
79
79
|
},
|
|
80
80
|
setContributeEnabled(enabled) {
|
|
81
81
|
const config = readConfig();
|
|
82
82
|
if (!config.contribute)
|
|
83
83
|
config.contribute = {};
|
|
84
84
|
config.contribute.enabled = enabled;
|
|
85
|
-
const scanCount = config.contribute.scanCount ?? 0;
|
|
86
|
-
if (scanCount >= 9)
|
|
87
|
-
config.contribute.promptedAtTen = true;
|
|
88
85
|
writeConfig(config);
|
|
89
86
|
},
|
|
90
87
|
incrementScanCount() {
|
|
91
88
|
const config = readConfig();
|
|
92
|
-
if (!config.
|
|
93
|
-
config.
|
|
94
|
-
config.
|
|
89
|
+
if (!config.telemetry)
|
|
90
|
+
config.telemetry = {};
|
|
91
|
+
config.telemetry.scanCount = (config.telemetry.scanCount ?? 0) + 1;
|
|
95
92
|
writeConfig(config);
|
|
96
|
-
return config.
|
|
93
|
+
return config.telemetry.scanCount;
|
|
94
|
+
},
|
|
95
|
+
getScanCount() {
|
|
96
|
+
const config = readConfig();
|
|
97
|
+
return config.telemetry?.scanCount ?? 0;
|
|
97
98
|
},
|
|
98
99
|
shouldPromptContribute() {
|
|
99
100
|
const config = readConfig();
|
|
101
|
+
// Already decided -- do not prompt
|
|
100
102
|
if (config.contribute?.enabled === true ||
|
|
101
103
|
config.contribute?.enabled === false) {
|
|
102
104
|
return false;
|
|
103
105
|
}
|
|
104
|
-
const
|
|
105
|
-
if (
|
|
106
|
-
return
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
106
|
+
const count = config.telemetry?.scanCount ?? 0;
|
|
107
|
+
if (count < 3)
|
|
108
|
+
return false;
|
|
109
|
+
// Check cooldown
|
|
110
|
+
const dismissed = config.telemetry?.contributePromptDismissedAt;
|
|
111
|
+
if (dismissed) {
|
|
112
|
+
const dismissedMs = new Date(dismissed).getTime();
|
|
113
|
+
if (Date.now() - dismissedMs < TIP_COOLDOWN_MS)
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
return true;
|
|
110
117
|
},
|
|
111
118
|
dismissContributePrompt() {
|
|
112
119
|
const config = readConfig();
|
|
113
|
-
if (!config.
|
|
114
|
-
config.
|
|
115
|
-
config.
|
|
120
|
+
if (!config.telemetry)
|
|
121
|
+
config.telemetry = {};
|
|
122
|
+
config.telemetry.contributePromptDismissedAt = new Date().toISOString();
|
|
116
123
|
writeConfig(config);
|
|
117
124
|
},
|
|
118
125
|
};
|
|
119
126
|
}
|
|
120
127
|
// ---------------------------------------------------------------------------
|
|
121
|
-
// Public API
|
|
128
|
+
// Public API
|
|
122
129
|
// ---------------------------------------------------------------------------
|
|
123
130
|
/**
|
|
124
131
|
* Check whether the contribution setting is enabled.
|
|
@@ -126,23 +133,18 @@ function createLocalBackend() {
|
|
|
126
133
|
* Returns:
|
|
127
134
|
* true - user explicitly opted in
|
|
128
135
|
* false - user explicitly opted out (or default in shared backend)
|
|
129
|
-
* undefined - not yet configured
|
|
130
|
-
* defaults to false, so callers should rely on
|
|
131
|
-
* shouldPromptContribute() for prompt logic)
|
|
136
|
+
* undefined - not yet configured
|
|
132
137
|
*/
|
|
133
138
|
export function isContributeEnabled() {
|
|
134
|
-
return resolveBackend().isContributeEnabled();
|
|
139
|
+
return resolveBackend().isContributeEnabled() || undefined;
|
|
135
140
|
}
|
|
136
141
|
/**
|
|
137
|
-
* Check whether we should show the contribution
|
|
142
|
+
* Check whether we should show the contribution tip.
|
|
138
143
|
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
* and cooldown/dismiss logic.
|
|
144
|
+
* Returns true after the 3rd scan if the user hasn't opted in,
|
|
145
|
+
* opted out, or dismissed the tip within the last 30 days.
|
|
142
146
|
*/
|
|
143
147
|
export function shouldPromptContribute() {
|
|
144
|
-
if (!process.stdin.isTTY || !process.stdout.isTTY)
|
|
145
|
-
return false;
|
|
146
148
|
return resolveBackend().shouldPromptContribute();
|
|
147
149
|
}
|
|
148
150
|
/**
|
|
@@ -150,7 +152,7 @@ export function shouldPromptContribute() {
|
|
|
150
152
|
* regardless of contribution setting.
|
|
151
153
|
*/
|
|
152
154
|
export function incrementScanCount() {
|
|
153
|
-
resolveBackend().incrementScanCount();
|
|
155
|
+
return resolveBackend().incrementScanCount();
|
|
154
156
|
}
|
|
155
157
|
/**
|
|
156
158
|
* Save the user's contribution choice to the config file.
|
|
@@ -162,66 +164,39 @@ export function saveContributeChoice(enabled) {
|
|
|
162
164
|
}
|
|
163
165
|
}
|
|
164
166
|
/**
|
|
165
|
-
*
|
|
167
|
+
* Record a scan and return a consent tip string if the threshold is reached.
|
|
166
168
|
*
|
|
167
|
-
*
|
|
168
|
-
* Returns
|
|
169
|
+
* After the 3rd scan, returns a non-interactive tip encouraging the user
|
|
170
|
+
* to enable contribution. Returns null if tip should not be shown.
|
|
171
|
+
* This replaces the previous interactive Y/N prompt.
|
|
169
172
|
*/
|
|
170
|
-
export
|
|
171
|
-
|
|
173
|
+
export function recordScanAndMaybeShowTip() {
|
|
174
|
+
incrementScanCount();
|
|
175
|
+
if (!shouldPromptContribute())
|
|
176
|
+
return null;
|
|
177
|
+
// Mark as shown so we respect the 30-day cooldown
|
|
178
|
+
resolveBackend().dismissContributePrompt();
|
|
179
|
+
return [
|
|
172
180
|
"",
|
|
173
|
-
"
|
|
181
|
+
" Tip: Your scans help build community trust data for MCP servers and AI agents.",
|
|
182
|
+
" Share anonymized results so other developers can make informed security decisions.",
|
|
183
|
+
" Enable: npx ai-trust check --contribute (or: opena2a config contribute on)",
|
|
174
184
|
"",
|
|
175
|
-
|
|
176
|
-
"No personal data. No source code. Only check pass/fail results.",
|
|
177
|
-
"You can opt out anytime: opena2a config set contribute false",
|
|
178
|
-
"",
|
|
179
|
-
"[Y] Yes, contribute [N] No thanks",
|
|
180
|
-
];
|
|
181
|
-
for (const line of lines) {
|
|
182
|
-
process.stderr.write(line + "\n");
|
|
183
|
-
}
|
|
184
|
-
const answer = await readSingleKey();
|
|
185
|
-
const enabled = answer.toLowerCase() === "y";
|
|
186
|
-
saveContributeChoice(enabled);
|
|
187
|
-
if (enabled) {
|
|
188
|
-
process.stderr.write("\nContribution enabled. Thank you.\n");
|
|
189
|
-
}
|
|
190
|
-
else {
|
|
191
|
-
process.stderr.write("\nContribution disabled. You can enable it later: opena2a config set contribute true\n");
|
|
192
|
-
}
|
|
193
|
-
return enabled;
|
|
185
|
+
].join("\n");
|
|
194
186
|
}
|
|
195
187
|
/**
|
|
196
|
-
*
|
|
197
|
-
*
|
|
188
|
+
* Display the contribution opt-in prompt and return the user's choice.
|
|
189
|
+
*
|
|
190
|
+
* @deprecated Use recordScanAndMaybeShowTip() instead. This is kept
|
|
191
|
+
* for backward compatibility but now shows a non-interactive tip
|
|
192
|
+
* rather than blocking for input.
|
|
198
193
|
*/
|
|
199
|
-
function
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
cleanup();
|
|
206
|
-
resolve("n");
|
|
207
|
-
}, 30_000);
|
|
208
|
-
function cleanup() {
|
|
209
|
-
clearTimeout(timer);
|
|
210
|
-
stdin.removeListener("data", onData);
|
|
211
|
-
if (stdin.isRaw !== wasRaw) {
|
|
212
|
-
stdin.setRawMode(wasRaw ?? false);
|
|
213
|
-
}
|
|
214
|
-
stdin.pause();
|
|
215
|
-
}
|
|
216
|
-
function onData(data) {
|
|
217
|
-
const char = data.toString().trim().toLowerCase();
|
|
218
|
-
cleanup();
|
|
219
|
-
resolve(char || "n");
|
|
220
|
-
}
|
|
221
|
-
stdin.setRawMode(true);
|
|
222
|
-
stdin.resume();
|
|
223
|
-
stdin.once("data", onData);
|
|
224
|
-
});
|
|
194
|
+
export async function showContributePrompt() {
|
|
195
|
+
const tip = recordScanAndMaybeShowTip();
|
|
196
|
+
if (tip) {
|
|
197
|
+
process.stdout.write(tip + "\n");
|
|
198
|
+
}
|
|
199
|
+
return false;
|
|
225
200
|
}
|
|
226
201
|
/**
|
|
227
202
|
* Reset the backend (for testing).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opt-in.js","sourceRoot":"","sources":["../../src/telemetry/opt-in.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"opt-in.js","sourceRoot":"","sources":["../../src/telemetry/opt-in.ts"],"names":[],"mappings":"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"}
|