@shield-agent/kya 0.28.0 → 0.30.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/.cursor-plugin/plugin.json +1 -1
- package/.mcp.json +1 -1
- package/README.md +3 -3
- package/amp/settings.example.json +1 -1
- package/claude/claude_desktop_config.example.json +1 -1
- package/cline/cline_mcp_settings.example.json +1 -1
- package/copilot/mcp-config.example.json +1 -1
- package/dist/certify/attest.js +4 -4
- package/dist/certify/attest.js.map +1 -1
- package/dist/commands/certify.js +6 -6
- package/dist/commands/certify.js.map +1 -1
- package/dist/commands/connect.d.ts +1 -1
- package/dist/commands/connect.d.ts.map +1 -1
- package/dist/commands/connect.js +15 -8
- package/dist/commands/connect.js.map +1 -1
- package/dist/commands/init.js +5 -5
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/orr.d.ts.map +1 -1
- package/dist/commands/orr.js +6 -4
- package/dist/commands/orr.js.map +1 -1
- package/dist/commands/receipt.d.ts.map +1 -1
- package/dist/commands/receipt.js +5 -5
- package/dist/commands/receipt.js.map +1 -1
- package/dist/commands/start.d.ts +1 -1
- package/dist/commands/start.d.ts.map +1 -1
- package/dist/commands/start.js +9 -2
- package/dist/commands/start.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +4 -4
- package/dist/config.js.map +1 -1
- package/dist/fs-atomic.d.ts +40 -0
- package/dist/fs-atomic.d.ts.map +1 -1
- package/dist/fs-atomic.js +140 -1
- package/dist/fs-atomic.js.map +1 -1
- package/dist/receipt/auto-open.d.ts.map +1 -1
- package/dist/receipt/auto-open.js +4 -3
- package/dist/receipt/auto-open.js.map +1 -1
- package/dist/receipt/daemon.d.ts.map +1 -1
- package/dist/receipt/daemon.js +7 -4
- package/dist/receipt/daemon.js.map +1 -1
- package/dist/receipt/live-server.d.ts.map +1 -1
- package/dist/receipt/live-server.js +68 -9
- package/dist/receipt/live-server.js.map +1 -1
- package/dist/receipt/openshell-card.d.ts +88 -0
- package/dist/receipt/openshell-card.d.ts.map +1 -0
- package/dist/receipt/openshell-card.js +219 -0
- package/dist/receipt/openshell-card.js.map +1 -0
- package/dist/receipt/render-receipt.d.ts +3 -0
- package/dist/receipt/render-receipt.d.ts.map +1 -1
- package/dist/receipt/render-receipt.js +201 -4
- package/dist/receipt/render-receipt.js.map +1 -1
- package/dist/sandbox/openshell-policy.d.ts.map +1 -1
- package/dist/sandbox/openshell-policy.js +2 -3
- package/dist/sandbox/openshell-policy.js.map +1 -1
- package/dist/sandbox/runtime.d.ts.map +1 -1
- package/dist/sandbox/runtime.js +4 -4
- package/dist/sandbox/runtime.js.map +1 -1
- package/dist/star-cta.js +4 -4
- package/dist/star-cta.js.map +1 -1
- package/droid/README.md +1 -1
- package/droid/mcp.example.json +1 -1
- package/gemini/settings.example.json +1 -1
- package/grok/README.md +1 -1
- package/kilo/kilo.example.json +1 -1
- package/kimi/mcp.example.json +1 -1
- package/kiro/mcp.example.json +1 -1
- package/manifest.json +1 -1
- package/mastracode/mcp.example.json +1 -1
- package/mcp.json +1 -1
- package/openai/codex.config.example.toml +1 -1
- package/opencode/opencode.example.json +1 -1
- package/package.json +1 -1
- package/qwen/settings.example.json +1 -1
- package/server.json +2 -2
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenShell card for the live Agent-activity report (NVIDIA OpenShell,
|
|
3
|
+
* github.com/NVIDIA/OpenShell). One dedicated panel aggregating the three
|
|
4
|
+
* places OpenShell shows up today: imported openshell trail events
|
|
5
|
+
* (reasonCode OPENSHELL_POLICY, toolId openshell.network / openshell.http),
|
|
6
|
+
* openshell-backend sandbox rows in .kya/sandboxes.json, and the locally
|
|
7
|
+
* detected openshell CLI / openshell-prover binaries.
|
|
8
|
+
*
|
|
9
|
+
* Fail-safe like every enrich loader: the pure rollup never throws, every
|
|
10
|
+
* runtime probe degrades to a "not detected" row on a missing binary, a
|
|
11
|
+
* failing --version, or a missing file, and the loader returns undefined
|
|
12
|
+
* (panel omitted entirely) when no OpenShell signal exists at all - fresh
|
|
13
|
+
* installs must not see the panel. The SAFE-06 certify outcome is reused
|
|
14
|
+
* from the already-computed certify card, never recomputed here.
|
|
15
|
+
*/
|
|
16
|
+
import { execFileSync } from "node:child_process";
|
|
17
|
+
import { accessSync, constants, existsSync } from "node:fs";
|
|
18
|
+
import { basename, join } from "node:path";
|
|
19
|
+
import { OPENSHELL_MIN_VERSION } from "../sandbox/openshell-driver.js";
|
|
20
|
+
import { openshellPolicyPath } from "../sandbox/openshell-policy.js";
|
|
21
|
+
import { resolveOpenshellProver } from "../certify/openshell-prover.js";
|
|
22
|
+
import { loadSandboxState } from "../sandbox/runtime.js";
|
|
23
|
+
const OPENSHELL_TOOLS = new Set(["openshell.network", "openshell.http"]);
|
|
24
|
+
const MAX_DST_LEN = 80;
|
|
25
|
+
const TOP_DESTINATIONS = 5;
|
|
26
|
+
/** One report panel signal: an openshell tool or the OPENSHELL_POLICY reason. */
|
|
27
|
+
export function isOpenshellEvent(e) {
|
|
28
|
+
return OPENSHELL_TOOLS.has(e.toolId) || e.reasonCode === "OPENSHELL_POLICY";
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The importer writes a redacted `dst: host:port` rendering into the event
|
|
32
|
+
* summary; parse it defensively - summaries are user-editable trail data.
|
|
33
|
+
*/
|
|
34
|
+
function destinationFromSummary(summary) {
|
|
35
|
+
if (!summary)
|
|
36
|
+
return undefined;
|
|
37
|
+
const dst = /(?:^|\s)dst:\s*(\S+)/i.exec(summary.trim())?.[1]?.trim();
|
|
38
|
+
if (!dst)
|
|
39
|
+
return undefined;
|
|
40
|
+
return dst.length <= MAX_DST_LEN ? dst : dst.slice(0, MAX_DST_LEN);
|
|
41
|
+
}
|
|
42
|
+
/** Pure rollup of openshell events for the panel's Policy activity card. */
|
|
43
|
+
export function aggregateOpenshellEvents(events) {
|
|
44
|
+
let total = 0;
|
|
45
|
+
let deny = 0;
|
|
46
|
+
let allow = 0;
|
|
47
|
+
let network = 0;
|
|
48
|
+
let http = 0;
|
|
49
|
+
let lastTs = "";
|
|
50
|
+
const dstCounts = new Map();
|
|
51
|
+
for (const e of events) {
|
|
52
|
+
if (!isOpenshellEvent(e))
|
|
53
|
+
continue;
|
|
54
|
+
total++;
|
|
55
|
+
const v = e.verdict.toUpperCase();
|
|
56
|
+
if (v === "DENY")
|
|
57
|
+
deny++;
|
|
58
|
+
else if (v === "ALLOW")
|
|
59
|
+
allow++;
|
|
60
|
+
if (e.toolId === "openshell.http")
|
|
61
|
+
http++;
|
|
62
|
+
else
|
|
63
|
+
network++;
|
|
64
|
+
if (e.ts > lastTs)
|
|
65
|
+
lastTs = e.ts;
|
|
66
|
+
const dst = destinationFromSummary(e.summary);
|
|
67
|
+
if (dst)
|
|
68
|
+
dstCounts.set(dst, (dstCounts.get(dst) ?? 0) + 1);
|
|
69
|
+
}
|
|
70
|
+
if (total === 0)
|
|
71
|
+
return undefined;
|
|
72
|
+
const topDestinations = [...dstCounts.entries()]
|
|
73
|
+
.map(([dst, count]) => ({ dst, count }))
|
|
74
|
+
.sort((a, b) => b.count - a.count || a.dst.localeCompare(b.dst))
|
|
75
|
+
.slice(0, TOP_DESTINATIONS);
|
|
76
|
+
return { total, deny, allow, network, http, topDestinations, lastTs };
|
|
77
|
+
}
|
|
78
|
+
function executable(path) {
|
|
79
|
+
try {
|
|
80
|
+
accessSync(path, constants.X_OK);
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Locate the openshell CLI the way the sandbox driver does: KYA_SANDBOX_OPENSHELL
|
|
89
|
+
* (absolute path, basename openshell) wins, else PATH. Never throws: a malformed
|
|
90
|
+
* env override or a missing binary yields undefined ("not detected").
|
|
91
|
+
*/
|
|
92
|
+
function resolveOpenshellCli(env) {
|
|
93
|
+
const fromEnv = env.KYA_SANDBOX_OPENSHELL?.trim();
|
|
94
|
+
if (fromEnv) {
|
|
95
|
+
if (!fromEnv.startsWith("/") || basename(fromEnv) !== "openshell")
|
|
96
|
+
return undefined;
|
|
97
|
+
return executable(fromEnv) ? fromEnv : undefined;
|
|
98
|
+
}
|
|
99
|
+
for (const dir of (env.PATH ?? "").split(":")) {
|
|
100
|
+
if (!dir || dir === "." || dir.startsWith("."))
|
|
101
|
+
continue;
|
|
102
|
+
const candidate = join(dir, "openshell");
|
|
103
|
+
if (!candidate.startsWith("/"))
|
|
104
|
+
continue;
|
|
105
|
+
if (executable(candidate))
|
|
106
|
+
return candidate;
|
|
107
|
+
}
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
/** One --version probe per resolved binary per process, never per refresh. */
|
|
111
|
+
const versionCache = new Map();
|
|
112
|
+
/** Test hook: drop cached `openshell --version` results. */
|
|
113
|
+
export function openshellCardResetForTests() {
|
|
114
|
+
versionCache.clear();
|
|
115
|
+
}
|
|
116
|
+
function probeOpenshellVersion(bin, env) {
|
|
117
|
+
if (versionCache.has(bin))
|
|
118
|
+
return versionCache.get(bin);
|
|
119
|
+
let version;
|
|
120
|
+
try {
|
|
121
|
+
const out = execFileSync(bin, ["--version"], {
|
|
122
|
+
encoding: "utf8",
|
|
123
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
124
|
+
env: { ...env, OPENSHELL_TELEMETRY_ENABLED: "false" },
|
|
125
|
+
timeout: 10_000,
|
|
126
|
+
}).trim();
|
|
127
|
+
version = /(\d+\.\d+\.\d+)/.exec(out)?.[1] ?? out.split("\n")[0]?.trim() ?? undefined;
|
|
128
|
+
if (!version)
|
|
129
|
+
version = undefined;
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
version = undefined;
|
|
133
|
+
}
|
|
134
|
+
versionCache.set(bin, version);
|
|
135
|
+
return version;
|
|
136
|
+
}
|
|
137
|
+
function containerRuntimeOnPath(env) {
|
|
138
|
+
for (const dir of (env.PATH ?? "").split(":")) {
|
|
139
|
+
if (!dir || dir === "." || dir.startsWith("."))
|
|
140
|
+
continue;
|
|
141
|
+
for (const rt of ["docker", "podman"]) {
|
|
142
|
+
const candidate = join(dir, rt);
|
|
143
|
+
if (candidate.startsWith("/") && executable(candidate))
|
|
144
|
+
return rt;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return undefined;
|
|
148
|
+
}
|
|
149
|
+
function openshellSandboxRows(cwd) {
|
|
150
|
+
let rows;
|
|
151
|
+
try {
|
|
152
|
+
rows = loadSandboxState(cwd);
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
return [];
|
|
156
|
+
}
|
|
157
|
+
return rows
|
|
158
|
+
.filter((r) => r.backend === "openshell")
|
|
159
|
+
.map((r) => {
|
|
160
|
+
let policyFile = false;
|
|
161
|
+
try {
|
|
162
|
+
policyFile = existsSync(openshellPolicyPath(cwd, r.sandboxId));
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
policyFile = false;
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
sandboxId: r.sandboxId,
|
|
169
|
+
status: r.status,
|
|
170
|
+
createdAt: r.createdAt,
|
|
171
|
+
externalName: r.externalName,
|
|
172
|
+
policyFile,
|
|
173
|
+
};
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* An all-empty card: no activity, no sandboxes, every runtime probe negative.
|
|
178
|
+
* Used by the renderer when the model carries no card (static artifacts) so the
|
|
179
|
+
* panel can still render its self-service empty state.
|
|
180
|
+
*/
|
|
181
|
+
export function emptyOpenshellCard() {
|
|
182
|
+
return {
|
|
183
|
+
activity: undefined,
|
|
184
|
+
sandboxes: [],
|
|
185
|
+
runtime: {
|
|
186
|
+
cliFound: false,
|
|
187
|
+
cliVersion: undefined,
|
|
188
|
+
containerRuntime: undefined,
|
|
189
|
+
minVersion: OPENSHELL_MIN_VERSION,
|
|
190
|
+
proverFound: false,
|
|
191
|
+
safe06: undefined,
|
|
192
|
+
},
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Build the OpenShell card. Always returns a card, even when nothing
|
|
197
|
+
* OpenShell-related exists yet (no trail events, no openshell sandboxes, no
|
|
198
|
+
* openshell CLI or prover on PATH): the report renders the panel with empty
|
|
199
|
+
* states so OpenShell support stays discoverable from the dashboard itself.
|
|
200
|
+
* See docs/report-design.md (the dashboard is self-explanatory at all times).
|
|
201
|
+
* Every probe is defensive and never throws.
|
|
202
|
+
*/
|
|
203
|
+
export function loadOpenshellCard(input) {
|
|
204
|
+
const env = input.env ?? process.env;
|
|
205
|
+
const activity = aggregateOpenshellEvents(input.events);
|
|
206
|
+
const sandboxes = openshellSandboxRows(input.cwd);
|
|
207
|
+
const cli = resolveOpenshellCli(env);
|
|
208
|
+
const safe06Row = input.certify?.requirements.find((r) => r.id === "SAFE-06");
|
|
209
|
+
const runtime = {
|
|
210
|
+
cliFound: cli !== undefined,
|
|
211
|
+
cliVersion: cli ? probeOpenshellVersion(cli, env) : undefined,
|
|
212
|
+
containerRuntime: containerRuntimeOnPath(env),
|
|
213
|
+
minVersion: OPENSHELL_MIN_VERSION,
|
|
214
|
+
proverFound: resolveOpenshellProver(env) !== undefined,
|
|
215
|
+
safe06: safe06Row ? { status: safe06Row.status, evidence: safe06Row.evidence } : undefined,
|
|
216
|
+
};
|
|
217
|
+
return { activity, sandboxes, runtime };
|
|
218
|
+
}
|
|
219
|
+
//# sourceMappingURL=openshell-card.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openshell-card.js","sourceRoot":"","sources":["../../src/receipt/openshell-card.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,7 @@ import { type OtelStats } from "../otel/stats.js";
|
|
|
6
6
|
import { type CertifyCard, type DiscoveryCard, type OrrCard, type SandboxCard, type WiredHostRow } from "./enrich.js";
|
|
7
7
|
import { type ShowbackReport } from "../showback/cost-per-task.js";
|
|
8
8
|
import { type GatePage } from "./gate-page.js";
|
|
9
|
+
import { type OpenshellCard } from "./openshell-card.js";
|
|
9
10
|
export declare const PAGE_SIZE = 50;
|
|
10
11
|
export declare function clampPage(page: number, total: number): number;
|
|
11
12
|
export interface ReceiptModel {
|
|
@@ -33,6 +34,8 @@ export interface ReceiptModel {
|
|
|
33
34
|
readonly identity?: KyaFileConfig;
|
|
34
35
|
/** Sandbox state + configured KYA_SANDBOX backend. */
|
|
35
36
|
readonly sandboxes?: SandboxCard;
|
|
37
|
+
/** OpenShell rollup: trail events, openshell sandboxes, detected CLI/prover. */
|
|
38
|
+
readonly openshell?: OpenshellCard;
|
|
36
39
|
/** Per-host wiring status across the connect registry. */
|
|
37
40
|
readonly wiredHosts?: readonly WiredHostRow[];
|
|
38
41
|
/** Local gateway state + per-server activity in the window. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render-receipt.d.ts","sourceRoot":"","sources":["../../src/receipt/render-receipt.ts"],"names":[],"mappings":"AAUA,OAAO,EAA2C,KAAK,UAAU,EAA6C,MAAM,aAAa,CAAC;AAElI,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAiB,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAQL,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,OAAO,EACZ,KAAK,WAAW,EAChB,KAAK,YAAY,EAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAEL,KAAK,cAAc,EACpB,MAAM,8BAA8B,CAAC;AAItC,OAAO,EAML,KAAK,QAAQ,EACd,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"render-receipt.d.ts","sourceRoot":"","sources":["../../src/receipt/render-receipt.ts"],"names":[],"mappings":"AAUA,OAAO,EAA2C,KAAK,UAAU,EAA6C,MAAM,aAAa,CAAC;AAElI,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAiB,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAQL,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,OAAO,EACZ,KAAK,WAAW,EAChB,KAAK,YAAY,EAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAEL,KAAK,cAAc,EACpB,MAAM,8BAA8B,CAAC;AAItC,OAAO,EAML,KAAK,QAAQ,EACd,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAyC,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEhG,eAAO,MAAM,SAAS,KAAK,CAAC;AAE5B,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAI7D;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,CAAC;IACvC,QAAQ,CAAC,KAAK,CAAC,EAAE;QACf,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;KAC/B,CAAC;IACF,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACpF,gEAAgE;IAChE,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,iFAAiF;IACjF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,mDAAmD;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,2DAA2D;IAC3D,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,uEAAuE;IACvE,QAAQ,CAAC,QAAQ,CAAC,EAAE,aAAa,CAAC;IAClC,sDAAsD;IACtD,QAAQ,CAAC,SAAS,CAAC,EAAE,WAAW,CAAC;IACjC,gFAAgF;IAChF,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,CAAC;IACnC,0DAA0D;IAC1D,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IAC9C,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC;IACzB,iDAAiD;IACjD,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC;IACvB,sEAAsE;IACtE,QAAQ,CAAC,OAAO,CAAC,EAAE,WAAW,CAAC;IAC/B,kDAAkD;IAClD,QAAQ,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAC;IACnC,4EAA4E;IAC5E,QAAQ,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC;IAC9B,0EAA0E;IAC1E,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,CAAC;IACnC,0EAA0E;IAC1E,QAAQ,CAAC,WAAW,CAAC,EAAE,kBAAkB,CAAC;IAC1C,mEAAmE;IACnE,QAAQ,CAAC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IACnC,gEAAgE;IAChE,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC;CAC3B;AAsGD,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAE/D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,mCAAmC;IACnC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;CAC9B;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,0EAA0E;IAC1E,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9F,QAAQ,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACpE,iCAAiC;IACjC,QAAQ,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC/C,mCAAmC;IACnC,QAAQ,CAAC,OAAO,EAAE,SAAS,QAAQ,EAAE,CAAC;IACtC,6EAA6E;IAC7E,QAAQ,CAAC,QAAQ,EAAE,SAAS,QAAQ,EAAE,CAAC;IACvC,2DAA2D;IAC3D,QAAQ,CAAC,QAAQ,EAAE,SAAS,QAAQ,EAAE,CAAC;IACvC,yEAAyE;IACzE,QAAQ,CAAC,OAAO,EAAE,SAAS,QAAQ,EAAE,CAAC;CACvC;AAED,4EAA4E;AAC5E,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,GAAG,eAAe,CA6E9E;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,gEAAgE;AAChE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,SAAS,eAAe,EAAE,CAAC;IAC7C,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAWD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,GAAG,UAAU,GAAG,SAAS,CAsBtF;AAED,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,SAAS,UAAU,EAAE,EAC7B,MAAM,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,GAAG,QAAQ,GAAG,aAAa,GAAG,YAAY,CAAC,CAAC,GACtF,YAAY,CA2Bd;AAED,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,SAAS,UAAU,EAAE,EAC7B,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,GAAG,QAAQ,GAAG,aAAa,GAAG,YAAY,CAAC,CAAC,GACtF,YAAY,CA2Bd;AAED,uEAAuE;AACvE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE;IACtC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CAClC,GAAG,YAAY,CAyCf;AA20CD,wBAAgB,eAAe,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAqClF;AA4OD,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;CAC7C;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,cAAc,CAC5B,MAAM,EAAE,SAAS,UAAU,EAAE,EAC7B,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,OAAO,EACb,KAAK,CAAC,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAC1C,cAAc,CAAC,EAAE,MAAM,EAAE,GACxB,cAAc,CA+BhB;AA6BD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CA8uB7D;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAuUjE"}
|
|
@@ -17,6 +17,7 @@ import { buildChangesModel } from "./changes.js";
|
|
|
17
17
|
import { GATE_NOT_SETUP_QUICKSTART, loadGatePage, toolNameFromToolId, toolServerPrefix, } from "./gate-page.js";
|
|
18
18
|
import { receiptCss } from "./receipt-css.js";
|
|
19
19
|
import { applyChipFilters, rankEvents } from "./search.js";
|
|
20
|
+
import { emptyOpenshellCard, loadOpenshellCard } from "./openshell-card.js";
|
|
20
21
|
export const PAGE_SIZE = 50;
|
|
21
22
|
export function clampPage(page, total) {
|
|
22
23
|
if (total === 0)
|
|
@@ -264,6 +265,7 @@ export function buildReceiptModel(sessionId, events, extras) {
|
|
|
264
265
|
searchQuery: extras?.searchQuery,
|
|
265
266
|
identity: extras?.identity,
|
|
266
267
|
sandboxes: extras?.sandboxes,
|
|
268
|
+
openshell: extras?.openshell,
|
|
267
269
|
wiredHosts: extras?.wiredHosts,
|
|
268
270
|
gate: extras?.gate,
|
|
269
271
|
orr: extras?.orr,
|
|
@@ -291,6 +293,7 @@ export function buildWindowReceiptModel(events, days, extras) {
|
|
|
291
293
|
searchQuery: extras?.searchQuery,
|
|
292
294
|
identity: extras?.identity,
|
|
293
295
|
sandboxes: extras?.sandboxes,
|
|
296
|
+
openshell: extras?.openshell,
|
|
294
297
|
wiredHosts: extras?.wiredHosts,
|
|
295
298
|
gate: extras?.gate,
|
|
296
299
|
orr: extras?.orr,
|
|
@@ -313,7 +316,9 @@ export function loadReceiptModel(input) {
|
|
|
313
316
|
: readTrailSince(input.cwd, new Date(Date.now() - days * 24 * 60 * 60 * 1000), env);
|
|
314
317
|
// The Import card aggregates the full trail, not just the window: imported
|
|
315
318
|
// spans keep their foreign timestamps and would fall out of a short window.
|
|
319
|
+
// The OpenShell card rolls up the same full-trail view for the same reason.
|
|
316
320
|
const importEvents = input.sessionId ? events : readTrail(input.cwd, env);
|
|
321
|
+
const certify = loadCertifyCard(input.cwd);
|
|
317
322
|
const extras = {
|
|
318
323
|
page: input.page ?? 1,
|
|
319
324
|
live: input.live,
|
|
@@ -321,10 +326,11 @@ export function loadReceiptModel(input) {
|
|
|
321
326
|
searchQuery: input.searchQuery,
|
|
322
327
|
identity: loadIdentity(input.cwd),
|
|
323
328
|
sandboxes: loadSandboxes(input.cwd),
|
|
329
|
+
openshell: loadOpenshellCard({ cwd: input.cwd, events: importEvents, env, certify }),
|
|
324
330
|
wiredHosts: loadWiredHosts(input.cwd),
|
|
325
331
|
gate: loadGatePage(events),
|
|
326
332
|
orr: loadOrrCard(input.cwd),
|
|
327
|
-
certify
|
|
333
|
+
certify,
|
|
328
334
|
showback,
|
|
329
335
|
imports: aggregateImports(importEvents),
|
|
330
336
|
discovery: loadDiscoveryCard(env),
|
|
@@ -689,6 +695,112 @@ function wiredHostsPanel(hosts) {
|
|
|
689
695
|
</ul>
|
|
690
696
|
</section>`;
|
|
691
697
|
}
|
|
698
|
+
/**
|
|
699
|
+
* Always-on Capabilities panel: the index of everything this kya install
|
|
700
|
+
* supports, each row showing live status (green) or availability (neutral)
|
|
701
|
+
* plus the exact command or config that turns it on. This is the dashboard
|
|
702
|
+
* half of the self-service rule in docs/report-design.md: a capability a user
|
|
703
|
+
* cannot see is a capability that does not exist, so this panel renders even
|
|
704
|
+
* on a fresh install with zero data anywhere. Status is derived only from
|
|
705
|
+
* fields already on the model; it never triggers probes or IO of its own.
|
|
706
|
+
*/
|
|
707
|
+
function capabilitiesPanel(model) {
|
|
708
|
+
const os = model.openshell;
|
|
709
|
+
const osLive = (os?.activity?.total ?? 0) > 0 || (os?.sandboxes.length ?? 0) > 0 || os?.runtime.cliFound === true || os?.runtime.proverFound === true;
|
|
710
|
+
const gateState = model.gate?.state;
|
|
711
|
+
const rows = [
|
|
712
|
+
{
|
|
713
|
+
name: "MCP gateway",
|
|
714
|
+
blurb: "Govern and audit tool calls to any MCP server",
|
|
715
|
+
live: gateState === "running",
|
|
716
|
+
liveLabel: gateState === "configured-stopped" ? "configured" : "running",
|
|
717
|
+
setup: "<code>kya gate init</code>",
|
|
718
|
+
},
|
|
719
|
+
{
|
|
720
|
+
name: "OpenShell sandboxing",
|
|
721
|
+
blurb: "NVIDIA OpenShell policy-enforced agent sandboxes",
|
|
722
|
+
live: osLive,
|
|
723
|
+
liveLabel: "in use",
|
|
724
|
+
setup: '<code>kya import --from openshell FILE</code> or install the openshell CLI',
|
|
725
|
+
},
|
|
726
|
+
{
|
|
727
|
+
name: "Sandboxes",
|
|
728
|
+
blurb: "Firecracker or mock isolated execution for tool calls",
|
|
729
|
+
live: (model.sandboxes?.sandboxes.length ?? 0) > 0 || !!model.sandboxes?.backend,
|
|
730
|
+
liveLabel: "in use",
|
|
731
|
+
setup: "<code>KYA_SANDBOX=mock kya sandbox spawn</code>",
|
|
732
|
+
},
|
|
733
|
+
{
|
|
734
|
+
name: "Trace imports",
|
|
735
|
+
blurb: "LangSmith, Langfuse, Phoenix, OTel, AGT, ADR Sensor, OpenShell",
|
|
736
|
+
live: (model.imports?.total ?? 0) > 0,
|
|
737
|
+
liveLabel: `${model.imports?.total ?? 0} imported`,
|
|
738
|
+
setup: "<code>kya import --from langsmith FILE</code>",
|
|
739
|
+
},
|
|
740
|
+
{
|
|
741
|
+
name: "Endpoint discovery",
|
|
742
|
+
blurb: "Inventory AI agents, IDEs, runtimes and MCP servers on this machine",
|
|
743
|
+
live: !!model.discovery,
|
|
744
|
+
liveLabel: `${model.discovery?.total ?? 0} found`,
|
|
745
|
+
setup: "<code>kya discover</code>",
|
|
746
|
+
},
|
|
747
|
+
{
|
|
748
|
+
name: "Investigation",
|
|
749
|
+
blurb: "Deterministic trail analysis with grouped incidents",
|
|
750
|
+
live: !!model.investigate,
|
|
751
|
+
liveLabel: "ran",
|
|
752
|
+
setup: "<code>kya investigate</code>",
|
|
753
|
+
},
|
|
754
|
+
{
|
|
755
|
+
name: "Alerts",
|
|
756
|
+
blurb: "Webhooks on DENY and REQUIRE_APPROVE verdicts",
|
|
757
|
+
live: !!model.alerts,
|
|
758
|
+
liveLabel: "configured",
|
|
759
|
+
setup: '<code>notify.webhooks</code> in .kya/config.json',
|
|
760
|
+
},
|
|
761
|
+
{
|
|
762
|
+
name: "OTel export",
|
|
763
|
+
blurb: "Mirror verdict events to any OTLP/HTTP collector",
|
|
764
|
+
live: !!model.otel,
|
|
765
|
+
liveLabel: "exporting",
|
|
766
|
+
setup: '<code>otlpExport.endpoint</code> in .kya/config.json',
|
|
767
|
+
},
|
|
768
|
+
{
|
|
769
|
+
name: "Certify baseline",
|
|
770
|
+
blurb: "Agent Trust Baseline gap report from local evidence",
|
|
771
|
+
live: !!model.certify,
|
|
772
|
+
liveLabel: "evaluated",
|
|
773
|
+
setup: "<code>kya certify</code>",
|
|
774
|
+
},
|
|
775
|
+
{
|
|
776
|
+
name: "ORR board",
|
|
777
|
+
blurb: "Operational readiness review across producers",
|
|
778
|
+
live: !!model.orr,
|
|
779
|
+
liveLabel: "ran",
|
|
780
|
+
setup: "<code>kya orr run</code>",
|
|
781
|
+
},
|
|
782
|
+
];
|
|
783
|
+
const body = rows
|
|
784
|
+
.map((r) => ` <tr>
|
|
785
|
+
<td><strong>${esc(r.name)}</strong></td>
|
|
786
|
+
<td>${esc(r.blurb)}</td>
|
|
787
|
+
<td>${r.live
|
|
788
|
+
? `<span class="pill ok">${esc(r.liveLabel)}</span>`
|
|
789
|
+
: '<span class="pill">available</span>'}</td>
|
|
790
|
+
<td class="mute small">${r.setup}</td>
|
|
791
|
+
</tr>`)
|
|
792
|
+
.join("\n");
|
|
793
|
+
return `<section class="panel" id="capabilities" aria-label="Capabilities">
|
|
794
|
+
<h2>Capabilities</h2>
|
|
795
|
+
<p class="mute small">Everything this install supports. Rows turn green as each capability is used; <span class="pill">available</span> rows name the command that activates them.</p>
|
|
796
|
+
<table class="tbl">
|
|
797
|
+
<thead><tr><th>Capability</th><th>What it does</th><th>Status</th><th>Turn it on</th></tr></thead>
|
|
798
|
+
<tbody>
|
|
799
|
+
${body}
|
|
800
|
+
</tbody>
|
|
801
|
+
</table>
|
|
802
|
+
</section>`;
|
|
803
|
+
}
|
|
692
804
|
/**
|
|
693
805
|
* System-tab gateway summary: a single status row that links to the dedicated
|
|
694
806
|
* Gateway section. Detail lives in the Gateway pages so the System tab stays
|
|
@@ -1063,6 +1175,89 @@ ${card.sandboxes
|
|
|
1063
1175
|
${tbl}
|
|
1064
1176
|
</section>`;
|
|
1065
1177
|
}
|
|
1178
|
+
/**
|
|
1179
|
+
* System-tab OpenShell panel (NVIDIA OpenShell): policy activity from
|
|
1180
|
+
* imported openshell trail events, openshell-backend sandbox rows with their
|
|
1181
|
+
* on-disk policy-file status, and a runtime card probing the openshell CLI
|
|
1182
|
+
* (version cached, probed once per report build), the container runtime, the
|
|
1183
|
+
* pinned version floor, the openshell-prover binary, and the SAFE-06 certify
|
|
1184
|
+
* outcome reused from the already-computed certify card. Always rendered: with
|
|
1185
|
+
* no OpenShell signal yet the activity and sandbox blocks fall back to empty
|
|
1186
|
+
* states that name the exact command to activate them, so the capability stays
|
|
1187
|
+
* discoverable from the dashboard itself (docs/report-design.md).
|
|
1188
|
+
*/
|
|
1189
|
+
function openshellPanel(card, nowMs) {
|
|
1190
|
+
const c = card ?? emptyOpenshellCard();
|
|
1191
|
+
const activity = c.activity
|
|
1192
|
+
? `<div class="card">
|
|
1193
|
+
<h3>Policy activity</h3>
|
|
1194
|
+
<div class="kpi-row">
|
|
1195
|
+
${kpiTile("Events", c.activity.total)}
|
|
1196
|
+
${kpiTile("Denied", c.activity.deny, "bad")}
|
|
1197
|
+
${kpiTile("Allowed", c.activity.allow)}
|
|
1198
|
+
</div>
|
|
1199
|
+
<div class="orrline">
|
|
1200
|
+
<span class="pill${c.activity.deny > 0 ? " bad" : ""}">DENY ${c.activity.deny}</span>
|
|
1201
|
+
<span class="pill ok">ALLOW ${c.activity.allow}</span>
|
|
1202
|
+
<span class="mute">network ${c.activity.network} · http ${c.activity.http}</span>
|
|
1203
|
+
</div>
|
|
1204
|
+
${c.activity.topDestinations.length === 0
|
|
1205
|
+
? ""
|
|
1206
|
+
: `<div class="chiprow">
|
|
1207
|
+
${c.activity.topDestinations
|
|
1208
|
+
.map((d) => `<span class="chip"><code>${esc(clip(d.dst, 60))}</code> × ${d.count}</span>`)
|
|
1209
|
+
.join("\n ")}
|
|
1210
|
+
</div>`}
|
|
1211
|
+
<p class="mute small">last event ${c.activity.lastTs ? esc(relativeTime(c.activity.lastTs, nowMs)) : "unknown"}</p>
|
|
1212
|
+
</div>`
|
|
1213
|
+
: `<p class="empty small">No OpenShell policy events on the trail. Import an export with <code>kya import --from openshell FILE</code>.</p>`;
|
|
1214
|
+
const sandboxTbl = c.sandboxes.length === 0
|
|
1215
|
+
? `<p class="empty small">No openshell-backend sandboxes recorded. Spawn one with <code>KYA_SANDBOX=openshell kya sandbox spawn</code>.</p>`
|
|
1216
|
+
: `<table class="tbl">
|
|
1217
|
+
<thead><tr><th>id</th><th>status</th><th>name</th><th>created</th><th>policy</th></tr></thead>
|
|
1218
|
+
<tbody>
|
|
1219
|
+
${c.sandboxes
|
|
1220
|
+
.map((s) => ` <tr>
|
|
1221
|
+
<td><code title="${esc(s.sandboxId)}">${esc(clip(s.sandboxId, 20))}</code></td>
|
|
1222
|
+
<td><span class="pill ${s.status === "running" ? "ok" : "mute"}">${esc(s.status)}</span></td>
|
|
1223
|
+
<td>${s.externalName ? `<code>${esc(clip(s.externalName, 40))}</code>` : '<span class="mute">-</span>'}</td>
|
|
1224
|
+
<td>${esc(relativeTime(s.createdAt, nowMs))}</td>
|
|
1225
|
+
<td><span class="pill ${s.policyFile ? "ok" : "mute"}">${s.policyFile ? "written" : "missing"}</span></td>
|
|
1226
|
+
</tr>`)
|
|
1227
|
+
.join("\n")}
|
|
1228
|
+
</tbody>
|
|
1229
|
+
</table>`;
|
|
1230
|
+
const rt = c.runtime;
|
|
1231
|
+
const cliLine = rt.cliFound
|
|
1232
|
+
? `<p class="line">openshell CLI <span class="pill ok">found</span>${rt.cliVersion
|
|
1233
|
+
? ` <code>${esc(clip(rt.cliVersion, 40))}</code>`
|
|
1234
|
+
: ' <span class="mute">version probe failed</span>'}</p>`
|
|
1235
|
+
: `<p class="line">openshell CLI <span class="pill">not detected</span></p>`;
|
|
1236
|
+
const runtimeLine = rt.containerRuntime
|
|
1237
|
+
? `<span class="pill ok">${esc(rt.containerRuntime)}</span>`
|
|
1238
|
+
: `<span class="pill">not detected</span>`;
|
|
1239
|
+
const proverLine = rt.proverFound
|
|
1240
|
+
? `<p class="line">openshell-prover <span class="pill ok">found</span></p>`
|
|
1241
|
+
: `<p class="line">openshell-prover <span class="pill">not detected</span></p>`;
|
|
1242
|
+
const safe06Tone = rt.safe06 ? DETAIL_PILL_TONE[rt.safe06.status] ?? "" : "";
|
|
1243
|
+
const safe06Line = rt.safe06
|
|
1244
|
+
? `<p class="line">SAFE-06 (openshell-prover) <span class="pill${safe06Tone ? ` ${safe06Tone}` : ""}">${esc(rt.safe06.status.replace(/_/g, " "))}</span> <span class="mute">${esc(clip(rt.safe06.evidence, 120))}</span></p>`
|
|
1245
|
+
: `<p class="line">SAFE-06 (openshell-prover) <span class="mute">not evaluated by Certify yet</span></p>`;
|
|
1246
|
+
const runtime = `<div class="card">
|
|
1247
|
+
<h3>Runtime</h3>
|
|
1248
|
+
${cliLine}
|
|
1249
|
+
<p class="line">container runtime ${runtimeLine} <span class="mute">minimum ${esc(rt.minVersion)}</span></p>
|
|
1250
|
+
${proverLine}
|
|
1251
|
+
${safe06Line}
|
|
1252
|
+
</div>`;
|
|
1253
|
+
return `<section class="panel" aria-label="OpenShell">
|
|
1254
|
+
<h2>OpenShell</h2>
|
|
1255
|
+
${activity}
|
|
1256
|
+
<h3>Sandboxes</h3>
|
|
1257
|
+
${sandboxTbl}
|
|
1258
|
+
${runtime}
|
|
1259
|
+
</section>`;
|
|
1260
|
+
}
|
|
1066
1261
|
function orrPanel(orr, nowMs) {
|
|
1067
1262
|
if (!orr)
|
|
1068
1263
|
return "";
|
|
@@ -1507,7 +1702,7 @@ function alertsPanel(card, nowMs, live) {
|
|
|
1507
1702
|
return `<section class="panel" aria-label="Alerts">
|
|
1508
1703
|
<h2>Alerts</h2>
|
|
1509
1704
|
<p class="line">No alert deliveries yet. kya fires webhooks for DENY and REQUIRE_APPROVE verdicts; every delivery attempt is logged here per target.</p>
|
|
1510
|
-
<p class="mute small">configure <code>notify.webhooks</code> in .kya/config.json or set <code>KYA_NOTIFY_WEBHOOK</code
|
|
1705
|
+
<p class="mute small">send a test alert to see the pipeline work (it uses a temporary loopback receiver until you configure <code>notify.webhooks</code> in .kya/config.json or set <code>KYA_NOTIFY_WEBHOOK</code>)</p>
|
|
1511
1706
|
${test}
|
|
1512
1707
|
</section>`;
|
|
1513
1708
|
}
|
|
@@ -1551,7 +1746,7 @@ function otelPanel(stats, nowMs, live) {
|
|
|
1551
1746
|
return `<section class="panel" aria-label="OTel export">
|
|
1552
1747
|
<h2>OTel export</h2>
|
|
1553
1748
|
<p class="line">No spans exported yet. kya can mirror verdict events to any OTLP/HTTP collector; sent and failed counts are tracked here.</p>
|
|
1554
|
-
<p class="mute small">configure <code>otlpExport.endpoint</code> in .kya/config.json or set <code>KYA_OTLP_EXPORT_ENDPOINT</code
|
|
1749
|
+
<p class="mute small">test the export now (it uses a temporary loopback collector until you configure <code>otlpExport.endpoint</code> in .kya/config.json or set <code>KYA_OTLP_EXPORT_ENDPOINT</code>)</p>
|
|
1555
1750
|
${test}
|
|
1556
1751
|
</section>`;
|
|
1557
1752
|
}
|
|
@@ -2160,7 +2355,7 @@ export function renderReceiptHtml(model) {
|
|
|
2160
2355
|
: action === 'discover'
|
|
2161
2356
|
? 'Done: ' + data.total + ' item(s) discovered'
|
|
2162
2357
|
: action === 'notify-test'
|
|
2163
|
-
? 'Test alert sent to ' + data.targets + ' target(s)'
|
|
2358
|
+
? (data.detail ? String(data.detail) : 'Test alert sent to ' + data.targets + ' target(s)')
|
|
2164
2359
|
: String(data.detail || 'ok');
|
|
2165
2360
|
setResult(resultEl, '<p>' + esc(msg) + '</p>', false);
|
|
2166
2361
|
if (action === 'otel-test') {
|
|
@@ -2243,9 +2438,11 @@ export function renderReceiptHtml(model) {
|
|
|
2243
2438
|
const overviewBody = zoneBody([dashboardPanel(dashboard), sessionsPanel(agg, nowMs, changes), reasonsPanel(agg)], "No activity in this window yet - analytics appear once events land.");
|
|
2244
2439
|
const certifyBody = zoneBody([model.certify ? certifyDetailPanel(model.certify.requirements) : ""], "No live evaluation yet - wrap tool calls and run kya certify to build the baseline.");
|
|
2245
2440
|
const systemBody = zoneBody([
|
|
2441
|
+
capabilitiesPanel(model),
|
|
2246
2442
|
gatePanel(model.gate, nowMs),
|
|
2247
2443
|
wiredHostsPanel(model.wiredHosts),
|
|
2248
2444
|
sandboxesPanel(model.sandboxes, nowMs),
|
|
2445
|
+
openshellPanel(model.openshell, nowMs),
|
|
2249
2446
|
orrPanel(model.orr, nowMs),
|
|
2250
2447
|
alertsPanel(model.alerts, nowMs, livePaged),
|
|
2251
2448
|
otelPanel(model.otel, nowMs, livePaged),
|