Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions Flowlight/Inspection/RewriteRule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,27 @@ struct RewriteRule: Codable, Equatable, Identifiable, Sendable {
}
}

/// A selected recorded exchange plus safe request context for reviewing a request-rewrite suggestion.
struct RewriteRuleDraft: Identifiable, Equatable, Sendable {
var id: UUID { rule.id }
var rule: RewriteRule
var method: String
var url: String
var requestHeaders: [HTTPHeader]

init(exchange: HTTPExchange, rule: RewriteRule? = nil) {
self.rule = rule ?? RewriteRule(name: "Rewrite \(exchange.method.uppercased()) \(exchange.host)\(Self.pathOnly(exchange.path))",
host: exchange.host, path: Self.pathOnly(exchange.path), method: exchange.method)
method = exchange.method
url = exchange.url
requestHeaders = exchange.requestHeaders
}

private static func pathOnly(_ path: String) -> String {
path.split(separator: "?", maxSplits: 1).first.map(String.init) ?? path
}
}

// MARK: Matching & applying

/// Pure functions over plain data — no sockets — so the whole rewrite is testable without a proxy.
Expand Down
35 changes: 29 additions & 6 deletions Flowlight/Localization/de.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1489,7 +1489,6 @@
"App identity" = "App identity";
"LLM metadata" = "LLM metadata";
"MCP metadata" = "MCP metadata";
"Suggest guardrails" = "Suggest guardrails";
"Metadata only" = "Metadata only";
"Tool names" = "Tool names";
"Guardrail suggestions" = "Guardrail suggestions";
Expand Down Expand Up @@ -1535,8 +1534,6 @@
"Modify requests" = "Modify requests";
"Modify responses" = "Modify responses";
"Add Guardrail" = "Add Guardrail";
"Save this as a normal Flowlight guardrail" = "Save this as a normal Flowlight guardrail";
"Save this as a normal Flowlight rule" = "Save this as a normal Flowlight rule";
"Plugin findings are advisory. They did not block or change this request." = "Plugin findings are advisory. They did not block or change this request.";
"Let the request reach %@, then change its eligible response before this app receives it" = "Let the request reach %@, then change its eligible response before this app receives it";
"%@ answered this request. Flowlight then changed the response with “%@” before the app received it." = "%@ answered this request. Flowlight then changed the response with “%@” before the app received it.";
Expand Down Expand Up @@ -1567,7 +1564,6 @@
"Content-Length, Connection and Transfer-Encoding are written by Flowlight." = "Content-Length, Connection and Transfer-Encoding are written by Flowlight.";
"Binary · hexadecimal" = "Binary · hexadecimal";
"Each pair of hexadecimal characters is one byte. Flowlight writes the original bytes." = "Each pair of hexadecimal characters is one byte. Flowlight writes the original bytes.";
"Plugins add advisory findings to inspected exchanges. They do not block, rewrite, or send traffic anywhere by themselves." = "Plugins add advisory findings to inspected exchanges. They do not block, rewrite, or send traffic anywhere by themselves.";
"Import Package…" = "Import Package…";
"Backfill Findings" = "Backfill Findings";
"Clear plugin findings…" = "Clear plugin findings…";
Expand All @@ -1590,7 +1586,6 @@
"Backfilled plugin findings: %lld findings." = "Backfilled plugin findings: %lld findings.";
"Backfill failed: %@" = "Backfill failed: %@";
"JavaScript" = "JavaScript";
"Suggests guardrails" = "Suggests guardrails";
"%@ · v%@ · rule v%lld" = "%@ · v%@ · rule v%lld";
"Package %@ · Script %@" = "Package %@ · Script %@";
"Configured: %@" = "Configured: %@";
Expand All @@ -1605,7 +1600,6 @@
"Package digest" = "Package digest";
"Script digest" = "Script digest";
"Permissions" = "Permissions";
"Plugins are advisory. Installing this package does not let it block, rewrite, upload, or export traffic." = "Plugins are advisory. Installing this package does not let it block, rewrite, upload, or export traffic.";
"Install" = "Install";
"Not declared" = "Not declared";
"Configure %@" = "Configure %@";
Expand Down Expand Up @@ -1651,3 +1645,32 @@
"Clear local analyses?" = "Clear local analyses?";
"Clear analyses" = "Clear analyses";
"This removes only local potential-harm scores and explanations. Recorded requests, response bodies, alerts, rules, and inspection settings stay in place." = "This removes only local potential-harm scores and explanations. Recorded requests, response bodies, alerts, rules, and inspection settings stay in place.";

