my-pi 0.1.4 → 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.
- package/dist/{api-BtlxiHyw.js → api-DgvJRqr3.js} +66 -4
- package/dist/api-DgvJRqr3.js.map +1 -0
- package/dist/api.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +4 -4
- package/src/extensions/filter-output.test.ts +105 -207
- package/src/extensions/filter-output.ts +137 -13
- package/dist/api-BtlxiHyw.js.map +0 -1
|
@@ -819,7 +819,39 @@ const SECRET_PATTERNS = [
|
|
|
819
819
|
pattern: /github_pat_[a-zA-Z0-9_]{20,}/g
|
|
820
820
|
}
|
|
821
821
|
];
|
|
822
|
-
|
|
822
|
+
const SSH_CONFIG_VALUE_DIRECTIVE_PATTERN = /^([ \t]*)(HostName|User|IdentityFile|CertificateFile|ProxyJump|ProxyCommand|LocalForward|RemoteForward|DynamicForward|HostKeyAlias)(\s+)(.+)$/gim;
|
|
823
|
+
const SSH_CONFIG_HOST_PATTERN = /^([ \t]*)(Host)(\s+)(.+)$/gim;
|
|
824
|
+
const SSH_CONFIG_MATCH_PATTERN = /^([ \t]*)(Match)(\s+)(.+)$/gim;
|
|
825
|
+
function looks_like_ssh_config(text) {
|
|
826
|
+
const has_scope_line = /^\s*(?:Host|Match)\b/m.test(text);
|
|
827
|
+
const has_sensitive_directive = /^\s*(?:HostName|User|IdentityFile|CertificateFile|ProxyJump|ProxyCommand|LocalForward|RemoteForward|DynamicForward|HostKeyAlias)\b/im.test(text);
|
|
828
|
+
return has_scope_line && has_sensitive_directive;
|
|
829
|
+
}
|
|
830
|
+
function redact_ssh_config_metadata(text) {
|
|
831
|
+
let count = 0;
|
|
832
|
+
const redact_directive_value = (match, indent, directive, spacing, value) => {
|
|
833
|
+
if (value.includes("[REDACTED:")) return match;
|
|
834
|
+
count++;
|
|
835
|
+
return `${indent}${directive}${spacing}[REDACTED:SSH ${directive}]`;
|
|
836
|
+
};
|
|
837
|
+
let result = text.replace(SSH_CONFIG_VALUE_DIRECTIVE_PATTERN, redact_directive_value);
|
|
838
|
+
result = result.replace(SSH_CONFIG_HOST_PATTERN, (match, indent, directive, spacing, value) => {
|
|
839
|
+
if (value.trim() === "*" || value.includes("[REDACTED:")) return match;
|
|
840
|
+
count++;
|
|
841
|
+
return `${indent}${directive}${spacing}[REDACTED:SSH Host]`;
|
|
842
|
+
});
|
|
843
|
+
result = result.replace(SSH_CONFIG_MATCH_PATTERN, (match, indent, directive, spacing, value) => {
|
|
844
|
+
if (value.trim().toLowerCase() === "all") return match;
|
|
845
|
+
if (value.includes("[REDACTED:")) return match;
|
|
846
|
+
count++;
|
|
847
|
+
return `${indent}${directive}${spacing}[REDACTED:SSH Match]`;
|
|
848
|
+
});
|
|
849
|
+
return {
|
|
850
|
+
redacted: result,
|
|
851
|
+
count
|
|
852
|
+
};
|
|
853
|
+
}
|
|
854
|
+
function redact_secret_patterns(text) {
|
|
823
855
|
let count = 0;
|
|
824
856
|
let result = text;
|
|
825
857
|
for (const sp of SECRET_PATTERNS) {
|
|
@@ -834,14 +866,44 @@ function redact(text) {
|
|
|
834
866
|
count
|
|
835
867
|
};
|
|
836
868
|
}
|
|
869
|
+
function is_ssh_config_path(path) {
|
|
870
|
+
if (typeof path !== "string") return false;
|
|
871
|
+
const normalized = path.replaceAll("\\", "/").toLowerCase();
|
|
872
|
+
return /(?:^|\/)(?:\.ssh\/(?:config|config\.d\/.+|conf\.d\/.+)|ssh_config)$/.test(normalized);
|
|
873
|
+
}
|
|
874
|
+
function should_force_ssh_config_redaction(event) {
|
|
875
|
+
if (event.toolName !== "read") return false;
|
|
876
|
+
if (!event.input || typeof event.input !== "object") return false;
|
|
877
|
+
return is_ssh_config_path(event.input.path);
|
|
878
|
+
}
|
|
879
|
+
function is_text_content(item) {
|
|
880
|
+
return item.type === "text";
|
|
881
|
+
}
|
|
882
|
+
function redact_text(text, options) {
|
|
883
|
+
let count = 0;
|
|
884
|
+
let result = text;
|
|
885
|
+
if (options?.force_ssh_config || looks_like_ssh_config(result)) {
|
|
886
|
+
const ssh_redaction = redact_ssh_config_metadata(result);
|
|
887
|
+
result = ssh_redaction.redacted;
|
|
888
|
+
count += ssh_redaction.count;
|
|
889
|
+
}
|
|
890
|
+
const secret_redaction = redact_secret_patterns(result);
|
|
891
|
+
result = secret_redaction.redacted;
|
|
892
|
+
count += secret_redaction.count;
|
|
893
|
+
return {
|
|
894
|
+
redacted: result,
|
|
895
|
+
count
|
|
896
|
+
};
|
|
897
|
+
}
|
|
837
898
|
async function filter_output(pi) {
|
|
838
899
|
let totalRedacted = 0;
|
|
839
900
|
pi.on("tool_result", async (event) => {
|
|
840
901
|
if (!event.content) return;
|
|
902
|
+
const force_ssh_config = should_force_ssh_config_redaction(event);
|
|
841
903
|
let modified = false;
|
|
842
904
|
const newContent = event.content.map((item) => {
|
|
843
|
-
if (item
|
|
844
|
-
const { redacted, count } =
|
|
905
|
+
if (!is_text_content(item) || !item.text) return item;
|
|
906
|
+
const { redacted, count } = redact_text(item.text, { force_ssh_config });
|
|
845
907
|
if (count > 0) {
|
|
846
908
|
modified = true;
|
|
847
909
|
totalRedacted += count;
|
|
@@ -5353,4 +5415,4 @@ async function create_my_pi(options = {}) {
|
|
|
5353
5415
|
//#endregion
|
|
5354
5416
|
export { runPrintMode$1 as i, create_my_pi as n, get_force_disabled_builtins as r, InteractiveMode$1 as t };
|
|
5355
5417
|
|
|
5356
|
-
//# sourceMappingURL=api-
|
|
5418
|
+
//# sourceMappingURL=api-DgvJRqr3.js.map
|