@openlines/opl-pi-sht 0.2.8 → 0.2.9
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
CHANGED
|
@@ -14,15 +14,16 @@
|
|
|
14
14
|
|
|
15
15
|
A portable collection of various Pi coding agent extensions. Repository directories and config files use `opl-`; established Pi-facing commands and tool names stay compatible.
|
|
16
16
|
|
|
17
|
-
<div align="center">
|
|
18
|
-
|
|
19
17
|
>
|
|
20
|
-
> ### v0.2.
|
|
18
|
+
> ### v0.2.9 - pi dependencies patch, updated test scripts
|
|
19
|
+
> - `devDependencies` updated to `>=0.87.0`, conforming to latest pi release `v0.99.x`; TUI and tests updates
|
|
20
|
+
> ### v0.2.8 - SSRF and tool-safety hardening
|
|
21
|
+
> - `opl-webaccess` and `opl-browser` block private/link-local hosts by default and cloud metadata always (localhost stays available for dev), fetch redirects are re-checked per hop, screenshots refuse to overwrite existing files, and `evaluate` no longer crashes on `undefined`.
|
|
21
22
|
>
|
|
22
|
-
>
|
|
23
|
+
> See [CHANGELOG](CHANGELOG.md) for more details.
|
|
24
|
+
>
|
|
25
|
+
> `Current project state also marked 'SAFE' for pi v0.99.x release`
|
|
23
26
|
>
|
|
24
|
-
|
|
25
|
-
</div>
|
|
26
27
|
|
|
27
28
|
## Installation
|
|
28
29
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# opl-guardian
|
|
2
2
|
|
|
3
|
-
A configurable session and tool safety extension. `opl-guardian` filters malformed assistant tool calls, prompts before dangerous Bash commands, blocks operations on protected paths, and confirms destructive session transitions. It replaces the standalone `permission-gate`, `protected-paths`, and `confirm-destructive` extensions while retaining malformed-call diagnostics. It adds no tools, commands, prompts, or model-facing schema overhead.
|
|
3
|
+
A configurable session and tool safety extension. `opl-guardian` filters malformed assistant tool calls, prompts before dangerous Bash commands, blocks operations on protected paths, and confirms destructive session transitions. It replaces the standalone `permission-gate`, `protected-paths`, and `confirm-destructive` extensions while retaining malformed-call diagnostics. It adds no tools, commands, prompts, or model-facing schema overhead. All Guardian notification, selection-prompt, and confirmation message text is rendered in fixed red, regardless of Pi's theme; choice labels retain Pi's normal styling.
|
|
4
4
|
|
|
5
5
|
## Configuration
|
|
6
6
|
|
|
@@ -20,6 +20,12 @@ import {
|
|
|
20
20
|
import { getProtectedPathBlock, hasPendingUserWork } from "./policies.js";
|
|
21
21
|
|
|
22
22
|
const LOG_PATH = join("err", "guardian.jsonl");
|
|
23
|
+
const RED = "\u001b[31m";
|
|
24
|
+
const RESET_FOREGROUND = "\u001b[39m";
|
|
25
|
+
|
|
26
|
+
function red(text: string): string {
|
|
27
|
+
return `${RED}${text}${RESET_FOREGROUND}`;
|
|
28
|
+
}
|
|
23
29
|
|
|
24
30
|
export async function appendIncident(cwd: string, incident: GuardianIncident): Promise<void> {
|
|
25
31
|
const directory = join(cwd, "err");
|
|
@@ -103,7 +109,7 @@ export function createToolCallHandler(config: GuardianConfig) {
|
|
|
103
109
|
const reason = blocked.unresolved
|
|
104
110
|
? `[opl-guardian] Cannot safely resolve path "${blocked.path}"; ${blocked.operation} denied by protected-path policy.`
|
|
105
111
|
: `[opl-guardian] Path "${blocked.path}" is protected (${blocked.operation} denied).`;
|
|
106
|
-
if (ctx.hasUI) ctx.ui.notify(reason, "warning");
|
|
112
|
+
if (ctx.hasUI) ctx.ui.notify(red(reason), "warning");
|
|
107
113
|
return { block: true, reason };
|
|
108
114
|
}
|
|
109
115
|
}
|
|
@@ -124,7 +130,7 @@ export function createToolCallHandler(config: GuardianConfig) {
|
|
|
124
130
|
const options = ["No", "Yes"];
|
|
125
131
|
if (ctx.mode === "rpc") {
|
|
126
132
|
try {
|
|
127
|
-
const choice = await ctx.ui.select(`Dangerous command
|
|
133
|
+
const choice = await ctx.ui.select(red(`Dangerous command:\n\n${preview.slice(0, 256)}\n\nAllow?`), options);
|
|
128
134
|
if (choice === "Yes") return undefined;
|
|
129
135
|
} catch {
|
|
130
136
|
// A failed RPC dialog is not approval.
|
|
@@ -132,10 +138,10 @@ export function createToolCallHandler(config: GuardianConfig) {
|
|
|
132
138
|
return { block: true, reason: "[opl-guardian] Command blocked; confirmation was declined or unavailable." };
|
|
133
139
|
}
|
|
134
140
|
|
|
135
|
-
const choice = await ctx.ui.select(`Dangerous command
|
|
141
|
+
const choice = await ctx.ui.select(red(`Dangerous command:\n\n${preview.slice(0, 256)}\n\nAllow?`), options);
|
|
136
142
|
if (choice === "Yes") return undefined;
|
|
137
143
|
const reason = "[opl-guardian] Command blocked by user because it matches a dangerous pattern.";
|
|
138
|
-
ctx.ui.notify(reason, "warning");
|
|
144
|
+
ctx.ui.notify(red(reason), "warning");
|
|
139
145
|
return { block: true, reason };
|
|
140
146
|
};
|
|
141
147
|
}
|
|
@@ -151,7 +157,7 @@ export function createMessageEndHandler(config: GuardianConfig) {
|
|
|
151
157
|
sessionId: ctx.sessionManager.getSessionId(),
|
|
152
158
|
});
|
|
153
159
|
if (!guarded) return undefined;
|
|
154
|
-
ctx.ui?.notify(guarded.diagnostic, "warning");
|
|
160
|
+
ctx.ui?.notify(red(guarded.diagnostic), "warning");
|
|
155
161
|
return { message: guarded.message };
|
|
156
162
|
};
|
|
157
163
|
}
|
|
@@ -172,7 +178,7 @@ export function createSessionBeforeSwitchHandler(config: GuardianConfig) {
|
|
|
172
178
|
}
|
|
173
179
|
|
|
174
180
|
if (!ctx.hasUI) return config.confirmDestructive.blockWithoutUI ? { cancel: true } : undefined;
|
|
175
|
-
return await ctx.ui.confirm(title, message) ? undefined : { cancel: true };
|
|
181
|
+
return await ctx.ui.confirm(red(title), red(message)) ? undefined : { cancel: true };
|
|
176
182
|
};
|
|
177
183
|
}
|
|
178
184
|
|
|
@@ -181,8 +187,8 @@ export function createSessionBeforeForkHandler(config: GuardianConfig) {
|
|
|
181
187
|
if (!config.confirmDestructive.forkSession) return undefined;
|
|
182
188
|
if (!ctx.hasUI) return config.confirmDestructive.blockWithoutUI ? { cancel: true } : undefined;
|
|
183
189
|
const confirmed = await ctx.ui.confirm(
|
|
184
|
-
`Fork from entry ${event.entryId.slice(0, 8)}
|
|
185
|
-
"Create a new session branch from this point?",
|
|
190
|
+
red(`Fork from entry ${event.entryId.slice(0, 8)}?`),
|
|
191
|
+
red("Create a new session branch from this point?"),
|
|
186
192
|
);
|
|
187
193
|
return confirmed ? undefined : { cancel: true };
|
|
188
194
|
};
|
|
@@ -192,7 +198,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
192
198
|
const { config, warnings } = loadGuardianConfig();
|
|
193
199
|
pi.on("session_start", async (_event, ctx) => {
|
|
194
200
|
if (warnings.length && ctx.hasUI) {
|
|
195
|
-
ctx.ui.notify(`[opl-guardian] Configuration warning(s):\n${warnings.join("\n")}
|
|
201
|
+
ctx.ui.notify(red(`[opl-guardian] Configuration warning(s):\n${warnings.join("\n")}`), "warning");
|
|
196
202
|
}
|
|
197
203
|
});
|
|
198
204
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openlines/opl-pi-sht",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.9",
|
|
4
4
|
"description": "opl-pi-sht (shouldHaveThat) Pi coding-agent extension kit: token-efficient context, tool and session safety, fingerprinted /init, model benchmarking, web access, and browser automation.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
},
|
|
41
41
|
"type": "module",
|
|
42
42
|
"scripts": {
|
|
43
|
-
"test": "
|
|
43
|
+
"test": "node tests/test-summary.mjs",
|
|
44
44
|
"test:opl-browser": "bun test tests/opl-browser-helpers.test.mjs && OPL_EXTENSION=opl-browser bun test tests/extension-smoke.test.mjs",
|
|
45
45
|
"test:opl-footer": "bun test tests/opl-footer-helpers.test.mjs && OPL_EXTENSION=opl-footer bun test tests/extension-smoke.test.mjs",
|
|
46
46
|
"test:opl-guardian": "bun test tests/opl-guardian.test.mjs && OPL_EXTENSION=opl-guardian bun test tests/extension-smoke.test.mjs",
|
|
@@ -55,6 +55,6 @@
|
|
|
55
55
|
"test:pi-host": "bun test tests/pi-host-loader.test.mjs"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
|
-
"@earendil-works/pi-coding-agent": "
|
|
58
|
+
"@earendil-works/pi-coding-agent": ">=0.87.0"
|
|
59
59
|
}
|
|
60
60
|
}
|