"Suggest reviewed actions" = "Suggest reviewed actions";
"Review guardrail" = "Review guardrail";
"Plugin suggested a normal Flowlight guardrail." = "Plugin suggested a normal Flowlight guardrail.";
"Review rule" = "Review rule";
"Plugin suggested a normal Flowlight rule." = "Plugin suggested a normal Flowlight rule.";
"Plugin suggested a reviewed Flowlight action." = "Plugin suggested a reviewed Flowlight action.";
"Review mock" = "Review mock";
"Review rewrite" = "Review rewrite";
"Review transform" = "Review transform";
"Optional" = "Optional";
"Any server" = "Any server";
"Any tool" = "Any tool";
"Resource" = "Resource";
"Any resource" = "Any resource";
"Saving creates a normal Flowlight guardrail. The plugin cannot save or enforce it by itself." = "Saving creates a normal Flowlight guardrail. The plugin cannot save or enforce it by itself.";
"Review Guardrail" = "Review Guardrail";
"Review Rule" = "Review Rule";
"Review Mock" = "Review Mock";
"Review Rewrite" = "Review Rewrite";
"Review Transform" = "Review Transform";
"Open this suggestion as a normal Flowlight guardrail before saving" = "Open this suggestion as a normal Flowlight guardrail before saving";
"Open this suggestion as a normal Flowlight rule before saving" = "Open this suggestion as a normal Flowlight rule before saving";
"Open this suggestion in the mock response editor before saving" = "Open this suggestion in the mock response editor before saving";
"Open this suggestion in the request rewrite editor before saving" = "Open this suggestion in the request rewrite editor before saving";
"Open this suggestion in the response transform editor before saving" = "Open this suggestion in the response transform editor before saving";
"Plugins add advisory findings to inspected exchanges. They do not block, rewrite, mock, transform, save settings, or send traffic anywhere by themselves." = "Plugins add advisory findings to inspected exchanges. They do not block, rewrite, mock, transform, save settings, or send traffic anywhere by themselves.";
"Suggests reviewed actions" = "Suggests reviewed actions";
"Plugins are advisory. Installing this package does not let it block, rewrite, mock, transform, save settings, upload, or export traffic." = "Plugins are advisory. Installing this package does not let it block, rewrite, mock, transform, save settings, upload, or export traffic.";
35 changes: 29 additions & 6 deletions Flowlight/Localization/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1488,7 +1488,6 @@
"App identity" = "App identity";
"LLM metadata" = "LLM metadata";
"MCP metadata" = "MCP metadata";
"Suggest guardrails" = "Suggest guardrails";
"Metadata only" = "Metadata only";
"Tool names" = "Tool names";
"Guardrail suggestions" = "Guardrail suggestions";
Expand Down Expand Up @@ -1534,8 +1533,6 @@
"Modify requests" = "Modify requests";
"Modify responses" = "Modify responses";
"Add Guardrail" = "Add Guardrail";
"Save this as a normal Flowlight guardrail" = "Save this as a normal Flowlight guardrail";
"Save this as a normal Flowlight rule" = "Save this as a normal Flowlight rule";
"Plugin findings are advisory. They did not block or change this request." = "Plugin findings are advisory. They did not block or change this request.";
"Let the request reach %@, then change its eligible response before this app receives it" = "Let the request reach %@, then change its eligible response before this app receives it";
"%@ answered this request. Flowlight then changed the response with “%@” before the app received it." = "%@ answered this request. Flowlight then changed the response with “%@” before the app received it.";
Expand Down Expand Up @@ -1566,7 +1563,6 @@
"Content-Length, Connection and Transfer-Encoding are written by Flowlight." = "Content-Length, Connection and Transfer-Encoding are written by Flowlight.";
"Binary · hexadecimal" = "Binary · hexadecimal";
"Each pair of hexadecimal characters is one byte. Flowlight writes the original bytes." = "Each pair of hexadecimal characters is one byte. Flowlight writes the original bytes.";
"Plugins add advisory findings to inspected exchanges. They do not block, rewrite, or send traffic anywhere by themselves." = "Plugins add advisory findings to inspected exchanges. They do not block, rewrite, or send traffic anywhere by themselves.";
"Import Package…" = "Import Package…";
"Backfill Findings" = "Backfill Findings";
"Clear plugin findings…" = "Clear plugin findings…";
Expand All @@ -1589,7 +1585,6 @@
"Backfilled plugin findings: %lld findings." = "Backfilled plugin findings: %lld findings.";
"Backfill failed: %@" = "Backfill failed: %@";
"JavaScript" = "JavaScript";
"Suggests guardrails" = "Suggests guardrails";
"%@ · v%@ · rule v%lld" = "%@ · v%@ · rule v%lld";
"Package %@ · Script %@" = "Package %@ · Script %@";
"Configured: %@" = "Configured: %@";
Expand All @@ -1604,7 +1599,6 @@
"Package digest" = "Package digest";
"Script digest" = "Script digest";
"Permissions" = "Permissions";
"Plugins are advisory. Installing this package does not let it block, rewrite, upload, or export traffic." = "Plugins are advisory. Installing this package does not let it block, rewrite, upload, or export traffic.";
"Install" = "Install";
"Not declared" = "Not declared";
"Configure %@" = "Configure %@";
Expand Down Expand Up @@ -1650,3 +1644,32 @@
"Clear local analyses?" = "Clear local analyses?";
"Clear analyses" = "Clear analyses";
"This removes only local potential-harm scores and explanations. Recorded requests, response bodies, alerts, rules, and inspection settings stay in place." = "This removes only local potential-harm scores and explanations. Recorded requests, response bodies, alerts, rules, and inspection settings stay in place.";

