@codyswann/lisa 2.222.2 → 2.222.3

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 (77) hide show
  1. package/dist/opencode/hooks-installer.d.ts.map +1 -1
  2. package/dist/opencode/hooks-installer.js +23 -2
  3. package/dist/opencode/hooks-installer.js.map +1 -1
  4. package/dist/opencode/plugin-templates/lisa-parity-safety-net.ts +43 -0
  5. package/dist/opencode/plugin-templates/parity-safety-net-heredoc.py +417 -0
  6. package/dist/opencode/plugin-templates/parity-safety-net.sh +155 -0
  7. package/dist/opencode/support-file-resolver.d.ts +8 -0
  8. package/dist/opencode/support-file-resolver.d.ts.map +1 -0
  9. package/dist/opencode/support-file-resolver.js +16 -0
  10. package/dist/opencode/support-file-resolver.js.map +1 -0
  11. package/package.json +1 -1
  12. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  13. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  14. package/plugins/lisa/hooks/parity-safety-net-heredoc.py +417 -0
  15. package/plugins/lisa/hooks/parity-safety-net.agy.sh +50 -0
  16. package/plugins/lisa/hooks/parity-safety-net.sh +33 -51
  17. package/plugins/lisa-agy/hooks/parity-safety-net-heredoc.py +417 -0
  18. package/plugins/lisa-agy/hooks/parity-safety-net.agy.sh +50 -0
  19. package/plugins/lisa-agy/hooks/parity-safety-net.sh +155 -0
  20. package/plugins/lisa-agy/hooks.json +13 -0
  21. package/plugins/lisa-agy/plugin.json +1 -1
  22. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  23. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  24. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  25. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  26. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  27. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  28. package/plugins/lisa-copilot/hooks/parity-safety-net-heredoc.py +417 -0
  29. package/plugins/lisa-copilot/hooks/parity-safety-net.sh +33 -51
  30. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  31. package/plugins/lisa-cursor/hooks/parity-safety-net-heredoc.py +417 -0
  32. package/plugins/lisa-cursor/hooks/parity-safety-net.sh +33 -51
  33. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  34. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  35. package/plugins/lisa-expo-agy/plugin.json +1 -1
  36. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  37. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  38. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  39. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  40. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  41. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  42. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  43. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  44. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  45. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  46. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  47. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  48. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  49. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  50. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  51. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  52. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  53. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  54. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  55. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  56. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  57. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  58. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  59. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  60. package/plugins/lisa-rails-agy/plugin.json +1 -1
  61. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  62. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  63. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  64. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  65. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  66. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  67. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  68. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  69. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  70. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  71. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  72. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  73. package/plugins/src/base/hooks/parity-safety-net-heredoc.py +417 -0
  74. package/plugins/src/base/hooks/parity-safety-net.agy.sh +50 -0
  75. package/plugins/src/base/hooks/parity-safety-net.sh +33 -51
  76. package/scripts/copy-opencode-plugin-templates.mjs +12 -0
  77. package/scripts/generate-agy-plugin-artifacts.mjs +24 -10
@@ -1 +1 @@
1
- {"version":3,"file":"hooks-installer.d.ts","sourceRoot":"","sources":["../../src/opencode/hooks-installer.ts"],"names":[],"mappings":"AAuCA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAKrD,gFAAgF;AAChF,eAAO,MAAM,sBAAsB,WAAW,CAAC;AAE/C,sEAAsE;AACtE,eAAO,MAAM,wBAAwB,kBAAkB,CAAC;AAKxD,wEAAwE;AACxE,eAAO,MAAM,0BAA0B,eAAe,CAAC;AAEvD,2EAA2E;AAC3E,eAAO,MAAM,gCAAgC,oCAAoE,CAAC;AA8DlH,gDAAgD;AAChD,MAAM,WAAW,0BAA0B;IACzC,uEAAuE;IACvE,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,mEAAmE;IACnE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,6EAA6E;IAC7E,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,yEAAyE;IACzE,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,SAAS,WAAW,EAAE,EACrC,oBAAoB,EAAE,SAAS,MAAM,EAAE,GACtC,OAAO,CAAC,0BAA0B,CAAC,CA6CrC;AAgGD;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAyCpE;AAiGD;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAa5B"}
1
+ {"version":3,"file":"hooks-installer.d.ts","sourceRoot":"","sources":["../../src/opencode/hooks-installer.ts"],"names":[],"mappings":"AAuCA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAMrD,gFAAgF;AAChF,eAAO,MAAM,sBAAsB,WAAW,CAAC;AAE/C,sEAAsE;AACtE,eAAO,MAAM,wBAAwB,kBAAkB,CAAC;AAKxD,wEAAwE;AACxE,eAAO,MAAM,0BAA0B,eAAe,CAAC;AAEvD,2EAA2E;AAC3E,eAAO,MAAM,gCAAgC,oCAAoE,CAAC;AAyElH,gDAAgD;AAChD,MAAM,WAAW,0BAA0B;IACzC,uEAAuE;IACvE,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,mEAAmE;IACnE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,6EAA6E;IAC7E,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,yEAAyE;IACzE,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,SAAS,WAAW,EAAE,EACrC,oBAAoB,EAAE,SAAS,MAAM,EAAE,GACtC,OAAO,CAAC,0BAA0B,CAAC,CAyDrC;AAgGD;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAyCpE;AAiGD;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAa5B"}
@@ -35,6 +35,7 @@ import { applyEdits, modify, parse as parseJsonc, } from "jsonc-parser";
35
35
  import { mirrorLisaRules } from "../core/lisa-rules-mirror.js";
