@panguard-ai/panguard-guard 1.7.3 → 1.8.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/README.md +18 -0
- package/dist/agent/analyze-agent.d.ts.map +1 -1
- package/dist/agent/analyze-agent.js +3 -0
- package/dist/agent/analyze-agent.js.map +1 -1
- package/dist/agent/respond-agent.d.ts.map +1 -1
- package/dist/agent/respond-agent.js +13 -0
- package/dist/agent/respond-agent.js.map +1 -1
- package/dist/audit/attribution.d.ts.map +1 -1
- package/dist/audit/attribution.js.map +1 -1
- package/dist/audit/audit-chain.d.ts.map +1 -1
- package/dist/audit/audit-chain.js +1 -3
- package/dist/audit/audit-chain.js.map +1 -1
- package/dist/audit/hash-chain.d.ts.map +1 -1
- package/dist/audit/hash-chain.js.map +1 -1
- package/dist/cli/index.js +39 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +8 -5
- package/dist/config.js.map +1 -1
- package/dist/dashboard/dashboard.html +38 -28
- package/dist/dashboard/index.d.ts.map +1 -1
- package/dist/dashboard/index.js +29 -11
- package/dist/dashboard/index.js.map +1 -1
- package/dist/event-processor.d.ts.map +1 -1
- package/dist/event-processor.js +63 -9
- package/dist/event-processor.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/integrity.d.ts +44 -0
- package/dist/integrity.d.ts.map +1 -1
- package/dist/integrity.js +94 -4
- package/dist/integrity.js.map +1 -1
- package/dist/license/index.js +2 -2
- package/dist/license/index.js.map +1 -1
- package/dist/llm-cli/adapters.d.ts +60 -0
- package/dist/llm-cli/adapters.d.ts.map +1 -0
- package/dist/llm-cli/adapters.js +115 -0
- package/dist/llm-cli/adapters.js.map +1 -0
- package/dist/llm-cli/detect.d.ts +37 -0
- package/dist/llm-cli/detect.d.ts.map +1 -0
- package/dist/llm-cli/detect.js +81 -0
- package/dist/llm-cli/detect.js.map +1 -0
- package/dist/llm-cli/index.d.ts +12 -0
- package/dist/llm-cli/index.d.ts.map +1 -0
- package/dist/llm-cli/index.js +12 -0
- package/dist/llm-cli/index.js.map +1 -0
- package/dist/llm-cli/subprocess-llm.d.ts +65 -0
- package/dist/llm-cli/subprocess-llm.d.ts.map +1 -0
- package/dist/llm-cli/subprocess-llm.js +249 -0
- package/dist/llm-cli/subprocess-llm.js.map +1 -0
- package/dist/threat-cloud/index.d.ts +10 -0
- package/dist/threat-cloud/index.d.ts.map +1 -1
- package/dist/threat-cloud/index.js +23 -2
- package/dist/threat-cloud/index.js.map +1 -1
- package/dist/threat-cloud/seal.d.ts.map +1 -1
- package/dist/threat-cloud/seal.js +8 -7
- package/dist/threat-cloud/seal.js.map +1 -1
- package/dist/types.d.ts +15 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +9 -9
package/dist/integrity.js
CHANGED
|
@@ -22,7 +22,15 @@
|
|
|
22
22
|
import { createHash, createHmac, timingSafeEqual } from 'node:crypto';
|
|
23
23
|
import { existsSync, readFileSync, writeFileSync, mkdirSync, renameSync } from 'node:fs';
|
|
24
24
|
import { join, dirname } from 'node:path';
|
|
25
|
-
import { hostname, userInfo } from 'node:os';
|
|
25
|
+
import { hostname, userInfo, homedir, platform } from 'node:os';
|
|
26
|
+
/**
|
|
27
|
+
* launchd label for the guard's own reboot-persistence service. MUST match
|
|
28
|
+
* SERVICE_LABEL in @panguard-ai/panguard's persist.ts — the two live in
|
|
29
|
+
* separate packages (panguard depends on panguard-guard, not the reverse), so
|
|
30
|
+
* the constant is duplicated here with this contract. A drift would make the
|
|
31
|
+
* self-removal check watch the wrong path. A test in persist pins the value.
|
|
32
|
+
*/
|
|
33
|
+
export const GUARD_SERVICE_LABEL = 'com.panguard.panguard-guard';
|
|
26
34
|
/** Config fields whose silent change weakens protection — the integrity-watched set. */
|
|
27
35
|
export const SECURITY_FIELDS = [
|
|
28
36
|
'mode',
|
|
@@ -48,7 +56,17 @@ const CRITICAL_FIELDS = new Set([
|
|
|
48
56
|
function deriveMachineKey() {
|
|
49
57
|
return createHash('sha256').update(`${hostname()}\n${userInfo().username}\npanguard-ai`).digest();
|
|
50
58
|
}
|
|
51
|
-
/**
|
|
59
|
+
/**
|
|
60
|
+
* Deterministic JSON with RECURSIVELY sorted keys, so the HMAC is order-stable.
|
|
61
|
+
*
|
|
62
|
+
* CRITICAL: object keys whose value is `undefined` are OMITTED, exactly as
|
|
63
|
+
* JSON.stringify does when the manifest is written to disk. Without this, sealing
|
|
64
|
+
* hashes `{enforcementPolicy: undefined}` as a present key while the persisted
|
|
65
|
+
* file drops it — so verify recomputes a different MAC and reports
|
|
66
|
+
* `manifest-tampered` on a pristine install (any config that leaves a watched
|
|
67
|
+
* security field unset, e.g. the default enforcementPolicy / trustedSkills).
|
|
68
|
+
* Array holes still serialize as null to match JSON.stringify array semantics.
|
|
69
|
+
*/
|
|
52
70
|
function canonical(v) {
|
|
53
71
|
if (v === null || v === undefined)
|
|
54
72
|
return 'null';
|
|
@@ -57,7 +75,9 @@ function canonical(v) {
|
|
|
57
75
|
if (Array.isArray(v))
|
|
58
76
|
return '[' + v.map(canonical).join(',') + ']';
|
|
59
77
|
const o = v;
|
|
60
|
-
const keys = Object.keys(o)
|
|
78
|
+
const keys = Object.keys(o)
|
|
79
|
+
.filter((k) => o[k] !== undefined)
|
|
80
|
+
.sort();
|
|
61
81
|
return '{' + keys.map((k) => JSON.stringify(k) + ':' + canonical(o[k])).join(',') + '}';
|
|
62
82
|
}
|
|
63
83
|
function hmacHex(data) {
|
|
@@ -160,7 +180,12 @@ export function verifyConfigIntegrity(config, dataDir) {
|
|
|
160
180
|
const was = sealed[f];
|
|
161
181
|
const now = config[f];
|
|
162
182
|
if (canonical(was) !== canonical(now)) {
|
|
163
|
-
findings.push({
|
|
183
|
+
findings.push({
|
|
184
|
+
field: f,
|
|
185
|
+
was,
|
|
186
|
+
now,
|
|
187
|
+
severity: CRITICAL_FIELDS.has(f) ? 'critical' : 'warn',
|
|
188
|
+
});
|
|
164
189
|
}
|
|
165
190
|
}
|
|
166
191
|
return { status: 'tampered', findings, checkedAt };
|
|
@@ -205,4 +230,69 @@ export function readSelfStateRefs(dataDir) {
|
|
|
205
230
|
return [];
|
|
206
231
|
return Array.isArray(m.selfState) ? m.selfState : [];
|
|
207
232
|
}
|
|
233
|
+
/**
|
|
234
|
+
* Discover the guard's own currently-present install artifacts as SelfStateRefs.
|
|
235
|
+
*
|
|
236
|
+
* This is the missing wiring that made self-removal detection dead: every seal
|
|
237
|
+
* recorded an EMPTY selfState, so checkSelfState() always iterated nothing and
|
|
238
|
+
* always returned ok — the guard claimed to notice its own removal but never
|
|
239
|
+
* did. We record only artifacts that EXIST right now (so we never emit a false
|
|
240
|
+
* "missing" for something that was never installed on this platform); merging
|
|
241
|
+
* with the previously-recorded refs (see mergeSelfState) is what preserves a
|
|
242
|
+
* later removal as a detection.
|
|
243
|
+
*
|
|
244
|
+
* Highest-value artifact: the reboot-persistence LaunchAgent. Its removal means
|
|
245
|
+
* protection silently never starts again after the next login. macOS-only for
|
|
246
|
+
* now (that is where the guard installs a user LaunchAgent). Hook / proxy-
|
|
247
|
+
* injection artifacts are recorded by the installers that own their paths.
|
|
248
|
+
*/
|
|
249
|
+
export function collectSelfState() {
|
|
250
|
+
const refs = [];
|
|
251
|
+
if (platform() === 'darwin') {
|
|
252
|
+
const plist = join(homedir(), 'Library', 'LaunchAgents', `${GUARD_SERVICE_LABEL}.plist`);
|
|
253
|
+
if (existsSync(plist)) {
|
|
254
|
+
refs.push({
|
|
255
|
+
kind: 'launchagent',
|
|
256
|
+
path: plist,
|
|
257
|
+
marker: GUARD_SERVICE_LABEL,
|
|
258
|
+
label: 'reboot-persistence service',
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return refs;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Union two SelfStateRef lists by path, preferring the previously-recorded ref
|
|
266
|
+
* on conflict. CRITICAL: this never DROPS a recorded ref — a recorded artifact
|
|
267
|
+
* that is now missing must stay in the set so checkSelfState() flags its
|
|
268
|
+
* removal. We only ADD newly-present artifacts. Re-sealing with a bare
|
|
269
|
+
* collectSelfState() (which omits anything currently absent) would erase the
|
|
270
|
+
* very removal we exist to detect; merging is what makes a refresh safe.
|
|
271
|
+
*/
|
|
272
|
+
export function mergeSelfState(recorded, discovered) {
|
|
273
|
+
const byPath = new Map();
|
|
274
|
+
for (const r of discovered) {
|
|
275
|
+
if (r && typeof r.path === 'string')
|
|
276
|
+
byPath.set(r.path, r);
|
|
277
|
+
}
|
|
278
|
+
// Recorded wins on conflict (preserves the original marker/label + presence contract).
|
|
279
|
+
for (const r of recorded) {
|
|
280
|
+
if (r && typeof r.path === 'string')
|
|
281
|
+
byPath.set(r.path, r);
|
|
282
|
+
}
|
|
283
|
+
return [...byPath.values()];
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Drop recorded refs by kind — the deliberate inverse of mergeSelfState, used
|
|
287
|
+
* ONLY when the guard removes its own artifact on purpose (e.g. `pga guard
|
|
288
|
+
* uninstall` removing the LaunchAgent). A LEGITIMATE removal must rebuild trust,
|
|
289
|
+
* not leave a permanent "missing" that makes checkSelfState flag tamper forever.
|
|
290
|
+
* Without this, once you uninstall the reboot service the manifest keeps its ref
|
|
291
|
+
* (merge never drops), so every subsequent start warns and the dashboard shows
|
|
292
|
+
* TAMPERED with no natural recovery. Callers pass the kind(s) they just removed.
|
|
293
|
+
*/
|
|
294
|
+
export function forgetSelfState(recorded, kinds) {
|
|
295
|
+
const drop = new Set(kinds);
|
|
296
|
+
return recorded.filter((r) => r && typeof r.kind === 'string' && !drop.has(r.kind));
|
|
297
|
+
}
|
|
208
298
|
//# sourceMappingURL=integrity.js.map
|
package/dist/integrity.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integrity.js","sourceRoot":"","sources":["../src/integrity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACzF,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"integrity.js","sourceRoot":"","sources":["../src/integrity.ts"],"names":[],"mappings":"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"}
|
package/dist/license/index.js
CHANGED
|
@@ -31,12 +31,12 @@ const COMMUNITY_FEATURES = [
|
|
|
31
31
|
'auto_respond',
|
|
32
32
|
'threat_cloud_upload',
|
|
33
33
|
'dashboard',
|
|
34
|
+
'sarif_export',
|
|
35
|
+
'evidence_pack',
|
|
34
36
|
];
|
|
35
37
|
const PILOT_FEATURES = [
|
|
36
38
|
...COMMUNITY_FEATURES,
|
|
37
39
|
'threat_cloud_live',
|
|
38
|
-
'sarif_export',
|
|
39
|
-
'evidence_pack',
|
|
40
40
|
'ai_analysis',
|
|
41
41
|
'auto_fix',
|
|
42
42
|
'notifications',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/license/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAiC,MAAM,MAAM,CAAC;AAiB5E,MAAM,kBAAkB,GAA0B;IAChD,YAAY;IACZ,kBAAkB;IAClB,aAAa;IACb,eAAe;IACf,cAAc;IACd,qBAAqB;IACrB,WAAW;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/license/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAiC,MAAM,MAAM,CAAC;AAiB5E,MAAM,kBAAkB,GAA0B;IAChD,YAAY;IACZ,kBAAkB;IAClB,aAAa;IACb,eAAe;IACf,cAAc;IACd,qBAAqB;IACrB,WAAW;IACX,cAAc;IACd,eAAe;CAChB,CAAC;AAEF,MAAM,cAAc,GAA0B;IAC5C,GAAG,kBAAkB;IACrB,mBAAmB;IACnB,aAAa;IACb,UAAU;IACV,eAAe;IACf,gBAAgB;IAChB,cAAc;CACf,CAAC;AAEF,MAAM,mBAAmB,GAA0B;IACjD,GAAG,cAAc;IACjB,kBAAkB;IAClB,KAAK;IACL,cAAc;IACd,kBAAkB;IAClB,gBAAgB;IAChB,aAAa;IACb,cAAc;CACf,CAAC;AAEF,MAAM,aAAa,GAA+C;IAChE,SAAS,EAAE,kBAAkB;IAC7B,IAAI,EAAE,kBAAkB;IACxB,KAAK,EAAE,cAAc;IACrB,GAAG,EAAE,cAAc;IACnB,UAAU,EAAE,mBAAmB;CAChC,CAAC;AAEF,MAAM,MAAM,GAAG,aAAa,CAAC;AAC7B,MAAM,QAAQ,GAAG,gBAAgB,CAAC;AAClC,MAAM,SAAS,GAAG,OAAO,CAAC;AAE1B,MAAM,kBAAkB,GAAG,KAAK,CAAC;AACjC,MAAM,YAAY,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AACzC,MAAM,eAAe,GAAG,yBAAyB,CAAC;AAElD,SAAS,SAAS;IAChB,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,oBAAoB,CAAC,CAAC;AAC5D,CAAC;AAED,SAAS,UAAU;IACjB,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,eAAe,CAAC;AAC3E,CAAC;AAED,SAAS,YAAY;IACnB,MAAM,GAAG,GACP,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC;QAC9C,EAAE,CAAC;IACL,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC5D,IAAI,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;YAAE,OAAO,OAAO,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC;QACP,kBAAkB;IACpB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,IAAI,eAAe,GAAmB,IAAI,CAAC;AAE3C,KAAK,UAAU,aAAa;IAC1B,IAAI,eAAe;QAAE,OAAO,eAAe,CAAC;IAC5C,MAAM,GAAG,GAAG,YAAY,EAAE,CAAC;IAC3B,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,IAAI,CAAC;QACH,eAAe,GAAG,CAAC,MAAM,UAAU,CAAC,GAAG,EAAE,SAAS,CAAC,CAAY,CAAC;QAChE,OAAO,eAAe,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,KAAa;IACpC,OAAO,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC;AACxD,CAAC;AAED,SAAS,YAAY,CAAC,KAAa;IACjC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACrC,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AACxE,CAAC;AAED,SAAS,eAAe,CAAC,OAAmB;IAC1C,MAAM,CAAC,GAAI,OAA8B,CAAC,IAAI,CAAC;IAC/C,IAAI,CAAC,KAAK,WAAW,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,YAAY,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,KAAK,EAAE,CAAC;QAC5F,OAAO,CAAC,CAAC;IACX,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,SAAS,oBAAoB,CAAC,OAAmB;IAC/C,MAAM,CAAC,GAAI,OAAsC,CAAC,YAAY,CAAC;IAC/D,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1D,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAa;IACtC,OAAO;QACL,GAAG,EAAE,KAAK;QACV,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,IAAI;QACb,SAAS,EAAE,IAAI;QACf,YAAY,EAAE,IAAI;QAClB,QAAQ,EAAE,CAAC,GAAG,kBAAkB,CAAC;KAClC,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,KAAa,EAAE,OAAmB;IACzD,MAAM,IAAI,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACtC,MAAM,MAAM,GAAG,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IACpE,OAAO;QACL,GAAG,EAAE,KAAK;QACV,IAAI;QACJ,OAAO,EAAE,IAAI;QACb,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI;QAClD,YAAY,EAAE,oBAAoB,CAAC,OAAO,CAAC;QAC3C,QAAQ,EAAE,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,kBAAkB,CAAC,CAAC;KAC3D,CAAC;AACJ,CAAC;AAOD,KAAK,UAAU,SAAS;IACtB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC;QACnD,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACxC,IACE,MAAM;YACN,OAAO,MAAM,KAAK,QAAQ;YAC1B,OAAQ,MAAsB,CAAC,GAAG,KAAK,QAAQ;YAC/C,OAAQ,MAAsB,CAAC,UAAU,KAAK,QAAQ,EACtD,CAAC;YACD,OAAO,MAAqB,CAAC;QAC/B,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,cAAc;IAChB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,KAAkB;IAC1C,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,SAAS,EAAE,CAAC;QACtB,MAAM,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACzE,CAAC;IAAC,MAAM,CAAC;QACP,iBAAiB;IACnB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,KAAa,EAAE,GAAW;IACjD,MAAM,GAAG,GAAG,MAAM,aAAa,EAAE,CAAC;IAClC,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,IAAI,CAAC;QACH,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE;YAC5C,MAAM,EAAE,MAAM;YACd,QAAQ,EAAE,QAAQ;YAClB,UAAU,EAAE,CAAC,SAAS,CAAC;SACxB,CAAC,CAAC;QACH,OAAO,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,MAAc;IAC1C,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,kBAAkB,CAAC,CAAC;IACvE,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,UAAU,EAAE,qBAAqB,EAAE;YAC5D,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,MAAM,EAAE;gBACjC,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YACxB,MAAM,EAAE,UAAU,CAAC,MAAM;SAC1B,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QACzB,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAsB,CAAC;QACrD,IAAI,OAAO,IAAI,CAAC,GAAG,KAAK,QAAQ,IAAI,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC,GAAG,CAAC;QAC5E,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,KAAa;IAC5C,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;IACjC,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,UAAU,GAAG,YAAY;QAAE,OAAO,IAAI,CAAC;IAC/D,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IAChD,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE;QAAE,OAAO,IAAI,CAAC;IAC1E,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,QAAgB;IACpD,MAAM,KAAK,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACtC,IAAI,CAAC,KAAK;QAAE,OAAO,iBAAiB,CAAC,EAAE,CAAC,CAAC;IAEzC,wCAAwC;IACxC,IAAI,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC3C,OAAO,IAAI,IAAI,iBAAiB,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC;IAED,0DAA0D;IAC1D,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,MAAM,cAAc,CAAC,KAAK,CAAC,CAAC;QACxC,IAAI,GAAG,EAAE,CAAC;YACR,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YACzC,IAAI,IAAI,EAAE,CAAC;gBACT,MAAM,UAAU,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;gBAClD,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QACD,2CAA2C;QAC3C,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,KAAK,CAAC,CAAC;QAC9C,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;QAC1B,OAAO,iBAAiB,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;IAED,sCAAsC;IACtC,OAAO,iBAAiB,CAAC,KAAK,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,OAA6B,EAAE,OAAgB;IACxE,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAChC,OAAO,kBAAkB,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAiB;IAC/C,OAAO,aAAa,CAAC,IAAI,CAAC,IAAI,kBAAkB,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,IAAkB;IACvD,MAAM,MAAM,GAAG,IAAI,IAAI,WAAW,CAAC;IACnC,OAAO,MAAM,MAAM,CAAC,WAAW,EAAE,iBAAiB,CAAC;AACrD,CAAC;AAED,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* adapters.ts — descriptors for subscription-riding LLM CLIs (Layer C).
|
|
3
|
+
*
|
|
4
|
+
* The optional semantic layer (Layer C) can borrow an LLM the user ALREADY has
|
|
5
|
+
* set up by shelling out to a coding-agent CLI they have installed and logged
|
|
6
|
+
* into — no separate API key configured in PanGuard. Each adapter here is a
|
|
7
|
+
* small, immutable descriptor: the binary name, how to build a one-shot
|
|
8
|
+
* classification invocation, and the honest caveat we surface at onboarding.
|
|
9
|
+
*
|
|
10
|
+
* HARD RULES (enforced by the provider, encoded here as data):
|
|
11
|
+
* - We invoke the REAL, unmodified vendor binary as a subprocess. We NEVER
|
|
12
|
+
* read, copy, or reuse the vendor's cached OAuth token, and never spoof a
|
|
13
|
+
* client-identity header. That token-reuse pattern is exactly what the
|
|
14
|
+
* vendors' terms forbid and enforce against; shelling out to the real binary
|
|
15
|
+
* is a different, user-initiated, local action.
|
|
16
|
+
* - We inherit the user's own environment unchanged: the CLI authenticates
|
|
17
|
+
* with whatever the user already configured — a cached subscription login OR
|
|
18
|
+
* their own API key. We deliberately do NOT strip API keys: a machine authed
|
|
19
|
+
* only by a key would otherwise lose its auth and fall back to an
|
|
20
|
+
* interactive browser login that hangs a subprocess (found in smoke tests).
|
|
21
|
+
* So onboarding says "uses your CLI's existing login (subscription or your
|
|
22
|
+
* own key)" — never "free", never "always a subscription".
|
|
23
|
+
* - riskTier records the vendor-terms reality: 'clean' = the vendor's own docs
|
|
24
|
+
* demonstrate subprocess use (Gemini); 'grey' = subscription-riding works
|
|
25
|
+
* but the vendor's terms are silent-to-restrictive or steer automation
|
|
26
|
+
* toward API keys. Onboarding discloses this; we never claim a vendor
|
|
27
|
+
* endorses it, nor that it is free or unlimited.
|
|
28
|
+
*
|
|
29
|
+
* @module @panguard-ai/panguard-guard/llm-cli/adapters
|
|
30
|
+
*/
|
|
31
|
+
export type CliRiskTier = 'clean' | 'grey';
|
|
32
|
+
export type CliId = 'gemini' | 'claude' | 'codex' | 'cursor' | 'devin';
|
|
33
|
+
export interface CliAdapter {
|
|
34
|
+
readonly id: CliId;
|
|
35
|
+
/** Human label for onboarding, e.g. "Google Gemini CLI". */
|
|
36
|
+
readonly label: string;
|
|
37
|
+
/** Primary binary probed on PATH. */
|
|
38
|
+
readonly binary: string;
|
|
39
|
+
/** Other names the same binary may be installed as (e.g. cursor's `agent`). */
|
|
40
|
+
readonly altBinaries: readonly string[];
|
|
41
|
+
/** What the user's plan is called, for the disclosure copy. */
|
|
42
|
+
readonly planLabel: string;
|
|
43
|
+
/** Vendor-terms reality — drives onboarding ordering + disclosure wording. */
|
|
44
|
+
readonly riskTier: CliRiskTier;
|
|
45
|
+
/** One honest caveat line surfaced at onboarding. */
|
|
46
|
+
readonly caveat: string;
|
|
47
|
+
/**
|
|
48
|
+
* argv (NOT a shell string — spawned via execFile, no shell) for a one-shot
|
|
49
|
+
* classification. `prompt` already contains the full instruction + payload.
|
|
50
|
+
* `model`, when set, pins the model to avoid silent drift across updates.
|
|
51
|
+
*/
|
|
52
|
+
buildArgs(prompt: string, model?: string): readonly string[];
|
|
53
|
+
}
|
|
54
|
+
/** All adapters, clean-tier first (onboarding recommends the cleanest). */
|
|
55
|
+
export declare function allAdapters(): readonly CliAdapter[];
|
|
56
|
+
/** Look up an adapter by id, or null if unknown. */
|
|
57
|
+
export declare function getAdapter(id: string): CliAdapter | null;
|
|
58
|
+
/** True if the id names a known subscription CLI. */
|
|
59
|
+
export declare function isCliId(id: string): id is CliId;
|
|
60
|
+
//# sourceMappingURL=adapters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapters.d.ts","sourceRoot":"","sources":["../../src/llm-cli/adapters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC;AAC3C,MAAM,MAAM,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEvE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IACnB,4DAA4D;IAC5D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,qCAAqC;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,+EAA+E;IAC/E,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,+DAA+D;IAC/D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,8EAA8E;IAC9E,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,qDAAqD;IACrD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;CAC9D;AAwFD,2EAA2E;AAC3E,wBAAgB,WAAW,IAAI,SAAS,UAAU,EAAE,CAKnD;AAED,oDAAoD;AACpD,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAExD;AAED,qDAAqD;AACrD,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,EAAE,IAAI,KAAK,CAE/C"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* adapters.ts — descriptors for subscription-riding LLM CLIs (Layer C).
|
|
3
|
+
*
|
|
4
|
+
* The optional semantic layer (Layer C) can borrow an LLM the user ALREADY has
|
|
5
|
+
* set up by shelling out to a coding-agent CLI they have installed and logged
|
|
6
|
+
* into — no separate API key configured in PanGuard. Each adapter here is a
|
|
7
|
+
* small, immutable descriptor: the binary name, how to build a one-shot
|
|
8
|
+
* classification invocation, and the honest caveat we surface at onboarding.
|
|
9
|
+
*
|
|
10
|
+
* HARD RULES (enforced by the provider, encoded here as data):
|
|
11
|
+
* - We invoke the REAL, unmodified vendor binary as a subprocess. We NEVER
|
|
12
|
+
* read, copy, or reuse the vendor's cached OAuth token, and never spoof a
|
|
13
|
+
* client-identity header. That token-reuse pattern is exactly what the
|
|
14
|
+
* vendors' terms forbid and enforce against; shelling out to the real binary
|
|
15
|
+
* is a different, user-initiated, local action.
|
|
16
|
+
* - We inherit the user's own environment unchanged: the CLI authenticates
|
|
17
|
+
* with whatever the user already configured — a cached subscription login OR
|
|
18
|
+
* their own API key. We deliberately do NOT strip API keys: a machine authed
|
|
19
|
+
* only by a key would otherwise lose its auth and fall back to an
|
|
20
|
+
* interactive browser login that hangs a subprocess (found in smoke tests).
|
|
21
|
+
* So onboarding says "uses your CLI's existing login (subscription or your
|
|
22
|
+
* own key)" — never "free", never "always a subscription".
|
|
23
|
+
* - riskTier records the vendor-terms reality: 'clean' = the vendor's own docs
|
|
24
|
+
* demonstrate subprocess use (Gemini); 'grey' = subscription-riding works
|
|
25
|
+
* but the vendor's terms are silent-to-restrictive or steer automation
|
|
26
|
+
* toward API keys. Onboarding discloses this; we never claim a vendor
|
|
27
|
+
* endorses it, nor that it is free or unlimited.
|
|
28
|
+
*
|
|
29
|
+
* @module @panguard-ai/panguard-guard/llm-cli/adapters
|
|
30
|
+
*/
|
|
31
|
+
const ADAPTERS = Object.freeze({
|
|
32
|
+
// Cleanest terms: Google's own automation tutorial demonstrates shelling out
|
|
33
|
+
// to the real `gemini` binary; only reusing the cached OAuth token directly is
|
|
34
|
+
// forbidden — which we never do.
|
|
35
|
+
gemini: Object.freeze({
|
|
36
|
+
id: 'gemini',
|
|
37
|
+
label: 'Google Gemini CLI',
|
|
38
|
+
binary: 'gemini',
|
|
39
|
+
altBinaries: Object.freeze([]),
|
|
40
|
+
planLabel: 'Google / Gemini subscription',
|
|
41
|
+
riskTier: 'clean',
|
|
42
|
+
caveat: 'Uses your daily Gemini quota (shared with your own gemini use). Requires a one-time `gemini` browser login first.',
|
|
43
|
+
buildArgs: (prompt, model) => model ? ['-m', model, '-p', prompt] : ['-p', prompt],
|
|
44
|
+
}),
|
|
45
|
+
// Rides the Claude Pro/Max OAuth login. Grey area: Anthropic's legal page says
|
|
46
|
+
// OAuth is "exclusively for ordinary use of Claude Code" and forbids third
|
|
47
|
+
// parties routing requests through Pro/Max credentials on behalf of users —
|
|
48
|
+
// invoking your own already-authed real binary locally sits on that boundary.
|
|
49
|
+
claude: Object.freeze({
|
|
50
|
+
id: 'claude',
|
|
51
|
+
label: 'Claude Code CLI',
|
|
52
|
+
binary: 'claude',
|
|
53
|
+
altBinaries: Object.freeze([]),
|
|
54
|
+
planLabel: 'Claude Pro / Max subscription',
|
|
55
|
+
riskTier: 'grey',
|
|
56
|
+
caveat: 'Spends your Claude Code usage (same pool as your coding) and can hit rate limits. Terms grey area; Anthropic has signalled billing may change. Do NOT pass --bare (that needs an API key).',
|
|
57
|
+
buildArgs: (prompt, model) => model ? ['-p', prompt, '--model', model] : ['-p', prompt],
|
|
58
|
+
}),
|
|
59
|
+
// Rides the "Sign in with ChatGPT" session. OpenAI's docs recommend an API key
|
|
60
|
+
// for automation; ChatGPT-login can auto-create a linked key → surprise
|
|
61
|
+
// billing, so we scrub keys and disclose.
|
|
62
|
+
codex: Object.freeze({
|
|
63
|
+
id: 'codex',
|
|
64
|
+
label: 'OpenAI Codex CLI',
|
|
65
|
+
binary: 'codex',
|
|
66
|
+
altBinaries: Object.freeze([]),
|
|
67
|
+
planLabel: 'ChatGPT Plus / Pro plan',
|
|
68
|
+
riskTier: 'grey',
|
|
69
|
+
caveat: 'Spends your ChatGPT plan agentic quota. OpenAI steers automation to API keys; sign-in-with-ChatGPT can create a linked key with per-token billing.',
|
|
70
|
+
buildArgs: (prompt, model) => model ? ['exec', '--model', model, prompt] : ['exec', prompt],
|
|
71
|
+
}),
|
|
72
|
+
// Cursor staff confirm the CLI rides the Cursor subscription, but it is beta
|
|
73
|
+
// ("use at your own risk") and third-party invocation is an unblessed grey
|
|
74
|
+
// area. Model is pinned when provided to control latency/drift.
|
|
75
|
+
cursor: Object.freeze({
|
|
76
|
+
id: 'cursor',
|
|
77
|
+
label: 'Cursor CLI',
|
|
78
|
+
binary: 'cursor-agent',
|
|
79
|
+
altBinaries: Object.freeze(['agent']),
|
|
80
|
+
planLabel: 'Cursor Pro subscription',
|
|
81
|
+
riskTier: 'grey',
|
|
82
|
+
caveat: 'Beta CLI ("use at your own risk"). Spends your Cursor Pro agent quota. Requires a one-time `cursor-agent login`.',
|
|
83
|
+
buildArgs: (prompt, model) => model
|
|
84
|
+
? ['-p', prompt, '--output-format', 'text', '--model', model]
|
|
85
|
+
: ['-p', prompt, '--output-format', 'text'],
|
|
86
|
+
}),
|
|
87
|
+
// Windsurf is now Devin Desktop (Cognition, rebranded 2026-06). The `devin`
|
|
88
|
+
// CLI rides the account plan/ACU quota; newest + most volatile, so smoke-test
|
|
89
|
+
// before trusting. "No separate key" is inferred by exclusion — disclosed as
|
|
90
|
+
// "appears to ride your plan", not guaranteed.
|
|
91
|
+
devin: Object.freeze({
|
|
92
|
+
id: 'devin',
|
|
93
|
+
label: 'Windsurf / Devin CLI',
|
|
94
|
+
binary: 'devin',
|
|
95
|
+
altBinaries: Object.freeze([]),
|
|
96
|
+
planLabel: 'Windsurf / Devin plan',
|
|
97
|
+
riskTier: 'grey',
|
|
98
|
+
caveat: 'Windsurf is now Devin Desktop. Appears to ride your plan ACU quota (no API-key step in the docs). Newest integration — verify with a real `devin -p` call.',
|
|
99
|
+
buildArgs: (prompt, model) => model ? ['-p', '--model', model, prompt] : ['-p', prompt],
|
|
100
|
+
}),
|
|
101
|
+
});
|
|
102
|
+
/** All adapters, clean-tier first (onboarding recommends the cleanest). */
|
|
103
|
+
export function allAdapters() {
|
|
104
|
+
const list = Object.values(ADAPTERS);
|
|
105
|
+
return Object.freeze([...list].sort((a, b) => (a.riskTier === b.riskTier ? 0 : a.riskTier === 'clean' ? -1 : 1)));
|
|
106
|
+
}
|
|
107
|
+
/** Look up an adapter by id, or null if unknown. */
|
|
108
|
+
export function getAdapter(id) {
|
|
109
|
+
return ADAPTERS[id] ?? null;
|
|
110
|
+
}
|
|
111
|
+
/** True if the id names a known subscription CLI. */
|
|
112
|
+
export function isCliId(id) {
|
|
113
|
+
return id in ADAPTERS;
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=adapters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapters.js","sourceRoot":"","sources":["../../src/llm-cli/adapters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AA2BH,MAAM,QAAQ,GAAwC,MAAM,CAAC,MAAM,CAAC;IAClE,6EAA6E;IAC7E,+EAA+E;IAC/E,iCAAiC;IACjC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC;QACpB,EAAE,EAAE,QAAQ;QACZ,KAAK,EAAE,mBAAmB;QAC1B,MAAM,EAAE,QAAQ;QAChB,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9B,SAAS,EAAE,8BAA8B;QACzC,QAAQ,EAAE,OAAO;QACjB,MAAM,EACJ,mHAAmH;QACrH,SAAS,EAAE,CAAC,MAAc,EAAE,KAAc,EAAE,EAAE,CAC5C,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC;KACvD,CAAC;IAEF,+EAA+E;IAC/E,2EAA2E;IAC3E,4EAA4E;IAC5E,8EAA8E;IAC9E,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC;QACpB,EAAE,EAAE,QAAQ;QACZ,KAAK,EAAE,iBAAiB;QACxB,MAAM,EAAE,QAAQ;QAChB,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9B,SAAS,EAAE,+BAA+B;QAC1C,QAAQ,EAAE,MAAM;QAChB,MAAM,EACJ,4LAA4L;QAC9L,SAAS,EAAE,CAAC,MAAc,EAAE,KAAc,EAAE,EAAE,CAC5C,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC;KAC5D,CAAC;IAEF,+EAA+E;IAC/E,wEAAwE;IACxE,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC;QACnB,EAAE,EAAE,OAAO;QACX,KAAK,EAAE,kBAAkB;QACzB,MAAM,EAAE,OAAO;QACf,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9B,SAAS,EAAE,yBAAyB;QACpC,QAAQ,EAAE,MAAM;QAChB,MAAM,EACJ,oJAAoJ;QACtJ,SAAS,EAAE,CAAC,MAAc,EAAE,KAAc,EAAE,EAAE,CAC5C,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC;KAChE,CAAC;IAEF,6EAA6E;IAC7E,2EAA2E;IAC3E,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC;QACpB,EAAE,EAAE,QAAQ;QACZ,KAAK,EAAE,YAAY;QACnB,MAAM,EAAE,cAAc;QACtB,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC;QACrC,SAAS,EAAE,yBAAyB;QACpC,QAAQ,EAAE,MAAM;QAChB,MAAM,EACJ,kHAAkH;QACpH,SAAS,EAAE,CAAC,MAAc,EAAE,KAAc,EAAE,EAAE,CAC5C,KAAK;YACH,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC;YAC7D,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,CAAC;KAChD,CAAC;IAEF,4EAA4E;IAC5E,8EAA8E;IAC9E,6EAA6E;IAC7E,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC;QACnB,EAAE,EAAE,OAAO;QACX,KAAK,EAAE,sBAAsB;QAC7B,MAAM,EAAE,OAAO;QACf,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9B,SAAS,EAAE,uBAAuB;QAClC,QAAQ,EAAE,MAAM;QAChB,MAAM,EACJ,4JAA4J;QAC9J,SAAS,EAAE,CAAC,MAAc,EAAE,KAAc,EAAE,EAAE,CAC5C,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC;KAC5D,CAAC;CACH,CAAC,CAAC;AAEH,2EAA2E;AAC3E,MAAM,UAAU,WAAW;IACzB,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACrC,OAAO,MAAM,CAAC,MAAM,CAClB,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAC5F,CAAC;AACJ,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,UAAU,CAAC,EAAU;IACnC,OAAQ,QAAuC,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC;AAC9D,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,OAAO,CAAC,EAAU;IAChC,OAAO,EAAE,IAAI,QAAQ,CAAC;AACxB,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* detect.ts — find subscription-riding LLM CLIs installed on this machine.
|
|
3
|
+
*
|
|
4
|
+
* The Layer C provider is NOT bound to the host being protected: whichever
|
|
5
|
+
* subscription CLI is installed and logged in can serve as the AI brain,
|
|
6
|
+
* regardless of whether the user runs Claude Code, Cursor, or something else.
|
|
7
|
+
* We detect purely by "is the binary on PATH" (cheap, no quota) and — only when
|
|
8
|
+
* the user is actively setting up — an optional one-call auth probe.
|
|
9
|
+
*
|
|
10
|
+
* @module @panguard-ai/panguard-guard/llm-cli/detect
|
|
11
|
+
*/
|
|
12
|
+
import { type CliId, type CliRiskTier } from './adapters.js';
|
|
13
|
+
export interface DetectedCli {
|
|
14
|
+
readonly id: CliId;
|
|
15
|
+
readonly label: string;
|
|
16
|
+
readonly binary: string;
|
|
17
|
+
readonly planLabel: string;
|
|
18
|
+
readonly riskTier: CliRiskTier;
|
|
19
|
+
readonly caveat: string;
|
|
20
|
+
/** The name actually found on PATH (binary or an alt). */
|
|
21
|
+
readonly foundAs: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Detect subscription CLIs present on PATH. Cheap — does NOT verify login or
|
|
25
|
+
* spend any quota. Clean-tier (Gemini) is returned first so onboarding can
|
|
26
|
+
* recommend the tool with the least-restrictive vendor terms.
|
|
27
|
+
*/
|
|
28
|
+
export declare function detectSubscriptionClis(): Promise<DetectedCli[]>;
|
|
29
|
+
/**
|
|
30
|
+
* Onboarding-only: verify a detected CLI is actually LOGGED IN by running one
|
|
31
|
+
* real classification and checking it returns a usable verdict. Spends one call
|
|
32
|
+
* of the user's quota — acceptable for an interactive, user-initiated setup, and
|
|
33
|
+
* never run on the hot path. Uses the CLI's own auth (subscription or the user's
|
|
34
|
+
* own key), same as the runtime path.
|
|
35
|
+
*/
|
|
36
|
+
export declare function probeCliAuth(id: string, model?: string): Promise<boolean>;
|
|
37
|
+
//# sourceMappingURL=detect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../src/llm-cli/detect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAgC,KAAK,KAAK,EAAE,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAG3F,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,0DAA0D;IAC1D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAoCD;;;;GAIG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAiBrE;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO/E"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* detect.ts — find subscription-riding LLM CLIs installed on this machine.
|
|
3
|
+
*
|
|
4
|
+
* The Layer C provider is NOT bound to the host being protected: whichever
|
|
5
|
+
* subscription CLI is installed and logged in can serve as the AI brain,
|
|
6
|
+
* regardless of whether the user runs Claude Code, Cursor, or something else.
|
|
7
|
+
* We detect purely by "is the binary on PATH" (cheap, no quota) and — only when
|
|
8
|
+
* the user is actively setting up — an optional one-call auth probe.
|
|
9
|
+
*
|
|
10
|
+
* @module @panguard-ai/panguard-guard/llm-cli/detect
|
|
11
|
+
*/
|
|
12
|
+
import { execFile } from 'node:child_process';
|
|
13
|
+
import { allAdapters } from './adapters.js';
|
|
14
|
+
import { SubscriptionCliLLM } from './subprocess-llm.js';
|
|
15
|
+
/** True if `bin` resolves on PATH (uses the platform's own lookup, no shell). */
|
|
16
|
+
function onPath(bin) {
|
|
17
|
+
const finder = process.platform === 'win32' ? 'where' : 'command';
|
|
18
|
+
const args = process.platform === 'win32' ? [bin] : ['-v', bin];
|
|
19
|
+
return new Promise((resolve) => {
|
|
20
|
+
// `command -v` is a shell builtin; invoke via the shell for POSIX. On Windows
|
|
21
|
+
// `where` is a real executable. Either way we only read a yes/no.
|
|
22
|
+
const child = process.platform === 'win32'
|
|
23
|
+
? execFile(finder, args, { windowsHide: true }, (err) => resolve(!err))
|
|
24
|
+
: execFile('/bin/sh', ['-c', `command -v ${shellQuote(bin)}`], { windowsHide: true }, (err) => resolve(!err));
|
|
25
|
+
child.on('error', () => resolve(false));
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
/** Minimal single-quote shell escaping for the `command -v <bin>` lookup. */
|
|
29
|
+
function shellQuote(s) {
|
|
30
|
+
return `'${s.replace(/'/g, `'\\''`)}'`;
|
|
31
|
+
}
|
|
32
|
+
/** Resolve which name an adapter's binary is installed as, or null if absent. */
|
|
33
|
+
async function resolveBinary(adapter) {
|
|
34
|
+
for (const name of [adapter.binary, ...adapter.altBinaries]) {
|
|
35
|
+
// eslint-disable-next-line no-await-in-loop -- short, ordered preference
|
|
36
|
+
if (await onPath(name))
|
|
37
|
+
return name;
|
|
38
|
+
}
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Detect subscription CLIs present on PATH. Cheap — does NOT verify login or
|
|
43
|
+
* spend any quota. Clean-tier (Gemini) is returned first so onboarding can
|
|
44
|
+
* recommend the tool with the least-restrictive vendor terms.
|
|
45
|
+
*/
|
|
46
|
+
export async function detectSubscriptionClis() {
|
|
47
|
+
const found = [];
|
|
48
|
+
for (const adapter of allAdapters()) {
|
|
49
|
+
// eslint-disable-next-line no-await-in-loop -- a handful of quick PATH lookups
|
|
50
|
+
const foundAs = await resolveBinary(adapter);
|
|
51
|
+
if (!foundAs)
|
|
52
|
+
continue;
|
|
53
|
+
found.push({
|
|
54
|
+
id: adapter.id,
|
|
55
|
+
label: adapter.label,
|
|
56
|
+
binary: adapter.binary,
|
|
57
|
+
planLabel: adapter.planLabel,
|
|
58
|
+
riskTier: adapter.riskTier,
|
|
59
|
+
caveat: adapter.caveat,
|
|
60
|
+
foundAs,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
return found;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Onboarding-only: verify a detected CLI is actually LOGGED IN by running one
|
|
67
|
+
* real classification and checking it returns a usable verdict. Spends one call
|
|
68
|
+
* of the user's quota — acceptable for an interactive, user-initiated setup, and
|
|
69
|
+
* never run on the hot path. Uses the CLI's own auth (subscription or the user's
|
|
70
|
+
* own key), same as the runtime path.
|
|
71
|
+
*/
|
|
72
|
+
export async function probeCliAuth(id, model) {
|
|
73
|
+
const adapter = allAdapters().find((a) => a.id === id);
|
|
74
|
+
if (!adapter)
|
|
75
|
+
return false;
|
|
76
|
+
const llm = new SubscriptionCliLLM(adapter, model, 20_000);
|
|
77
|
+
// probeAuth makes one real call and does NOT fail open — a non-empty answer
|
|
78
|
+
// means the CLI is installed AND logged in; a throw/timeout means not ready.
|
|
79
|
+
return llm.probeAuth();
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../src/llm-cli/detect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* llm-cli — Layer C via a subscription-riding coding-agent CLI.
|
|
3
|
+
*
|
|
4
|
+
* Public surface: detect installed CLIs, build a provider, and the adapter data
|
|
5
|
+
* (for onboarding copy + tests). See ./adapters.ts for the ToS guardrails.
|
|
6
|
+
*
|
|
7
|
+
* @module @panguard-ai/panguard-guard/llm-cli
|
|
8
|
+
*/
|
|
9
|
+
export { allAdapters, getAdapter, isCliId, type CliAdapter, type CliId, type CliRiskTier, } from './adapters.js';
|
|
10
|
+
export { SubscriptionCliLLM, createSubscriptionCliLLM, extractVerdict } from './subprocess-llm.js';
|
|
11
|
+
export { detectSubscriptionClis, probeCliAuth, type DetectedCli } from './detect.js';
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/llm-cli/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,WAAW,EACX,UAAU,EACV,OAAO,EACP,KAAK,UAAU,EACf,KAAK,KAAK,EACV,KAAK,WAAW,GACjB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACnG,OAAO,EAAE,sBAAsB,EAAE,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* llm-cli — Layer C via a subscription-riding coding-agent CLI.
|
|
3
|
+
*
|
|
4
|
+
* Public surface: detect installed CLIs, build a provider, and the adapter data
|
|
5
|
+
* (for onboarding copy + tests). See ./adapters.ts for the ToS guardrails.
|
|
6
|
+
*
|
|
7
|
+
* @module @panguard-ai/panguard-guard/llm-cli
|
|
8
|
+
*/
|
|
9
|
+
export { allAdapters, getAdapter, isCliId, } from './adapters.js';
|
|
10
|
+
export { SubscriptionCliLLM, createSubscriptionCliLLM, extractVerdict } from './subprocess-llm.js';
|
|
11
|
+
export { detectSubscriptionClis, probeCliAuth } from './detect.js';
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/llm-cli/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,WAAW,EACX,UAAU,EACV,OAAO,GAIR,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACnG,OAAO,EAAE,sBAAsB,EAAE,YAAY,EAAoB,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* subprocess-llm.ts — an AnalyzeLLM backed by a subscription-riding CLI.
|
|
3
|
+
*
|
|
4
|
+
* Spawns the user's already-installed, already-logged-in coding-agent CLI
|
|
5
|
+
* (gemini / claude / codex / cursor-agent / devin) as a one-shot classifier for
|
|
6
|
+
* the optional semantic layer (Layer C). It NEVER touches the vendor's token
|
|
7
|
+
* file — it only runs the real binary — and it strips provider API-key env vars
|
|
8
|
+
* before spawn so the call rides the subscription, not metered API billing.
|
|
9
|
+
*
|
|
10
|
+
* Fail-open by construction: any spawn error, timeout, unparseable output, or an
|
|
11
|
+
* open circuit-breaker returns a zero-confidence benign verdict, so Layer C
|
|
12
|
+
* degrading never blocks and never masquerades as a detection. The regex Layers
|
|
13
|
+
* A/B keep protecting regardless.
|
|
14
|
+
*
|
|
15
|
+
* @module @panguard-ai/panguard-guard/llm-cli/subprocess-llm
|
|
16
|
+
*/
|
|
17
|
+
import type { SecurityEvent } from '@panguard-ai/core';
|
|
18
|
+
import type { AnalyzeLLM, LLMAnalysisResult, LLMClassificationResult } from '../types.js';
|
|
19
|
+
import { type CliAdapter } from './adapters.js';
|
|
20
|
+
/** A parsed verdict, already clamped to safe ranges. */
|
|
21
|
+
interface Verdict {
|
|
22
|
+
severity: string;
|
|
23
|
+
confidence: number;
|
|
24
|
+
technique: string;
|
|
25
|
+
summary: string;
|
|
26
|
+
}
|
|
27
|
+
/** Extract the model's structured verdict from raw stdout, leniently. */
|
|
28
|
+
export declare function extractVerdict(rawStdout: string): Verdict;
|
|
29
|
+
/** An AnalyzeLLM whose brain is a locally-installed subscription CLI. */
|
|
30
|
+
export declare class SubscriptionCliLLM implements AnalyzeLLM {
|
|
31
|
+
private readonly adapter;
|
|
32
|
+
private readonly model?;
|
|
33
|
+
private readonly timeoutMs;
|
|
34
|
+
private failures;
|
|
35
|
+
private openUntil;
|
|
36
|
+
constructor(adapter: CliAdapter, model?: string | undefined, timeoutMs?: number);
|
|
37
|
+
/**
|
|
38
|
+
* Onboarding-only: verify the CLI is actually LOGGED IN by making one real
|
|
39
|
+
* classification call and requiring a non-empty answer. Unlike the hot path,
|
|
40
|
+
* this does NOT swallow the error into a benign verdict — an auth failure /
|
|
41
|
+
* timeout / missing binary returns false so setup can degrade honestly. Spends
|
|
42
|
+
* one call of the user's quota; never run on the hot path.
|
|
43
|
+
*/
|
|
44
|
+
probeAuth(): Promise<boolean>;
|
|
45
|
+
/**
|
|
46
|
+
* Availability = the binary runs at all (cheap, spends NO model quota). Probes
|
|
47
|
+
* with literal `--version` then `--help` — NOT via buildArgs, which would treat
|
|
48
|
+
* the flag as a prompt. Different CLIs support different liveness flags, so
|
|
49
|
+
* either exiting cleanly counts.
|
|
50
|
+
*/
|
|
51
|
+
isAvailable(): Promise<boolean>;
|
|
52
|
+
analyze(prompt: string, context?: string): Promise<LLMAnalysisResult>;
|
|
53
|
+
classify(event: SecurityEvent): Promise<LLMClassificationResult>;
|
|
54
|
+
/** Core path: breaker-guarded, timeout-bounded, fail-open one-shot classify. */
|
|
55
|
+
private classifyText;
|
|
56
|
+
private breakerOpen;
|
|
57
|
+
private recordFailure;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Build a SubscriptionCliLLM for a config'd cli id, or null if the id is unknown.
|
|
61
|
+
* Does not probe — callers gate on isAvailable().
|
|
62
|
+
*/
|
|
63
|
+
export declare function createSubscriptionCliLLM(cli: string, model?: string, timeoutMs?: number): SubscriptionCliLLM | null;
|
|
64
|
+
export {};
|
|
65
|
+
//# sourceMappingURL=subprocess-llm.d.ts.map
|