skillscript-runtime 0.18.8 → 0.19.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 +2 -2
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +41 -5
- package/dist/bootstrap.js.map +1 -1
- package/dist/cli.js +13 -0
- package/dist/cli.js.map +1 -1
- package/dist/connectors/agent.d.ts +6 -2
- package/dist/connectors/agent.d.ts.map +1 -1
- package/dist/connectors/types.d.ts +2 -8
- package/dist/connectors/types.d.ts.map +1 -1
- package/dist/connectors/types.js.map +1 -1
- package/dist/dashboard/server.d.ts +49 -0
- package/dist/dashboard/server.d.ts.map +1 -1
- package/dist/dashboard/server.js +108 -0
- package/dist/dashboard/server.js.map +1 -1
- package/dist/dashboard/spa/app.js +219 -2
- package/dist/dashboard/spa/index.html +1 -0
- package/dist/dashboard/spa/styles.css +39 -0
- package/dist/errors.d.ts +25 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +48 -2
- package/dist/errors.js.map +1 -1
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +57 -3
- package/dist/mcp-server.js.map +1 -1
- package/dist/parser.d.ts +1 -1
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +4 -4
- package/dist/parser.js.map +1 -1
- package/dist/runtime.d.ts +10 -0
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +1 -1
- package/dist/runtime.js.map +1 -1
- package/dist/scheduler.d.ts +54 -11
- package/dist/scheduler.d.ts.map +1 -1
- package/dist/scheduler.js +103 -33
- package/dist/scheduler.js.map +1 -1
- package/dist/skill-catalog.js +7 -11
- package/dist/skill-catalog.js.map +1 -1
- package/dist/trace.d.ts +9 -1
- package/dist/trace.d.ts.map +1 -1
- package/dist/trace.js +10 -2
- package/dist/trace.js.map +1 -1
- package/docs/adopter-playbook.md +147 -0
- package/docs/configuration.md +3 -1
- package/examples/skillscripts/hello-world.skill.provenance.json +1 -1
- package/package.json +1 -1
- package/scaffold/.env.example +22 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/dashboard/server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAU,MAAM,WAAW,CAAC;AAKzE,OAAO,KAAK,EAAE,SAAS,EAAkB,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/dashboard/server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAU,MAAM,WAAW,CAAC;AAKzE,OAAO,KAAK,EAAE,SAAS,EAAkB,MAAM,kBAAkB,CAAC;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAGjD;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,SAAS,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8GAA8G;IAC9G,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;;;;;;;;;;;;;OAkBG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC;;;;;;;;;OASG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;;;;OAOG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AASD,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAU;IACnC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAqB;IAC1D,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAU;IAC9C,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAqB;IAC3D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwB;IAClD,OAAO,CAAC,UAAU,CAAuB;gBAE7B,MAAM,EAAE,qBAAqB;IAmBnC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAStB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAO3B,yEAAyE;IACnE,MAAM,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAiDtE;;;;;;;;;;;;;;;OAeG;YACW,WAAW;YA8DX,SAAS;YAkCT,YAAY;CAkB3B"}
|
package/dist/dashboard/server.js
CHANGED
|
@@ -3,6 +3,7 @@ import { readFile } from "node:fs/promises";
|
|
|
3
3
|
import { existsSync } from "node:fs";
|
|
4
4
|
import { extname, join, resolve, dirname } from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { EventNotFoundError, EventParamMismatchError } from "../errors.js";
|
|
6
7
|
const MIME = {
|
|
7
8
|
".html": "text/html; charset=utf-8",
|
|
8
9
|
".js": "application/javascript; charset=utf-8",
|
|
@@ -16,6 +17,9 @@ export class DashboardServer {
|
|
|
16
17
|
assetsDir;
|
|
17
18
|
mountSpa;
|
|
18
19
|
callerIdentityHeader;
|
|
20
|
+
eventIngressEnabled;
|
|
21
|
+
eventIngressAuthToken;
|
|
22
|
+
scheduler;
|
|
19
23
|
httpServer = null;
|
|
20
24
|
constructor(config) {
|
|
21
25
|
this.mcpServer = config.mcpServer;
|
|
@@ -27,6 +31,13 @@ export class DashboardServer {
|
|
|
27
31
|
// configured name once at constructor time so per-request lookup is
|
|
28
32
|
// a single Map access (req.headers[<lowercased-name>]).
|
|
29
33
|
this.callerIdentityHeader = config.mcpCallerIdentityHeader?.toLowerCase();
|
|
34
|
+
// v0.19.0 — event ingress configuration (memory `ceaf4579`).
|
|
35
|
+
this.eventIngressEnabled = config.eventIngressEnabled ?? false;
|
|
36
|
+
this.eventIngressAuthToken = config.eventIngressAuthToken;
|
|
37
|
+
this.scheduler = config.scheduler;
|
|
38
|
+
if (this.eventIngressEnabled && this.scheduler === undefined) {
|
|
39
|
+
throw new Error("DashboardServer: eventIngressEnabled requires a scheduler reference");
|
|
40
|
+
}
|
|
30
41
|
}
|
|
31
42
|
async start() {
|
|
32
43
|
this.httpServer = createServer((req, res) => {
|
|
@@ -59,6 +70,23 @@ export class DashboardServer {
|
|
|
59
70
|
await this.handleRpc(req, res);
|
|
60
71
|
return;
|
|
61
72
|
}
|
|
73
|
+
// v0.19.0 — POST /event for external HTTP-triggered skills.
|
|
74
|
+
// Off-by-default per memory `ceaf4579`; returns 404 when not
|
|
75
|
+
// enabled (operator hasn't opted in).
|
|
76
|
+
if (url.pathname === "/event") {
|
|
77
|
+
if (!this.eventIngressEnabled) {
|
|
78
|
+
res.statusCode = 404;
|
|
79
|
+
res.end("Not Found (event ingress disabled)");
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (req.method !== "POST") {
|
|
83
|
+
res.statusCode = 405;
|
|
84
|
+
res.end("Method Not Allowed");
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
await this.handleEvent(req, res);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
62
90
|
if (req.method === "GET") {
|
|
63
91
|
if (!this.mountSpa) {
|
|
64
92
|
res.statusCode = 404;
|
|
@@ -76,6 +104,86 @@ export class DashboardServer {
|
|
|
76
104
|
res.end(`Internal server error: ${err.message}`);
|
|
77
105
|
}
|
|
78
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* v0.19.0 — POST /event handler (memory `ceaf4579`).
|
|
109
|
+
*
|
|
110
|
+
* Wire contract:
|
|
111
|
+
* - Request body: `{ event_name: string, params: Record<string, unknown> }`
|
|
112
|
+
* - Optional bearer-token auth via `Authorization: Bearer <token>` when
|
|
113
|
+
* `eventIngressAuthToken` configured (401 if missing/wrong)
|
|
114
|
+
* - 200 + `{run_id, durability: "in-process"}` on accept (NOT skill-completed)
|
|
115
|
+
* - 404 if event_name not registered
|
|
116
|
+
* - 400 if params don't match declared (missing or extra)
|
|
117
|
+
*
|
|
118
|
+
* Async semantics: 200 = ACCEPTED into THIS process's in-memory queue.
|
|
119
|
+
* Best-effort / at-most-once / NOT durable across restart. The
|
|
120
|
+
* `durability` field on the response self-describes this — adopters
|
|
121
|
+
* needing at-least-once delivery wrap with their own queue.
|
|
122
|
+
*/
|
|
123
|
+
async handleEvent(req, res) {
|
|
124
|
+
// Auth check first — short-circuit BEFORE body parsing so unauthorized
|
|
125
|
+
// callers don't get to chew through arbitrary bodies.
|
|
126
|
+
if (this.eventIngressAuthToken !== undefined) {
|
|
127
|
+
const auth = req.headers["authorization"];
|
|
128
|
+
const expected = `Bearer ${this.eventIngressAuthToken}`;
|
|
129
|
+
if (typeof auth !== "string" || auth !== expected) {
|
|
130
|
+
res.statusCode = 401;
|
|
131
|
+
res.setHeader("content-type", MIME[".json"]);
|
|
132
|
+
res.end(JSON.stringify({ error: "Unauthorized", reason: "missing or invalid bearer token" }));
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
const chunks = [];
|
|
137
|
+
for await (const chunk of req)
|
|
138
|
+
chunks.push(chunk);
|
|
139
|
+
const body = Buffer.concat(chunks).toString("utf8");
|
|
140
|
+
let parsed;
|
|
141
|
+
try {
|
|
142
|
+
parsed = JSON.parse(body);
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
res.statusCode = 400;
|
|
146
|
+
res.setHeader("content-type", MIME[".json"]);
|
|
147
|
+
res.end(JSON.stringify({ error: "Bad Request", reason: "body is not valid JSON" }));
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
if (typeof parsed.event_name !== "string" || parsed.event_name === "") {
|
|
151
|
+
res.statusCode = 400;
|
|
152
|
+
res.setHeader("content-type", MIME[".json"]);
|
|
153
|
+
res.end(JSON.stringify({ error: "Bad Request", reason: "body must include non-empty 'event_name' string" }));
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
const params = (typeof parsed.params === "object" && parsed.params !== null && !Array.isArray(parsed.params))
|
|
157
|
+
? parsed.params
|
|
158
|
+
: {};
|
|
159
|
+
try {
|
|
160
|
+
const result = this.scheduler.fireEvent(parsed.event_name, params);
|
|
161
|
+
res.statusCode = 200;
|
|
162
|
+
res.setHeader("content-type", MIME[".json"]);
|
|
163
|
+
res.end(JSON.stringify({ ...result, durability: "in-process" }));
|
|
164
|
+
}
|
|
165
|
+
catch (err) {
|
|
166
|
+
if (err instanceof EventNotFoundError) {
|
|
167
|
+
res.statusCode = 404;
|
|
168
|
+
res.setHeader("content-type", MIME[".json"]);
|
|
169
|
+
res.end(JSON.stringify({ error: "Not Found", reason: err.message }));
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
if (err instanceof EventParamMismatchError) {
|
|
173
|
+
res.statusCode = 400;
|
|
174
|
+
res.setHeader("content-type", MIME[".json"]);
|
|
175
|
+
res.end(JSON.stringify({
|
|
176
|
+
error: "Bad Request",
|
|
177
|
+
reason: err.message,
|
|
178
|
+
declared: err.declared,
|
|
179
|
+
missing: err.missing,
|
|
180
|
+
extra: err.extra,
|
|
181
|
+
}));
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
throw err;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
79
187
|
async handleRpc(req, res) {
|
|
80
188
|
const chunks = [];
|
|
81
189
|
for await (const chunk of req)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/dashboard/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/dashboard/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,6 +12,7 @@ const state = {
|
|
|
12
12
|
triggers: [],
|
|
13
13
|
metrics: null,
|
|
14
14
|
capabilities: null,
|
|
15
|
+
blockedShellAttempts: null,
|
|
15
16
|
lastUpdate: null,
|
|
16
17
|
};
|
|
17
18
|
|
|
@@ -42,7 +43,7 @@ async function refresh() {
|
|
|
42
43
|
const ts = new Date();
|
|
43
44
|
document.getElementById("poll-status").textContent = `polling…`;
|
|
44
45
|
try {
|
|
45
|
-
const [catalog, triggers, metrics, capabilities] = await Promise.all([
|
|
46
|
+
const [catalog, triggers, metrics, capabilities, blocked] = await Promise.all([
|
|
46
47
|
// v0.9.8 — skill_list returns SkillCatalog (pre-grouped by audience).
|
|
47
48
|
// Dashboard wants the full picture (all categories); flatten the
|
|
48
49
|
// groups into a single array for the existing rendering code.
|
|
@@ -50,6 +51,10 @@ async function refresh() {
|
|
|
50
51
|
callTool("list_triggers", {}),
|
|
51
52
|
callTool("health_metrics", {}),
|
|
52
53
|
callTool("runtime_capabilities", { include: ["mcpConnectors", "mcpConnectorClasses", "localModels", "dataStores", "skillStores", "agentConnectors", "runtimeVersion"] }),
|
|
54
|
+
// v0.18.9 — blocked shell attempts for the Security view's
|
|
55
|
+
// observe→promote loop. Graceful: pre-v0.18.9 servers don't have
|
|
56
|
+
// this tool; catch returns null and the Security view degrades.
|
|
57
|
+
callTool("blocked_shell_attempts", { limit: 100 }).catch(() => null),
|
|
53
58
|
]);
|
|
54
59
|
state.skills = [
|
|
55
60
|
...(catalog.receives ?? []),
|
|
@@ -59,6 +64,7 @@ async function refresh() {
|
|
|
59
64
|
state.triggers = triggers;
|
|
60
65
|
state.metrics = metrics;
|
|
61
66
|
state.capabilities = capabilities;
|
|
67
|
+
state.blockedShellAttempts = blocked;
|
|
62
68
|
state.lastUpdate = ts;
|
|
63
69
|
document.getElementById("poll-status").textContent = `last updated ${ts.toLocaleTimeString()}`;
|
|
64
70
|
renderCurrentView();
|
|
@@ -201,9 +207,11 @@ async function renderSkillDetail(name) {
|
|
|
201
207
|
</div>
|
|
202
208
|
</section>
|
|
203
209
|
|
|
210
|
+
${source ? renderSecuritySignalsPanel(source) : ""}
|
|
211
|
+
|
|
204
212
|
<section>
|
|
205
213
|
<h2>Source</h2>
|
|
206
|
-
${source ? `<pre>${
|
|
214
|
+
${source ? `<pre class="skill-source">${renderHighlightedSkillBody(source)}</pre>` : `<div class="empty">Source not available.</div>`}
|
|
207
215
|
</section>
|
|
208
216
|
|
|
209
217
|
${renderComposesSection(name, source)}
|
|
@@ -318,6 +326,214 @@ function renderTriggers() {
|
|
|
318
326
|
`;
|
|
319
327
|
}
|
|
320
328
|
|
|
329
|
+
// v0.18.9 — security highlighting in the skill source viewer. Two
|
|
330
|
+
// severity tiers visualized as soft background tints in the <pre> body
|
|
331
|
+
// so a human reviewer can scan-prioritize "what's risky in this skill":
|
|
332
|
+
//
|
|
333
|
+
// HIGH (orange tint) — bypasses human-in-loop OR has unbounded blast radius:
|
|
334
|
+
// - `unsafe=true` kwarg (bash interpretation enabled)
|
|
335
|
+
// - `# Autonomous: true` frontmatter (no human-in-loop)
|
|
336
|
+
// - `approved="..."` kwarg (per-op author authorization)
|
|
337
|
+
// - `$ skill_write`, `$ data_write`, `file_write(...)` (mutation ops)
|
|
338
|
+
//
|
|
339
|
+
// MEDIUM (yellow tint) — touches OS / live-session surfaces:
|
|
340
|
+
// - `shell(...)` ops (OS-level dispatch even when allowlisted)
|
|
341
|
+
// - `notify(agent="X@session", ...)` (wake-class interrupt)
|
|
342
|
+
//
|
|
343
|
+
// Implementation: regex-based annotation pass over the already-esc'd
|
|
344
|
+
// source string. Each pattern wraps its match in a <span class=...>
|
|
345
|
+
// with low-alpha background. Patterns are deliberately conservative —
|
|
346
|
+
// false negatives are fine (the highlight aids scanning, not gating);
|
|
347
|
+
// false positives are worse because they desensitize the reviewer.
|
|
348
|
+
function renderHighlightedSkillBody(source) {
|
|
349
|
+
let body = esc(source);
|
|
350
|
+
// HIGH tier — must apply on the esc'd string, so patterns reference
|
|
351
|
+
// entity-escaped quote chars (e.g., approved="...").
|
|
352
|
+
const highPatterns = [
|
|
353
|
+
// Frontmatter signal: `# Autonomous: true`
|
|
354
|
+
/(^|\n)(# Autonomous:\s*true)/g,
|
|
355
|
+
// Per-op author authorization kwarg
|
|
356
|
+
/(approved="[^&]*")/g,
|
|
357
|
+
// Unsafe shell axis
|
|
358
|
+
/(unsafe\s*=\s*true)/g,
|
|
359
|
+
// Mutation ops (substrate writes + filesystem writes + skill writes)
|
|
360
|
+
/(file_write\s*\()/g,
|
|
361
|
+
/(\$\s*skill_write\b)/g,
|
|
362
|
+
/(\$\s*data_write\b)/g,
|
|
363
|
+
];
|
|
364
|
+
// MEDIUM tier — shell() ops + wake-class notify
|
|
365
|
+
const mediumPatterns = [
|
|
366
|
+
/(shell\s*\()/g,
|
|
367
|
+
/(notify\s*\(\s*agent\s*=\s*"[^&]*@[^&]*")/g,
|
|
368
|
+
];
|
|
369
|
+
for (const re of highPatterns) {
|
|
370
|
+
body = body.replace(re, (_match, p1, p2) => {
|
|
371
|
+
const prefix = p2 !== undefined ? p1 : "";
|
|
372
|
+
const captured = p2 !== undefined ? p2 : p1;
|
|
373
|
+
return `${prefix}<span class="sig-high">${captured}</span>`;
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
for (const re of mediumPatterns) {
|
|
377
|
+
body = body.replace(re, (m) => `<span class="sig-medium">${m}</span>`);
|
|
378
|
+
}
|
|
379
|
+
return body;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// v0.18.9 — security signals summary panel. Glance-first surface
|
|
383
|
+
// showing aggregated counts so a reviewer knows WHAT to look for before
|
|
384
|
+
// scanning the body. Pairs with renderHighlightedSkillBody() (the
|
|
385
|
+
// WHERE).
|
|
386
|
+
function renderSecuritySignalsPanel(source) {
|
|
387
|
+
const sig = collectSecuritySignals(source);
|
|
388
|
+
const items = [];
|
|
389
|
+
if (sig.shellOps > 0) {
|
|
390
|
+
items.push(`<li class="sig-medium-text">${sig.shellOps} shell op${sig.shellOps === 1 ? "" : "s"}${sig.shellBinaries.length > 0 ? ` (binaries: ${sig.shellBinaries.map(esc).join(", ")})` : ""}</li>`);
|
|
391
|
+
}
|
|
392
|
+
if (sig.unsafeShell > 0) {
|
|
393
|
+
items.push(`<li class="sig-high-text">${sig.unsafeShell} unsafe shell op${sig.unsafeShell === 1 ? "" : "s"} <small>(requires <code>SKILLSCRIPT_ENABLE_UNSAFE_SHELL=true</code> AND <code>bash</code> on allowlist)</small></li>`);
|
|
394
|
+
}
|
|
395
|
+
if (sig.autonomous) {
|
|
396
|
+
items.push(`<li class="sig-high-text"><code># Autonomous: true</code> <small>(bypasses human-in-loop on mutation ops)</small></li>`);
|
|
397
|
+
}
|
|
398
|
+
if (sig.approvedOps > 0) {
|
|
399
|
+
items.push(`<li class="sig-high-text">${sig.approvedOps} <code>approved="..."</code> per-op authorization${sig.approvedOps === 1 ? "" : "s"}</li>`);
|
|
400
|
+
}
|
|
401
|
+
if (sig.writeOps > 0) {
|
|
402
|
+
items.push(`<li class="sig-high-text">${sig.writeOps} mutation op${sig.writeOps === 1 ? "" : "s"} <small>(<code>skill_write</code> / <code>data_write</code> / <code>file_write</code>)</small></li>`);
|
|
403
|
+
}
|
|
404
|
+
if (sig.wakeAddresses > 0) {
|
|
405
|
+
items.push(`<li class="sig-medium-text">${sig.wakeAddresses} <code>@session</code> wake-class deliver${sig.wakeAddresses === 1 ? "" : "s"}</li>`);
|
|
406
|
+
}
|
|
407
|
+
if (sig.cronTriggers > 0) {
|
|
408
|
+
items.push(`<li class="sig-info-text">${sig.cronTriggers} cron trigger${sig.cronTriggers === 1 ? "" : "s"} <small>(autonomous fire)</small></li>`);
|
|
409
|
+
}
|
|
410
|
+
if (items.length === 0) return "";
|
|
411
|
+
return `
|
|
412
|
+
<section>
|
|
413
|
+
<h2>Security signals</h2>
|
|
414
|
+
<ul class="security-signals">
|
|
415
|
+
${items.join("")}
|
|
416
|
+
</ul>
|
|
417
|
+
<p><small>Scan the source below — highlighted spans match these signals. <span class="sig-high">Orange</span> = review carefully; <span class="sig-medium">yellow</span> = worth noting.</small></p>
|
|
418
|
+
</section>
|
|
419
|
+
`;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
function collectSecuritySignals(source) {
|
|
423
|
+
const lines = source.split("\n");
|
|
424
|
+
let shellOps = 0;
|
|
425
|
+
let unsafeShell = 0;
|
|
426
|
+
let autonomous = false;
|
|
427
|
+
let approvedOps = 0;
|
|
428
|
+
let writeOps = 0;
|
|
429
|
+
let wakeAddresses = 0;
|
|
430
|
+
let cronTriggers = 0;
|
|
431
|
+
const shellBinaries = new Set();
|
|
432
|
+
for (const line of lines) {
|
|
433
|
+
if (/^# Autonomous:\s*true\s*$/i.test(line)) autonomous = true;
|
|
434
|
+
if (/^# Triggers:\s*cron:/i.test(line)) cronTriggers++;
|
|
435
|
+
const shellMatch = /shell\s*\(\s*command\s*=\s*"([^"]+)"/.exec(line);
|
|
436
|
+
if (shellMatch !== null) {
|
|
437
|
+
shellOps++;
|
|
438
|
+
const cmd = shellMatch[1]!.trim();
|
|
439
|
+
const isUnsafe = /unsafe\s*=\s*true/.test(line);
|
|
440
|
+
if (isUnsafe) {
|
|
441
|
+
unsafeShell++;
|
|
442
|
+
shellBinaries.add("bash");
|
|
443
|
+
} else if (cmd.length > 0 && !cmd.startsWith("${") && !cmd.startsWith("$(")) {
|
|
444
|
+
const binary = /^([^\s]+)/.exec(cmd);
|
|
445
|
+
if (binary !== null) shellBinaries.add(binary[1]!);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
if (/approved\s*=\s*"/.test(line)) approvedOps++;
|
|
449
|
+
if (/\$\s*skill_write\b|\$\s*data_write\b|file_write\s*\(/.test(line)) writeOps++;
|
|
450
|
+
if (/notify\s*\(\s*agent\s*=\s*"[^"]*@[^"]*"/.test(line)) wakeAddresses++;
|
|
451
|
+
}
|
|
452
|
+
return {
|
|
453
|
+
shellOps,
|
|
454
|
+
unsafeShell,
|
|
455
|
+
autonomous,
|
|
456
|
+
approvedOps,
|
|
457
|
+
writeOps,
|
|
458
|
+
wakeAddresses,
|
|
459
|
+
cronTriggers,
|
|
460
|
+
shellBinaries: [...shellBinaries].sort(),
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// v0.18.9 — Security view. Cross-skill observability for the shell
|
|
465
|
+
// allowlist's observe→promote loop. Operator sees what binaries skills
|
|
466
|
+
// tried to invoke off-list; decides whether to add any to .env.
|
|
467
|
+
function renderSecurity() {
|
|
468
|
+
const blocked = state.blockedShellAttempts;
|
|
469
|
+
if (blocked === null) {
|
|
470
|
+
return `
|
|
471
|
+
<section>
|
|
472
|
+
<h2>Security</h2>
|
|
473
|
+
<div class="empty">
|
|
474
|
+
<strong>blocked_shell_attempts tool unavailable.</strong>
|
|
475
|
+
The runtime serving this dashboard is pre-v0.18.9 and doesn't expose the
|
|
476
|
+
blocked-attempts query surface. Upgrade to v0.18.9+ to see what shell
|
|
477
|
+
binaries skills tried to invoke off the allowlist.
|
|
478
|
+
</div>
|
|
479
|
+
</section>
|
|
480
|
+
`;
|
|
481
|
+
}
|
|
482
|
+
const attempts = blocked.attempts ?? [];
|
|
483
|
+
// Group by binary for the "what should I consider adding?" angle.
|
|
484
|
+
const byBinary = {};
|
|
485
|
+
for (const a of attempts) {
|
|
486
|
+
if (!byBinary[a.binary]) byBinary[a.binary] = { count: 0, skills: new Set(), latest: 0 };
|
|
487
|
+
byBinary[a.binary].count++;
|
|
488
|
+
byBinary[a.binary].skills.add(a.skill_name);
|
|
489
|
+
if (a.fired_at_ms > byBinary[a.binary].latest) byBinary[a.binary].latest = a.fired_at_ms;
|
|
490
|
+
}
|
|
491
|
+
const groups = Object.entries(byBinary).sort((a, b) => b[1].count - a[1].count);
|
|
492
|
+
return `
|
|
493
|
+
<section>
|
|
494
|
+
<h2>Security · Blocked shell attempts</h2>
|
|
495
|
+
<p>
|
|
496
|
+
Skills attempted these shell binaries; the runtime refused each because
|
|
497
|
+
the binary isn't in <code>SKILLSCRIPT_SHELL_ALLOWLIST</code>. Review the
|
|
498
|
+
list — add any you intended to permit to your <code>.env</code>, then
|
|
499
|
+
restart the runtime. Run <code>skillfile shell-audit</code> from the
|
|
500
|
+
CLI to scan the full corpus instead of the recent trace window.
|
|
501
|
+
</p>
|
|
502
|
+
${attempts.length === 0
|
|
503
|
+
? `<div class="empty">No blocked shell attempts in the recent trace window.</div>`
|
|
504
|
+
: `<h3>By binary (${groups.length})</h3>
|
|
505
|
+
<table>
|
|
506
|
+
<thead><tr><th>Binary</th><th>Attempts</th><th>Skills</th><th>Last attempt</th></tr></thead>
|
|
507
|
+
<tbody>
|
|
508
|
+
${groups.map(([binary, g]) => `
|
|
509
|
+
<tr>
|
|
510
|
+
<td><code>${esc(binary)}</code></td>
|
|
511
|
+
<td>${g.count}</td>
|
|
512
|
+
<td>${[...g.skills].sort().map((s) => `<a href="#skill/${encodeURIComponent(s)}">${esc(s)}</a>`).join(", ")}</td>
|
|
513
|
+
<td>${new Date(g.latest).toLocaleString()}</td>
|
|
514
|
+
</tr>
|
|
515
|
+
`).join("")}
|
|
516
|
+
</tbody>
|
|
517
|
+
</table>
|
|
518
|
+
<h3 style="margin-top: 24px;">Recent attempts (${attempts.length})</h3>
|
|
519
|
+
<table>
|
|
520
|
+
<thead><tr><th>When</th><th>Skill</th><th>Target</th><th>Binary</th><th>Body</th></tr></thead>
|
|
521
|
+
<tbody>
|
|
522
|
+
${attempts.slice(0, 25).map((a) => `
|
|
523
|
+
<tr>
|
|
524
|
+
<td>${new Date(a.fired_at_ms).toLocaleString()}</td>
|
|
525
|
+
<td><a href="#skill/${encodeURIComponent(a.skill_name)}">${esc(a.skill_name)}</a></td>
|
|
526
|
+
<td><code>${esc(a.target)}</code></td>
|
|
527
|
+
<td><code>${esc(a.binary)}</code></td>
|
|
528
|
+
<td><code style="font-size: 0.85em;">${esc(a.body)}</code></td>
|
|
529
|
+
</tr>
|
|
530
|
+
`).join("")}
|
|
531
|
+
</tbody>
|
|
532
|
+
</table>`}
|
|
533
|
+
</section>
|
|
534
|
+
`;
|
|
535
|
+
}
|
|
536
|
+
|
|
321
537
|
function renderConnectors() {
|
|
322
538
|
const caps = state.capabilities;
|
|
323
539
|
const wiredMcp = caps?.mcpConnectors ?? [];
|
|
@@ -576,6 +792,7 @@ async function renderCurrentView() {
|
|
|
576
792
|
case "skills": main.innerHTML = renderSkills(); break;
|
|
577
793
|
case "triggers": main.innerHTML = renderTriggers(); break;
|
|
578
794
|
case "connectors": main.innerHTML = renderConnectors(); break;
|
|
795
|
+
case "security": main.innerHTML = renderSecurity(); break;
|
|
579
796
|
default: main.innerHTML = `<section><div class="empty">Unknown view: ${esc(hash)}</div></section>`;
|
|
580
797
|
}
|
|
581
798
|
}
|
|
@@ -97,3 +97,42 @@ pre {
|
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
.empty { color: #6c757d; padding: 24px; text-align: center; font-style: italic; }
|
|
100
|
+
|
|
101
|
+
/* v0.18.9 — Security signal highlighting in the skill source viewer.
|
|
102
|
+
* Two tiers as soft tints on the dark <pre> background. Low alpha so
|
|
103
|
+
* the prose stays readable; the eye picks up the tinted spans on a
|
|
104
|
+
* scan without being overwhelmed. */
|
|
105
|
+
pre.skill-source { white-space: pre-wrap; word-break: break-word; }
|
|
106
|
+
.sig-high {
|
|
107
|
+
background: rgba(255, 140, 50, 0.30);
|
|
108
|
+
padding: 1px 3px;
|
|
109
|
+
border-radius: 3px;
|
|
110
|
+
}
|
|
111
|
+
.sig-medium {
|
|
112
|
+
background: rgba(255, 215, 0, 0.22);
|
|
113
|
+
padding: 1px 3px;
|
|
114
|
+
border-radius: 3px;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/* Inline color chips for the security-signals summary panel + the
|
|
118
|
+
* "what colors mean what" legend at the bottom of that panel. */
|
|
119
|
+
.security-signals { list-style: none; padding-left: 0; margin: 0; }
|
|
120
|
+
.security-signals li {
|
|
121
|
+
padding: 6px 10px;
|
|
122
|
+
margin: 4px 0;
|
|
123
|
+
border-radius: 4px;
|
|
124
|
+
border-left: 3px solid transparent;
|
|
125
|
+
}
|
|
126
|
+
.security-signals .sig-high-text {
|
|
127
|
+
background: rgba(255, 140, 50, 0.10);
|
|
128
|
+
border-left-color: rgba(255, 140, 50, 0.75);
|
|
129
|
+
}
|
|
130
|
+
.security-signals .sig-medium-text {
|
|
131
|
+
background: rgba(255, 215, 0, 0.10);
|
|
132
|
+
border-left-color: rgba(255, 215, 0, 0.80);
|
|
133
|
+
}
|
|
134
|
+
.security-signals .sig-info-text {
|
|
135
|
+
background: #fafbfc;
|
|
136
|
+
border-left-color: #c4cad0;
|
|
137
|
+
}
|
|
138
|
+
.security-signals small { color: #6c757d; }
|
package/dist/errors.d.ts
CHANGED
|
@@ -227,4 +227,29 @@ export interface OpErrorMetadata {
|
|
|
227
227
|
skill?: string;
|
|
228
228
|
trace_id?: string;
|
|
229
229
|
}
|
|
230
|
+
/**
|
|
231
|
+
* v0.19.0 — POST `/event` hit with an event_name not registered with the
|
|
232
|
+
* scheduler. The route maps this to HTTP 404. Standalone (not an
|
|
233
|
+
* OpError) because it fires from the HTTP boundary, not inside skill
|
|
234
|
+
* execution.
|
|
235
|
+
*/
|
|
236
|
+
export declare class EventNotFoundError extends Error {
|
|
237
|
+
readonly eventName: string;
|
|
238
|
+
constructor(eventName: string);
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* v0.19.0 — POST `/event` hit a registered event_name but the params
|
|
242
|
+
* don't match the declared set. The route maps this to HTTP 400.
|
|
243
|
+
* Per Perry's spec (memory `ceaf4579`): strict v1 — all declared params
|
|
244
|
+
* must be present; no unknown params allowed. Defaults + type validation
|
|
245
|
+
* deferred to v2.
|
|
246
|
+
*/
|
|
247
|
+
export declare class EventParamMismatchError extends Error {
|
|
248
|
+
readonly eventName: string;
|
|
249
|
+
readonly declared: string[];
|
|
250
|
+
readonly supplied: string[];
|
|
251
|
+
readonly missing: string[];
|
|
252
|
+
readonly extra: string[];
|
|
253
|
+
constructor(eventName: string, declared: string[], supplied: string[], missing: string[], extra: string[]);
|
|
254
|
+
}
|
|
230
255
|
//# sourceMappingURL=errors.d.ts.map
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.js
CHANGED
|
@@ -254,10 +254,14 @@ export class ShellBinaryNotAllowedError extends OpError {
|
|
|
254
254
|
? "(empty list — operator declared no shell binaries permitted)"
|
|
255
255
|
: allowlist.join(", ");
|
|
256
256
|
const message = `\`shell\` op refused: binary '${binary}' is not in the operator's shell allowlist. Current allowlist: ${allowlistDisplay}.`;
|
|
257
|
-
const remediation = `Add '${binary}' to
|
|
257
|
+
const remediation = `Add '${binary}' to the runtime's shell allowlist via one of three wiring paths: ` +
|
|
258
|
+
`(1) \`SKILLSCRIPT_SHELL_ALLOWLIST\` env var (comma-separated; works on CLI + bootstrap()); ` +
|
|
259
|
+
`(2) \`shellAllowlist\` field in \`skillscript.config.json\`; ` +
|
|
260
|
+
`(3) \`bootstrap({ shellAllowlist: [...] })\` programmatic opt for embedders. ` +
|
|
261
|
+
`Then restart the runtime. ` +
|
|
258
262
|
`To discover what binaries your existing skill corpus uses, run \`skillfile shell-audit\` — it scans every skill and prints the union of binaries ready to paste into the allowlist. ` +
|
|
259
263
|
`Binary-scope is an operator boundary the skill author cannot escape via the \`unsafe\` keyword or any other in-skill mechanism. ` +
|
|
260
|
-
`See \`docs/adopter-playbook.md\` § "Shell binary allowlist" for the migration walkthrough.`;
|
|
264
|
+
`See \`docs/adopter-playbook.md\` § "Shell binary allowlist" for the migration walkthrough (including the programmatic-bootstrap path's \`.env\` auto-load gotcha).`;
|
|
261
265
|
super(message, "shell", remediation, target);
|
|
262
266
|
this.binary = binary;
|
|
263
267
|
this.allowlist = allowlist;
|
|
@@ -401,4 +405,46 @@ export class UnsupportedFilterError extends OpError {
|
|
|
401
405
|
this.name = "UnsupportedFilterError";
|
|
402
406
|
}
|
|
403
407
|
}
|
|
408
|
+
/**
|
|
409
|
+
* v0.19.0 — POST `/event` hit with an event_name not registered with the
|
|
410
|
+
* scheduler. The route maps this to HTTP 404. Standalone (not an
|
|
411
|
+
* OpError) because it fires from the HTTP boundary, not inside skill
|
|
412
|
+
* execution.
|
|
413
|
+
*/
|
|
414
|
+
export class EventNotFoundError extends Error {
|
|
415
|
+
eventName;
|
|
416
|
+
constructor(eventName) {
|
|
417
|
+
super(`event_name '${eventName}' is not registered with this runtime`);
|
|
418
|
+
this.eventName = eventName;
|
|
419
|
+
this.name = "EventNotFoundError";
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* v0.19.0 — POST `/event` hit a registered event_name but the params
|
|
424
|
+
* don't match the declared set. The route maps this to HTTP 400.
|
|
425
|
+
* Per Perry's spec (memory `ceaf4579`): strict v1 — all declared params
|
|
426
|
+
* must be present; no unknown params allowed. Defaults + type validation
|
|
427
|
+
* deferred to v2.
|
|
428
|
+
*/
|
|
429
|
+
export class EventParamMismatchError extends Error {
|
|
430
|
+
eventName;
|
|
431
|
+
declared;
|
|
432
|
+
supplied;
|
|
433
|
+
missing;
|
|
434
|
+
extra;
|
|
435
|
+
constructor(eventName, declared, supplied, missing, extra) {
|
|
436
|
+
const parts = [];
|
|
437
|
+
if (missing.length > 0)
|
|
438
|
+
parts.push(`missing required params: ${missing.map((p) => `'${p}'`).join(", ")}`);
|
|
439
|
+
if (extra.length > 0)
|
|
440
|
+
parts.push(`unknown params: ${extra.map((p) => `'${p}'`).join(", ")}`);
|
|
441
|
+
super(`POST /event '${eventName}' — ${parts.join("; ")}. Declared params: [${declared.map((p) => `'${p}'`).join(", ") || "(none)"}].`);
|
|
442
|
+
this.eventName = eventName;
|
|
443
|
+
this.declared = declared;
|
|
444
|
+
this.supplied = supplied;
|
|
445
|
+
this.missing = missing;
|
|
446
|
+
this.extra = extra;
|
|
447
|
+
this.name = "EventParamMismatchError";
|
|
448
|
+
}
|
|
449
|
+
}
|
|
404
450
|
//# sourceMappingURL=errors.js.map
|