36
36
  import { OPENCODE_CONFIG_DIR } from "./manifest.js";
37
37
  import { OPENCODE_SCHEMA_URL } from "./settings-installer.js";
38
+ import { resolveSupportFile } from "./support-file-resolver.js";
38
39
  /** Subdirectory inside `.opencode/` where OpenCode discovers project plugins */
39
40
  export const OPENCODE_PLUGIN_SUBDIR = "plugin";
40
41
  /** Filename of the OpenCode project config merged at the host root */
@@ -62,6 +63,11 @@ const NO_VERIFY_DENY_PATTERNS = {
62
63
  * plugin? Drop a template in `plugin-templates/`, add an entry here, add tests.
63
64
  */
64
65
  const PLUGIN_CATALOG = [
66
+ {
67
+ id: "parity-safety-net",
68
+ templateFilename: "lisa-parity-safety-net.ts",
69
+ forProjectTypes: ["*"],
70
+ },
65
71
  {
66
72
  id: "session-bootstrap",
67
73
  templateFilename: "lisa-session-bootstrap.ts",
@@ -93,6 +99,11 @@ const PLUGIN_CATALOG = [
93
99
  forProjectTypes: ["rails"],
94
100
  },
95
101
  ];
102
+ /** Canonical policy files used by universal OpenCode adapters. */
103
+ const PLUGIN_SUPPORT_FILES = [
104
+ "parity-safety-net.sh",
105
+ "parity-safety-net-heredoc.py",
106
+ ];
96
107
  /**
97
108
  * Install Lisa's OpenCode hooks: merge `permission.bash` deny rules into
98
109
  * `opencode.json`, mirror Lisa rule files for `instructions`, and emit the
@@ -118,16 +129,26 @@ export async function installHooks(lisaDir, destDir, detectedTypes, previousMana
118
129
  const pluginDir = path.join(destDir, OPENCODE_CONFIG_DIR, OPENCODE_PLUGIN_SUBDIR);
119
130
  await fse.ensureDir(pluginDir);
120
131
  const applicable = filterCatalogByTypes(detectedTypes);
121
- const managedFiles = await Promise.all(applicable.map(async (entry) => {
132
+ const managedPlugins = await Promise.all(applicable.map(async (entry) => {
122
133
  const source = resolveTemplate(entry.templateFilename);
123
134
  const dest = path.join(pluginDir, entry.templateFilename);
124
135
  await copyFile(source, dest);
125
136
  return path.join(OPENCODE_PLUGIN_SUBDIR, entry.templateFilename);
126
137
  }));
138
+ const managedSupportFiles = await Promise.all(PLUGIN_SUPPORT_FILES.map(async (filename) => {
139
+ const source = resolveSupportFile(import.meta.url, filename);
140
+ const dest = path.join(pluginDir, filename);
141
+ await copyFile(source, dest);
142
+ return path.join(OPENCODE_PLUGIN_SUBDIR, filename);
143
+ }));
127
144
  const currentFilenames = new Set(applicable.map(entry => entry.templateFilename));
128
145
  const deleted = await deleteStalePlugins(previousManagedFiles, currentFilenames, destDir);
129
146
  return {
130
- managedFiles: Object.freeze([...managedFiles, ...ruleFiles]),
147
+ managedFiles: Object.freeze([
148
+ ...managedPlugins,
149
+ ...managedSupportFiles,
150
+ ...ruleFiles,
151
+ ]),
131
152
  pluginCount: applicable.length,
132
153
  configCreated,
133
154
  deleted,
@@ -1 +1 @@
1
- {"version":3,"file":"hooks-installer.js","sourceRoot":"","sources":["../../src/opencode/hooks-installer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hooks-installer.js","sourceRoot":"","sources":["../../src/opencode/hooks-installer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Lisa-managed OpenCode plugin (tool.execute.before).
3
+ *
4
+ * This adapter converts OpenCode's `bash` tool input to Lisa's canonical
5
+ * Claude Bash-hook envelope, runs the canonical parity-safety-net.sh copied
6
+ * beside this module, and surfaces its denial reason. Policy stays single-
7
+ * sourced in the shell hook and its heredoc parser.
8
+ *
9
+ * NOTE: Lisa copies this template verbatim into `.opencode/plugin/`. It runs
10
+ * under OpenCode's Bun runtime and is excluded from this repository's tsconfig.
11
+ */
12
+ export const LisaParitySafetyNet = async () => ({
13
+ "tool.execute.before": async (
14
+ input: { tool: string },
15
+ output: { args?: { command?: string } }
16
+ ) => {
17
+ if (input.tool !== "bash") return;
18
+ const command = String(output.args?.command ?? "");
19
+ if (!command) return;
20
+
21
+ const hookPath = `${import.meta.dir}/parity-safety-net.sh`;
22
+ const processHandle = Bun.spawn(["/bin/bash", hookPath], {
23
+ env: { ...process.env, CLAUDE_PROJECT_DIR: process.cwd() },
24
+ stdin: "pipe",
25
+ stdout: "ignore",
26
+ stderr: "pipe",
27
+ });
28
+ processHandle.stdin.write(
29
+ JSON.stringify({ tool_name: "Bash", tool_input: { command } })
30
+ );
31
+ processHandle.stdin.end();
32
+
33
+ const [status, reason] = await Promise.all([
34
+ processHandle.exited,
35
+ new Response(processHandle.stderr).text(),
36
+ ]);
37
+ if (status === 0) return;
38
+ throw new Error(
39
+ reason.trim() ||
40
+ "Blocked by safety-net: the canonical safety policy failed closed."
41
+ );
42
+ },
43
+ });
@@ -0,0 +1,417 @@
1
+ #!/usr/bin/env python3
2
+ """Classify the only heredoc forms whose payload is non-executable text."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import re
7
+ import shlex
8
+ import sys
9
+ from dataclasses import dataclass
10
+
11
+ SAFE = 0
12
+ UNSUPPORTED = 10
13
+ MALFORMED = 20
14
+
15
+ DELIMITER = r"(?P<delimiter>[A-Za-z_][A-Za-z0-9_]*)"
16
+ BODY_CAT_MARKER = re.compile(
17
+ r"(?P<prefix>.*(?:^|\s)--body\s+)\"\$\(cat\s+<<'"
18
+ + DELIMITER
19
+ + r"'\s*$"
20
+ )
21
+ ALLOWED_GROUPS = {"issue", "pr"}
22
+ ALLOWED_ACTIONS = {"create", "edit", "comment"}
23
+
24
+
25
+ @dataclass(frozen=True)
26
+ class Marker:
27
+ start: int
28
+ end: int
29
+ delimiter: str
30
+ strip_tabs: bool
31
+
32
+
33
+ def shell_tokens(prefix: str) -> list[str] | None:
34
+ """Return literal simple-command tokens, rejecting executable shell syntax."""
35
+ state = "plain"
36
+ escaped = False
37
+ index = 0
38
+ while index < len(prefix):
39
+ char = prefix[index]
40
+ if escaped:
41
+ escaped = False
42
+ elif state == "single":
43
+ if char == "'":
44
+ state = "plain"
45
+ elif state == "double":
46
+ if char == '"':
47
+ state = "plain"
48
+ elif char == "\\":
49
+ escaped = True
50
+ elif char == "`" or (
51
+ char == "$"
52
+ and index + 1 < len(prefix)
53
+ and prefix[index + 1] in "([{"):
54
+ return None
55
+ elif char == "'":
56
+ state = "single"
57
+ elif char == '"':
58
+ state = "double"
59
+ elif char == "\\":
60
+ escaped = True
61
+ elif char == "#" and (index == 0 or prefix[index - 1].isspace()):
62
+ return None
63
+ elif char in ";|&()<>`\n\r":
64
+ return None
65
+ elif char == "$" and index + 1 < len(prefix) and prefix[index + 1] in "([{":
66
+ return None
67
+ index += 1
68
+
69
+ if state != "plain" or escaped:
70
+ return None
71
+ try:
72
+ return shlex.split(prefix, comments=False, posix=True)
73
+ except ValueError:
74
+ return None
75
+
76
+
77
+ def is_allowed_gh(tokens: list[str]) -> bool:
78
+ return (
79
+ len(tokens) >= 3
80
+ and tokens[0] == "gh"
81
+ and tokens[1] in ALLOWED_GROUPS
82
+ and tokens[2] in ALLOWED_ACTIONS
83
+ )
84
+
85
+
86
+ def line_has_allowed_writer(line: str) -> bool:
87
+ """Find a writer after shell quote-concatenation and control operators."""
88
+ try:
89
+ lexer = shlex.shlex(line, posix=True, punctuation_chars=";&|()")
90
+ lexer.whitespace_split = True
91
+ lexer.commenters = "#"
92
+ tokens = list(lexer)
93
+ except ValueError:
94
+ return False
95
+ return any(
96
+ is_allowed_gh(tokens[index : index + 3])
97
+ for index in range(max(0, len(tokens) - 2))
98
+ )
99
+
100
+
101
+ def has_body_file_stdin(tokens: list[str]) -> bool:
102
+ return "--body-file=-" in tokens or any(
103
+ tokens[index : index + 2] == ["--body-file", "-"]
104
+ for index in range(len(tokens) - 1)
105
+ )
106
+
107
+
108
+ def exact_terminator(lines: list[str], delimiter: str, start: int) -> int | None:
109
+ for index in range(start, len(lines)):
110
+ if lines[index] == delimiter:
111
+ return index
112
+ return None
113
+
114
+
115
+ def only_whitespace(lines: list[str], start: int) -> bool:
116
+ return all(not line.strip() for line in lines[start:])
117
+
118
+
119
+ def classify_safe(command: str) -> str | None:
120
+ lines = command.splitlines()
121
+ if len(lines) < 2 or "\x00" in command or "\r" in command:
122
+ return None
123
+
124
+ header = lines[0]
125
+ body_cat = BODY_CAT_MARKER.search(header)
126
+ if body_cat is not None:
127
+ tokens = shell_tokens(body_cat.group("prefix"))
128
+ if tokens is None or not is_allowed_gh(tokens):
129
+ return None
130
+ terminator = exact_terminator(lines, body_cat.group("delimiter"), 1)
131
+ if terminator is None:
132
+ raise ValueError("unclosed body cat heredoc")
133
+ if terminator + 1 >= len(lines) or lines[terminator + 1].strip() != ')"':
134
+ raise ValueError("body cat substitution is not closed exactly")
135
+ if not only_whitespace(lines, terminator + 2):
136
+ raise ValueError("command follows body cat heredoc")
137
+ return body_cat.group("prefix") + '"<heredoc-text>"'
138
+
139
+ header_markers = top_level_markers(header)
140
+ if len(header_markers) != 1:
141
+ return None
142
+ direct = header_markers[0]
143
+ raw_marker = header[direct.start : direct.end]
144
+ if raw_marker != f"<<'{direct.delimiter}'" or header[direct.end :].strip():
145
+ return None
146
+ prefix = header[: direct.start]
147
+ tokens = shell_tokens(prefix)
148
+ if tokens is None or not is_allowed_gh(tokens) or not has_body_file_stdin(tokens):
149
+ return None
150
+ terminator = exact_terminator(lines, direct.delimiter, 1)
151
+ if terminator is None:
152
+ raise ValueError("unclosed direct heredoc")
153
+ if not only_whitespace(lines, terminator + 1):
154
+ raise ValueError("command follows direct heredoc")
155
+ return prefix.rstrip()
156
+
157
+
158
+ def top_level_markers(command: str) -> list[Marker]:
159
+ """Find conservative top-level markers for malformed/duplicate detection."""
160
+ markers: list[Marker] = []
161
+ lines = command.splitlines()
162
+ offset = 0
163
+ for line in lines:
164
+ state = "plain"
165
+ escaped = False
166
+ index = 0
167
+ while index < len(line):
168
+ char = line[index]
169
+ if escaped:
170
+ escaped = False
171
+ elif state == "single":
172
+ if char == "'":
173
+ state = "plain"
174
+ elif state == "double":
175
+ if char == '"':
176
+ state = "plain"
177
+ elif char == "\\":
178
+ escaped = True
179
+ elif char == "'":
180
+ state = "single"
181
+ elif char == '"':
182
+ state = "double"
183
+ elif char == "\\":
184
+ escaped = True
185
+ elif char == "#" and (index == 0 or line[index - 1].isspace()):
186
+ break
187
+ elif line.startswith("<<", index) and not line.startswith("<<<", index):
188
+ marker = parse_marker(line, index, offset)
189
+ if marker is not None:
190
+ markers.append(marker)
191
+ index = marker.end - offset - 1
192
+ index += 1
193
+ offset += len(line) + 1
194
+ return markers
195
+
196
+
197
+ def unquoted_code_and_comment(line: str) -> tuple[str, str]:
198
+ """Return executable text and any shell comment, hiding quoted prose."""
199
+ code: list[str] = []
200
+ state = "plain"
201
+ escaped = False
202
+ index = 0
203
+ while index < len(line):
204
+ char = line[index]
205
+ if escaped:
206
+ code.append(" ")
207
+ escaped = False
208
+ elif state == "single":
209
+ code.append(" ")
210
+ if char == "'":
211
+ state = "plain"
212
+ elif state == "double":
213
+ code.append(" ")
214
+ if char == '"':
215
+ state = "plain"
216
+ elif char == "\\":
217
+ escaped = True
218
+ elif char == "'":
219
+ code.append(" ")
220
+ state = "single"
221
+ elif char == '"':
222
+ code.append(" ")
223
+ state = "double"
224
+ elif char == "\\":
225
+ code.append(" ")
226
+ escaped = True
227
+ elif char == "#" and (index == 0 or line[index - 1].isspace()):
228
+ return "".join(code), line[index + 1 :]
229
+ else:
230
+ code.append(char)
231
+ index += 1
232
+ return "".join(code), ""
233
+
234
+
235
+ def collapse_line_continuations(command: str) -> str:
236
+ """Remove Bash backslash-newline pairs outside single-quoted text."""
237
+ result: list[str] = []
238
+ state = "plain"
239
+ escaped = False
240
+ index = 0
241
+ while index < len(command):
242
+ char = command[index]
243
+ if escaped:
244
+ result.append(char)
245
+ escaped = False
246
+ elif state == "single":
247
+ result.append(char)
248
+ if char == "'":
249
+ state = "plain"
250
+ elif char == "\\" and command.startswith("\n", index + 1):
251
+ index += 2
252
+ continue
253
+ elif char == "\\":
254
+ result.append(char)
255
+ escaped = True
256
+ elif char == "'" and state == "plain":
257
+ result.append(char)
258
+ state = "single"
259
+ elif char == '"':
260
+ result.append(char)
261
+ state = "plain" if state == "double" else "double"
262
+ else:
263
+ result.append(char)
264
+ index += 1
265
+ return "".join(result)
266
+
267
+
268
+ def writer_owns_real_marker(command: str, markers: list[Marker]) -> bool:
269
+ """Detect a supported writer on a line containing a real heredoc marker."""
270
+ logical_command = collapse_line_continuations(command)
271
+ logical_markers = (
272
+ markers if logical_command == command else top_level_markers(logical_command)
273
+ )
274
+ lines = logical_command.splitlines()
275
+ for marker in logical_markers:
276
+ line_index = logical_command.count("\n", 0, marker.start)
277
+ if line_has_allowed_writer(lines[line_index]):
278
+ return True
279
+ return False
280
+
281
+
282
+ def writer_has_commented_marker_and_following_code(command: str) -> bool:
283
+ """Reject fake writer markers whose following lines would execute."""
284
+ lines = command.splitlines()
285
+ for index, line in enumerate(lines):
286
+ _code, comment = unquoted_code_and_comment(line)
287
+ if (
288
+ line_has_allowed_writer(line)
289
+ and "<<" in comment
290
+ and any(candidate.strip() for candidate in lines[index + 1 :])
291
+ ):
292
+ return True
293
+ return False
294
+
295
+
296
+ def has_active_command_substitution(command: str) -> bool:
297
+ """Detect substitutions outside single-quoted text and shell comments."""
298
+ state = "plain"
299
+ escaped = False
300
+ index = 0
301
+ while index < len(command):
302
+ char = command[index]
303
+ if escaped:
304
+ escaped = False
305
+ elif state == "single":
306
+ if char == "'":
307
+ state = "plain"
308
+ elif state == "double":
309
+ if char == '"':
310
+ state = "plain"
311
+ elif char == "\\":
312
+ escaped = True
313
+ elif char == "`" or command.startswith("$(", index):
314
+ return True
315
+ elif char == "'":
316
+ state = "single"
317
+ elif char == '"':
318
+ state = "double"
319
+ elif char == "\\":
320
+ escaped = True
321
+ elif char == "#" and (
322
+ index == 0 or command[index - 1].isspace()
323
+ ):
324
+ newline = command.find("\n", index)
325
+ if newline < 0:
326
+ return False
327
+ index = newline
328
+ elif char == "`" or command.startswith("$(", index):
329
+ return True
330
+ index += 1
331
+ return False
332
+
333
+
334
+ def parse_marker(line: str, start: int, offset: int) -> Marker | None:
335
+ index = start + 2
336
+ strip_tabs = False
337
+ if index < len(line) and line[index] == "-":
338
+ strip_tabs = True
339
+ index += 1
340
+ while index < len(line) and line[index] in " \t":
341
+ index += 1
342
+ if index >= len(line):
343
+ return None
344
+ quote = line[index] if line[index] in "'\"" else None
345
+ if quote:
346
+ index += 1
347
+ end = line.find(quote, index)
348
+ if end < 0:
349
+ return None
350
+ delimiter = line[index:end]
351
+ final = end + 1
352
+ else:
353
+ match = re.match(r"[A-Za-z_][A-Za-z0-9_]*", line[index:])
354
+ if match is None:
355
+ return None
356
+ delimiter = match.group(0)
357
+ final = index + len(delimiter)
358
+ if not delimiter:
359
+ return None
360
+ return Marker(offset + start, offset + final, delimiter, strip_tabs)
361
+
362
+
363
+ def marker_is_closed(command: str, marker: Marker) -> bool:
364
+ marker_line = command.count("\n", 0, marker.start)
365
+ lines = command.splitlines()
366
+ for line in lines[marker_line + 1 :]:
367
+ candidate = line.lstrip("\t") if marker.strip_tabs else line
368
+ if candidate == marker.delimiter:
369
+ return True
370
+ return False
371
+
372
+
373
+ def main() -> int:
374
+ command = sys.stdin.read()
375
+ if "<<" not in command:
376
+ print(command, end="")
377
+ return SAFE
378
+ try:
379
+ sanitized = classify_safe(command)
380
+ except ValueError:
381
+ return MALFORMED
382
+ if sanitized is not None:
383
+ print(sanitized, end="")
384
+ return SAFE
385
+
386
+ logical_command = collapse_line_continuations(command)
387
+ markers = top_level_markers(logical_command)
388
+ if writer_has_commented_marker_and_following_code(logical_command):
389
+ return MALFORMED
390
+ if writer_owns_real_marker(logical_command, markers):
391
+ return MALFORMED
392
+ # Textual operators inside quotes or comments are not heredocs. Leave the
393
+ # raw command unchanged so ordinary guard matching proceeds normally.
394
+ if not markers and not has_active_command_substitution(logical_command):
395
+ return UNSUPPORTED
396
+
397
+ # A supported writer that failed the exact safe grammar is ambiguous: do
398
+ # not let chaining, alternate redirects, or an expanding delimiter turn a
399
+ # would-be payload exemption into a bypass.
400
+ if logical_command.splitlines() and line_has_allowed_writer(
401
+ logical_command.splitlines()[0]
402
+ ):
403
+ return MALFORMED
404
+
405
+ # Nested substitution plus a heredoc is executable shell syntax unless it
406
+ # matched the one exact quoted `--body "$(cat ...)"` form above.
407
+ if has_active_command_substitution(logical_command):
408
+ return MALFORMED
409
+ if len(markers) > 1:
410
+ return MALFORMED
411
+ if markers and not marker_is_closed(logical_command, markers[0]):
412
+ return MALFORMED
413
+ return UNSUPPORTED
414
+
415
+
416
+ if __name__ == "__main__":
417
+ raise SystemExit(main())