"Suggest reviewed actions" = "Suggest reviewed actions";
"Review guardrail" = "Review guardrail";
"Plugin suggested a normal Flowlight guardrail." = "Plugin suggested a normal Flowlight guardrail.";
"Review rule" = "Review rule";
"Plugin suggested a normal Flowlight rule." = "Plugin suggested a normal Flowlight rule.";
"Plugin suggested a reviewed Flowlight action." = "Plugin suggested a reviewed Flowlight action.";
"Review mock" = "Review mock";
"Review rewrite" = "Review rewrite";
"Review transform" = "Review transform";
"Optional" = "Optional";
"Any server" = "Any server";
"Any tool" = "Any tool";
"Resource" = "Resource";
"Any resource" = "Any resource";
"Saving creates a normal Flowlight guardrail. The plugin cannot save or enforce it by itself." = "Saving creates a normal Flowlight guardrail. The plugin cannot save or enforce it by itself.";
"Review Guardrail" = "Review Guardrail";
"Review Rule" = "Review Rule";
"Review Mock" = "Review Mock";
"Review Rewrite" = "Review Rewrite";
"Review Transform" = "Review Transform";
"Open this suggestion as a normal Flowlight guardrail before saving" = "Open this suggestion as a normal Flowlight guardrail before saving";
"Open this suggestion as a normal Flowlight rule before saving" = "Open this suggestion as a normal Flowlight rule before saving";
"Open this suggestion in the mock response editor before saving" = "Open this suggestion in the mock response editor before saving";
"Open this suggestion in the request rewrite editor before saving" = "Open this suggestion in the request rewrite editor before saving";
"Open this suggestion in the response transform editor before saving" = "Open this suggestion in the response transform editor before saving";
"Plugins add advisory findings to inspected exchanges. They do not block, rewrite, mock, transform, save settings, or send traffic anywhere by themselves." = "Plugins add advisory findings to inspected exchanges. They do not block, rewrite, mock, transform, save settings, or send traffic anywhere by themselves.";
"Suggests reviewed actions" = "Suggests reviewed actions";
"Plugins are advisory. Installing this package does not let it block, rewrite, mock, transform, save settings, upload, or export traffic." = "Plugins are advisory. Installing this package does not let it block, rewrite, mock, transform, save settings, upload, or export traffic.";
35 changes: 29 additions & 6 deletions Flowlight/Localization/es.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1489,7 +1489,6 @@
"App identity" = "App identity";
"LLM metadata" = "LLM metadata";
"MCP metadata" = "MCP metadata";
"Suggest guardrails" = "Suggest guardrails";
"Metadata only" = "Metadata only";
"Tool names" = "Tool names";
"Guardrail suggestions" = "Guardrail suggestions";
Expand Down Expand Up @@ -1535,8 +1534,6 @@
"Modify requests" = "Modify requests";
"Modify responses" = "Modify responses";
"Add Guardrail" = "Add Guardrail";
"Save this as a normal Flowlight guardrail" = "Save this as a normal Flowlight guardrail";
"Save this as a normal Flowlight rule" = "Save this as a normal Flowlight rule";
"Plugin findings are advisory. They did not block or change this request." = "Plugin findings are advisory. They did not block or change this request.";
"Let the request reach %@, then change its eligible response before this app receives it" = "Let the request reach %@, then change its eligible response before this app receives it";
"%@ answered this request. Flowlight then changed the response with “%@” before the app received it." = "%@ answered this request. Flowlight then changed the response with “%@” before the app received it.";
Expand Down Expand Up @@ -1567,7 +1564,6 @@
"Content-Length, Connection and Transfer-Encoding are written by Flowlight." = "Content-Length, Connection and Transfer-Encoding are written by Flowlight.";
"Binary · hexadecimal" = "Binary · hexadecimal";
"Each pair of hexadecimal characters is one byte. Flowlight writes the original bytes." = "Each pair of hexadecimal characters is one byte. Flowlight writes the original bytes.";
"Plugins add advisory findings to inspected exchanges. They do not block, rewrite, or send traffic anywhere by themselves." = "Plugins add advisory findings to inspected exchanges. They do not block, rewrite, or send traffic anywhere by themselves.";
"Import Package…" = "Import Package…";
"Backfill Findings" = "Backfill Findings";
"Clear plugin findings…" = "Clear plugin findings…";
Expand All @@ -1590,7 +1586,6 @@
"Backfilled plugin findings: %lld findings." = "Backfilled plugin findings: %lld findings.";
"Backfill failed: %@" = "Backfill failed: %@";
"JavaScript" = "JavaScript";
"Suggests guardrails" = "Suggests guardrails";
"%@ · v%@ · rule v%lld" = "%@ · v%@ · rule v%lld";
"Package %@ · Script %@" = "Package %@ · Script %@";
"Configured: %@" = "Configured: %@";
Expand All @@ -1605,7 +1600,6 @@
"Package digest" = "Package digest";
"Script digest" = "Script digest";
"Permissions" = "Permissions";
"Plugins are advisory. Installing this package does not let it block, rewrite, upload, or export traffic." = "Plugins are advisory. Installing this package does not let it block, rewrite, upload, or export traffic.";
"Install" = "Install";
"Not declared" = "Not declared";
"Configure %@" = "Configure %@";
Expand Down Expand Up @@ -1651,3 +1645,32 @@
"Clear local analyses?" = "Clear local analyses?";
"Clear analyses" = "Clear analyses";
"This removes only local potential-harm scores and explanations. Recorded requests, response bodies, alerts, rules, and inspection settings stay in place." = "This removes only local potential-harm scores and explanations. Recorded requests, response bodies, alerts, rules, and inspection settings stay in place.";

