opencode-secrets-obfuscation 0.1.2 → 0.1.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.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. package/plugin.mjs +15 -3
package/README.md CHANGED
@@ -10,7 +10,7 @@ This plugin keeps configured dotenv values private and substitutes opaque secret
10
10
 
11
11
  ## Installation
12
12
 
13
- Install with: opencode plugin add opencode-secrets-obfuscation@0.1.2
13
+ Install with: opencode plugin add opencode-secrets-obfuscation@0.1.5
14
14
 
15
15
  Configure the published package in opencode.jsonc with the options documented at https://github.com/jfomhhover/opencode-secrets-obfuscation/blob/main/INSTALL.md.
16
16
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-secrets-obfuscation",
3
- "version": "0.1.2",
3
+ "version": "0.1.5",
4
4
  "description": "Transparent OpenCode V2 secret substitution plugin",
5
5
  "license": "MIT",
6
6
  "repository": {
package/plugin.mjs CHANGED
@@ -3445,6 +3445,7 @@ function redactHeaders(headers, state, options2) {
3445
3445
  }
3446
3446
  function redactBody(text, state) {
3447
3447
  if (!hasSecrets(state)) return text;
3448
+ if (scanForSecrets(text, state.patterns, state.budget) === "clean") return text;
3448
3449
  const trimmed = text.trimStart();
3449
3450
  if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
3450
3451
  try {
@@ -3514,8 +3515,8 @@ async function redactRequest(request, state) {
3514
3515
  request.headers.forEach((value, name) => {
3515
3516
  record[name] = value;
3516
3517
  });
3518
+ const originalHeaders = { ...record };
3517
3519
  if (redactHeaders(record, state, { skipAuth: true, strict: true }) === "withheld") return "withheld";
3518
- delete record["content-length"];
3519
3520
  let body;
3520
3521
  if (request.body !== null) {
3521
3522
  const read = await readBoundedBody(request.clone().body, verifyCeiling);
@@ -3528,6 +3529,12 @@ async function redactRequest(request, state) {
3528
3529
  if (safe !== read.text) body = safe;
3529
3530
  }
3530
3531
  }
3532
+ const headersChanged = Object.keys(record).length !== Object.keys(originalHeaders).length || Object.keys(record).some((name) => record[name] !== originalHeaders[name]);
3533
+ if (body === void 0 && !headersChanged) return request;
3534
+ if (body !== void 0) {
3535
+ delete record["content-length"];
3536
+ record["content-length"] = String(encoder2.encode(body).byteLength);
3537
+ }
3531
3538
  try {
3532
3539
  return new Request(request, {
3533
3540
  headers: record,
@@ -3723,14 +3730,19 @@ var realRuntimeFactory = (options2, location) => {
3723
3730
  };
3724
3731
  const sanitizeValue = (value) => {
3725
3732
  if (typeof value === "string") return redactString(value, filter) ?? WITHHELD;
3733
+ try {
3734
+ const serialized = JSON.stringify(value);
3735
+ const scan = serialized === void 0 ? "none" : scanForSecrets(serialized, filter.patterns, filter.budget);
3736
+ if (serialized !== void 0 && Buffer.byteLength(serialized, "utf8") <= scanCeiling && scan === "clean") return value;
3737
+ } catch {
3738
+ }
3726
3739
  redactTree(value, filter);
3727
3740
  return value;
3728
3741
  };
3729
3742
  const sanitizeRequestContext = (event) => {
3730
3743
  event.system = sanitizeValue(event.system);
3731
- redactTree(event.messages, filter);
3744
+ event.messages = sanitizeValue(event.messages);
3732
3745
  event.options = sanitizeValue(event.options);
3733
- if (event.tools !== void 0) event.tools = sanitizeValue(event.tools);
3734
3746
  };
3735
3747
  const runtime = {
3736
3748
  close: () => Effect4.sync(() => store.teardown()),