@xynogen/pix-gate 0.4.3 → 0.4.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xynogen/pix-gate",
3
- "version": "0.4.3",
3
+ "version": "0.4.5",
4
4
  "description": "Pi extension \u2014 permission gate for dangerous bash commands (confirm/block with TUI dialog)",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
package/src/lib.ts CHANGED
@@ -323,8 +323,11 @@ export function buildRules(cfg: UserConfig): {
323
323
  pathRules: PathRule[];
324
324
  } {
325
325
  const base = cfg.guardrails === "off" ? [] : DEFAULT_RULES.slice();
326
+ // `g`/`y` make RegExp.test() stateful (lastIndex), so the same command would
327
+ // match on one call and slip through on the next. Strip them.
328
+ const stateless = (flags: string) => flags.replace(/[gy]/g, "");
326
329
  const extra = (cfg.extraRules ?? []).map((r) => ({
327
- pattern: new RegExp(r.pattern, r.flags ?? "i"),
330
+ pattern: new RegExp(r.pattern, stateless(r.flags ?? "i")),
328
331
  severity: (r.severity ?? "dangerous") as Severity,
329
332
  reason: r.reason ?? "user-defined rule",
330
333
  }));
package/src/prompt.ts CHANGED
@@ -145,7 +145,7 @@ const SEVERITY_TIER: {
145
145
  export async function promptMergedGateDecision(
146
146
  ui: GatePromptUI,
147
147
  concerns: Concern[],
148
- command: string,
148
+ _command: string,
149
149
  ): Promise<GateDecision> {
150
150
  // Sort by tier desc so the highest-severity concern drives dialog behavior.
151
151
  const sorted = [...concerns].sort((a, b) => b.tier - a.tier);
@@ -163,11 +163,12 @@ export async function promptMergedGateDecision(
163
163
  uniqueLabels.push(key);
164
164
  }
165
165
  }
166
- const titleSuffix = command.length > 55 ? `${command.slice(0, 52)}…` : command;
167
- const title = `${uniqueLabels.join(" + ")} — ${titleSuffix}`;
166
+ const title = uniqueLabels.join(" + ");
168
167
 
169
- // Body: command + concern list
170
- const body = [command, "", ...sorted.map((c) => `${c.icon} ${c.label} — ${c.detail}`)];
168
+ const body = [
169
+ "Review the command in the tool card below.",
170
+ ...sorted.map((c) => `${c.icon} ${c.label} — ${c.detail}`),
171
+ ];
171
172
 
172
173
  const accent =
173
174
  highest.tier >= SEVERITY_TIER.critical
@@ -234,7 +235,7 @@ const TIMEOUT_BY_TIER: Record<string, number> = {
234
235
  export async function promptGateDecision(
235
236
  ui: GatePromptUI,
236
237
  hit: Rule,
237
- command: string,
238
+ _command: string,
238
239
  ): Promise<GateDecision> {
239
240
  const icon = SEVERITY_ICON[hit.severity];
240
241
  const label = titleCase(hit.severity);
@@ -268,7 +269,7 @@ export async function promptGateDecision(
268
269
  mode: "confirm",
269
270
  icon,
270
271
  title: `${label} — ${hit.reason}`,
271
- body: [command],
272
+ body: ["Review the command in the tool card below."],
272
273
  accent,
273
274
  timeoutMs: TIMEOUT_MS[hit.severity],
274
275
  choices,