"Suggest reviewed actions" = "Suggest reviewed actions";
"Review guardrail" = "Review guardrail";
"Plugin suggested a normal Flowlight guardrail." = "Plugin suggested a normal Flowlight guardrail.";
"Review rule" = "Review rule";
"Plugin suggested a normal Flowlight rule." = "Plugin suggested a normal Flowlight rule.";
"Plugin suggested a reviewed Flowlight action." = "Plugin suggested a reviewed Flowlight action.";
"Review mock" = "Review mock";
"Review rewrite" = "Review rewrite";
"Review transform" = "Review transform";
"Optional" = "Optional";
"Any server" = "Any server";
"Any tool" = "Any tool";
"Resource" = "Resource";
"Any resource" = "Any resource";
"Saving creates a normal Flowlight guardrail. The plugin cannot save or enforce it by itself." = "Saving creates a normal Flowlight guardrail. The plugin cannot save or enforce it by itself.";
"Review Guardrail" = "Review Guardrail";
"Review Rule" = "Review Rule";
"Review Mock" = "Review Mock";
"Review Rewrite" = "Review Rewrite";
"Review Transform" = "Review Transform";
"Open this suggestion as a normal Flowlight guardrail before saving" = "Open this suggestion as a normal Flowlight guardrail before saving";
"Open this suggestion as a normal Flowlight rule before saving" = "Open this suggestion as a normal Flowlight rule before saving";
"Open this suggestion in the mock response editor before saving" = "Open this suggestion in the mock response editor before saving";
"Open this suggestion in the request rewrite editor before saving" = "Open this suggestion in the request rewrite editor before saving";
"Open this suggestion in the response transform editor before saving" = "Open this suggestion in the response transform editor before saving";
"Plugins add advisory findings to inspected exchanges. They do not block, rewrite, mock, transform, save settings, or send traffic anywhere by themselves." = "Plugins add advisory findings to inspected exchanges. They do not block, rewrite, mock, transform, save settings, or send traffic anywhere by themselves.";
"Suggests reviewed actions" = "Suggests reviewed actions";
"Plugins are advisory. Installing this package does not let it block, rewrite, mock, transform, save settings, upload, or export traffic." = "Plugins are advisory. Installing this package does not let it block, rewrite, mock, transform, save settings, upload, or export traffic.";
Loading
Loading