pi-warden 0.2.1 → 0.4.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 +61 -13
- package/dist/config.d.ts +19 -4
- package/dist/config.js +35 -6
- package/dist/done.d.ts +2 -2
- package/dist/done.js +11 -13
- package/dist/extension.d.ts +3 -1
- package/dist/extension.js +125 -28
- package/dist/guard.d.ts +20 -11
- package/dist/guard.js +53 -38
- package/dist/index.d.ts +11 -2
- package/dist/index.js +5 -0
- package/dist/panel.d.ts +44 -0
- package/dist/panel.js +121 -0
- package/dist/prose.d.ts +57 -0
- package/dist/prose.js +98 -0
- package/dist/stuck.d.ts +6 -3
- package/dist/stuck.js +11 -14
- package/dist/tools.d.ts +16 -0
- package/dist/tools.js +37 -0
- package/dist/trace.d.ts +31 -0
- package/dist/trace.js +93 -0
- package/dist/widget.d.ts +40 -0
- package/dist/widget.js +120 -0
- package/package.json +1 -1
package/dist/widget.js
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
export const DEFAULT_TEMPLATES = {
|
|
2
|
+
action: "warden · {tool} · irreversible {irreversible} · off-task {offTask} · {scope} · slop: {slop} · patterns: {patterns} · {flags} · {level}",
|
|
3
|
+
stuck: "warden · stuck · {failures} failures · same strategy {sameStrategy} · change {approachChange} · progress {progress} · {flags} · {status}",
|
|
4
|
+
done: "warden · done-check · {changes} changes · {checksPassed}/{checks} checks passed · claims done {claimsDone} · claims verified {claimsVerified} · checks apply {checksApply} · {outcome} · {status}",
|
|
5
|
+
prose: "warden · prose · wordy {wordy} · clichés {cliches} · jargon {jargon} · {flags} · {status}",
|
|
6
|
+
};
|
|
7
|
+
export function defaultWidgetConfig() {
|
|
8
|
+
return { enabled: true, placement: "aboveEditor", shortcut: "ctrl+shift+w", ...DEFAULT_TEMPLATES };
|
|
9
|
+
}
|
|
10
|
+
const SEPARATOR = " · ";
|
|
11
|
+
const TOKEN = /\{([a-zA-Z]+)\}/g;
|
|
12
|
+
/**
|
|
13
|
+
* Fill `{token}` placeholders. The template is split on " · "; a segment is dropped when any of its tokens is empty,
|
|
14
|
+
* so optional information disappears together with its label. Unknown tokens render as empty (and drop their segment).
|
|
15
|
+
*/
|
|
16
|
+
export function renderTemplate(template, tokens) {
|
|
17
|
+
const segments = [];
|
|
18
|
+
for (const segment of template.split(SEPARATOR)) {
|
|
19
|
+
let missing = false;
|
|
20
|
+
const rendered = segment.replace(TOKEN, (_match, name) => {
|
|
21
|
+
const value = tokens[name];
|
|
22
|
+
if (value === undefined || value === "")
|
|
23
|
+
missing = true;
|
|
24
|
+
return value ?? "";
|
|
25
|
+
});
|
|
26
|
+
if (!missing && rendered.trim())
|
|
27
|
+
segments.push(rendered.trim());
|
|
28
|
+
}
|
|
29
|
+
return segments.join(SEPARATOR);
|
|
30
|
+
}
|
|
31
|
+
const fixed = (value, digits = 2) => (value === undefined ? undefined : value.toFixed(digits));
|
|
32
|
+
const time = (at) => new Date(at).toTimeString().slice(0, 8);
|
|
33
|
+
export function actionTokens(verdict, at = Date.now()) {
|
|
34
|
+
const flags = [
|
|
35
|
+
verdict.approvedByUser ? "user approved" : undefined,
|
|
36
|
+
verdict.source === "error" ? "typesafe error" : undefined,
|
|
37
|
+
verdict.source === "read-only" ? "read-only" : undefined,
|
|
38
|
+
].filter(Boolean).join(", ");
|
|
39
|
+
return {
|
|
40
|
+
guard: "action",
|
|
41
|
+
time: time(at),
|
|
42
|
+
tool: verdict.summary.tool,
|
|
43
|
+
level: verdict.level,
|
|
44
|
+
source: verdict.source,
|
|
45
|
+
irreversible: fixed(verdict.judgment?.irreversible),
|
|
46
|
+
offTask: fixed(verdict.judgment?.offTask),
|
|
47
|
+
scope: verdict.judgment?.scope.replace(/_/g, " "),
|
|
48
|
+
approved: fixed(verdict.judgment?.approved),
|
|
49
|
+
slop: verdict.slopSymptoms?.length ? verdict.slopSymptoms.map(symptom => `${symptom} ${verdict.slop[symptom].toFixed(2)}`).join(", ") : verdict.slop ? "none" : undefined,
|
|
50
|
+
slopStub: fixed(verdict.slop?.stub),
|
|
51
|
+
slopComments: fixed(verdict.slop?.comments),
|
|
52
|
+
slopDead: fixed(verdict.slop?.dead),
|
|
53
|
+
slopHedging: fixed(verdict.slop?.hedging),
|
|
54
|
+
patterns: verdict.patterns.length ? verdict.patterns.map(hit => hit.id).join(", ") : undefined,
|
|
55
|
+
reasons: verdict.reasons.length ? verdict.reasons.join("; ") : undefined,
|
|
56
|
+
path: verdict.summary.path,
|
|
57
|
+
model: verdict.judgment?.model,
|
|
58
|
+
ms: verdict.judgment ? String(verdict.judgment.elapsedMs) : undefined,
|
|
59
|
+
flags: flags || undefined,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
export function stuckTokens(verdict, at = Date.now()) {
|
|
63
|
+
const flags = [
|
|
64
|
+
verdict.source === "repeat" && verdict.stuck ? "exact repeat" : undefined,
|
|
65
|
+
verdict.source === "error" ? "typesafe error" : undefined,
|
|
66
|
+
].filter(Boolean).join(", ");
|
|
67
|
+
return {
|
|
68
|
+
guard: "stuck",
|
|
69
|
+
time: time(at),
|
|
70
|
+
failures: String(verdict.failures),
|
|
71
|
+
sameStrategy: fixed(verdict.judgment?.sameStrategy),
|
|
72
|
+
approachChange: verdict.judgment ? `${verdict.judgment.approachChange.toFixed(1)}/2` : undefined,
|
|
73
|
+
progress: fixed(verdict.judgment?.progress),
|
|
74
|
+
status: verdict.stuck ? "stuck" : "ok",
|
|
75
|
+
source: verdict.source,
|
|
76
|
+
reasons: verdict.reasons.length ? verdict.reasons.join("; ") : undefined,
|
|
77
|
+
model: verdict.judgment?.model,
|
|
78
|
+
ms: verdict.judgment ? String(verdict.judgment.elapsedMs) : undefined,
|
|
79
|
+
flags: flags || undefined,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
export function doneTokens(verdict, at = Date.now()) {
|
|
83
|
+
return {
|
|
84
|
+
guard: "done",
|
|
85
|
+
time: time(at),
|
|
86
|
+
changes: String(verdict.evidence.mutations),
|
|
87
|
+
checks: String(verdict.evidence.checks.length),
|
|
88
|
+
checksPassed: String(verdict.evidence.checks.filter(check => check.passed).length),
|
|
89
|
+
claimsDone: fixed(verdict.judgment?.claimsDone),
|
|
90
|
+
claimsVerified: fixed(verdict.judgment?.claimsVerified),
|
|
91
|
+
checksApply: fixed(verdict.judgment?.verificationApplies),
|
|
92
|
+
outcome: verdict.judgment?.outcome,
|
|
93
|
+
status: verdict.falseClaim ? "false claim" : verdict.unverified ? "unverified" : "ok",
|
|
94
|
+
reasons: verdict.reasons.length ? verdict.reasons.join("; ") : undefined,
|
|
95
|
+
model: verdict.judgment?.model,
|
|
96
|
+
ms: verdict.judgment ? String(verdict.judgment.elapsedMs) : undefined,
|
|
97
|
+
flags: verdict.error ? "typesafe error" : undefined,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
export function proseTokens(verdict, at = Date.now()) {
|
|
101
|
+
return {
|
|
102
|
+
guard: "prose",
|
|
103
|
+
time: time(at),
|
|
104
|
+
wordy: fixed(verdict.scores?.wordy),
|
|
105
|
+
cliches: fixed(verdict.scores?.cliches),
|
|
106
|
+
jargon: fixed(verdict.scores?.jargon),
|
|
107
|
+
status: verdict.nudged ? "nudged" : verdict.flagged.length ? verdict.flagged.join(", ") : "ok",
|
|
108
|
+
reasons: verdict.flagged.length ? verdict.flagged.join(", ") : undefined,
|
|
109
|
+
model: verdict.model,
|
|
110
|
+
ms: verdict.elapsedMs === undefined ? undefined : String(verdict.elapsedMs),
|
|
111
|
+
flags: verdict.error ? "typesafe error" : undefined,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
/** Token names users can put in templates, for /warden status and the README. */
|
|
115
|
+
export const TOKEN_NAMES = {
|
|
116
|
+
action: ["tool", "level", "source", "irreversible", "offTask", "scope", "approved", "slop", "slopStub", "slopComments", "slopDead", "slopHedging", "patterns", "reasons", "path", "model", "ms", "flags", "time", "guard"],
|
|
117
|
+
prose: ["wordy", "cliches", "jargon", "status", "reasons", "model", "ms", "flags", "time", "guard"],
|
|
118
|
+
stuck: ["failures", "sameStrategy", "approachChange", "progress", "status", "source", "reasons", "model", "ms", "flags", "time", "guard"],
|
|
119
|
+
done: ["changes", "checks", "checksPassed", "claimsDone", "claimsVerified", "checksApply", "outcome", "status", "reasons", "model", "ms", "flags", "time", "guard"],
|
|
120
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-warden",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Guardrails for Pi built on pi-typesafe that steer the agent instead of interrupting you: Jev judges irreversible and off-task tool calls before they run, detects stuck loops, checks unverified done claims, and flags slop.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|