@codyswann/lisa 4.70.4 → 4.71.0

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 (139) hide show
  1. package/all/copy-overwrite/scripts/lib/automation-provenance-contract.mjs +174 -0
  2. package/all/copy-overwrite/scripts/lib/automation-provenance-local.mjs +279 -0
  3. package/all/copy-overwrite/scripts/lib/gate-failure-diagnosis.mjs +17 -7
  4. package/all/copy-overwrite/scripts/lib/github-attestation-provider.mjs +241 -0
  5. package/all/copy-overwrite/scripts/lib/github-attestation-recovery.mjs +283 -0
  6. package/all/copy-overwrite/scripts/lib/github-attestation-verifier.mjs +244 -0
  7. package/all/copy-overwrite/scripts/lib/npm-update-allocate.mjs +289 -0
  8. package/all/copy-overwrite/scripts/lib/npm-update-authorization.mjs +235 -0
  9. package/all/copy-overwrite/scripts/lib/npm-update-broker-client.mjs +92 -0
  10. package/all/copy-overwrite/scripts/lib/npm-update-checkpoint.mjs +241 -0
  11. package/all/copy-overwrite/scripts/lib/npm-update-contract.mjs +278 -0
  12. package/all/copy-overwrite/scripts/lib/npm-update-controller-broker.mjs +234 -0
  13. package/all/copy-overwrite/scripts/lib/npm-update-controller-factory.mjs +278 -0
  14. package/all/copy-overwrite/scripts/lib/npm-update-controller-recipe.mjs +135 -0
  15. package/all/copy-overwrite/scripts/lib/npm-update-execution-adapter.mjs +292 -0
  16. package/all/copy-overwrite/scripts/lib/npm-update-gate-hooks.mjs +214 -0
  17. package/all/copy-overwrite/scripts/lib/npm-update-gate-install.mjs +267 -0
  18. package/all/copy-overwrite/scripts/lib/npm-update-gate-proof.mjs +99 -0
  19. package/all/copy-overwrite/scripts/lib/npm-update-gate.mjs +300 -0
  20. package/all/copy-overwrite/scripts/lib/npm-update-gh-dispatch.mjs +182 -0
  21. package/all/copy-overwrite/scripts/lib/npm-update-gh-grants.mjs +156 -0
  22. package/all/copy-overwrite/scripts/lib/npm-update-gh-requests.mjs +221 -0
  23. package/all/copy-overwrite/scripts/lib/npm-update-github.mjs +214 -0
  24. package/all/copy-overwrite/scripts/lib/npm-update-helper-graph.mjs +238 -0
  25. package/all/copy-overwrite/scripts/lib/npm-update-helper-inventory.mjs +126 -0
  26. package/all/copy-overwrite/scripts/lib/npm-update-helper.mjs +292 -0
  27. package/all/copy-overwrite/scripts/lib/npm-update-hook-installation.mjs +116 -0
  28. package/all/copy-overwrite/scripts/lib/npm-update-hook-preload.mjs +153 -0
  29. package/all/copy-overwrite/scripts/lib/npm-update-hook-provider.mjs +207 -0
  30. package/all/copy-overwrite/scripts/lib/npm-update-hook-read-client.mjs +164 -0
  31. package/all/copy-overwrite/scripts/lib/npm-update-hosted-gate.mjs +272 -0
  32. package/all/copy-overwrite/scripts/lib/npm-update-hosted-hook.mjs +157 -0
  33. package/all/copy-overwrite/scripts/lib/npm-update-invariants.mjs +28 -0
  34. package/all/copy-overwrite/scripts/lib/npm-update-isolation.mjs +11 -0
  35. package/all/copy-overwrite/scripts/lib/npm-update-leaf-contract.mjs +171 -0
  36. package/all/copy-overwrite/scripts/lib/npm-update-leaf.mjs +194 -0
  37. package/all/copy-overwrite/scripts/lib/npm-update-native-process.mjs +155 -0
  38. package/all/copy-overwrite/scripts/lib/npm-update-npm.mjs +190 -0
  39. package/all/copy-overwrite/scripts/lib/npm-update-object.mjs +112 -0
  40. package/all/copy-overwrite/scripts/lib/npm-update-orchestrator.mjs +273 -0
  41. package/all/copy-overwrite/scripts/lib/npm-update-owner.mjs +292 -0
  42. package/all/copy-overwrite/scripts/lib/npm-update-prepare.mjs +263 -0
  43. package/all/copy-overwrite/scripts/lib/npm-update-process-core.mjs +179 -0
  44. package/all/copy-overwrite/scripts/lib/npm-update-process.mjs +16 -0
  45. package/all/copy-overwrite/scripts/lib/npm-update-publication.mjs +258 -0
  46. package/all/copy-overwrite/scripts/lib/npm-update-publish.mjs +258 -0
  47. package/all/copy-overwrite/scripts/lib/npm-update-quality.mjs +153 -0
  48. package/all/copy-overwrite/scripts/lib/npm-update-recovery.mjs +264 -0
  49. package/all/copy-overwrite/scripts/lib/npm-update-runtime-archive.mjs +204 -0
  50. package/all/copy-overwrite/scripts/lib/npm-update-runtime-graph.mjs +185 -0
  51. package/all/copy-overwrite/scripts/lib/npm-update-runtime-transport.mjs +221 -0
  52. package/all/copy-overwrite/scripts/lib/npm-update-runtime.mjs +284 -0
  53. package/all/copy-overwrite/scripts/lib/npm-update-tool-launcher.mjs +287 -0
  54. package/all/copy-overwrite/scripts/lib/npm-update-worker-environment.mjs +161 -0
  55. package/all/copy-overwrite/scripts/lib/npm-update-worker-inspection.mjs +142 -0
  56. package/all/copy-overwrite/scripts/lib/npm-update-worker-lifecycle.mjs +256 -0
  57. package/all/copy-overwrite/scripts/lib/npm-update-worker-policy.mjs +266 -0
  58. package/all/copy-overwrite/scripts/lib/process-tree-runner.mjs +230 -36
  59. package/all/copy-overwrite/scripts/lisa-automation-provenance.mjs +161 -0
  60. package/all/copy-overwrite/scripts/lisa-hooks/block-no-verify.sh +89 -5
  61. package/all/copy-overwrite/scripts/lisa-npm-updater.mjs +204 -0
  62. package/all/copy-overwrite/scripts/lisa-run-gates.mjs +48 -123
  63. package/all/copy-overwrite/scripts/lisa-work-item.mjs +107 -41
  64. package/all/copy-overwrite/scripts/npm-updater-gate-runtime.json +1 -0
  65. package/all/copy-overwrite/scripts/npm-updater-gate-supervisor.c +121 -0
  66. package/all/copy-overwrite/scripts/npm-updater-gate.Dockerfile +49 -0
  67. package/all/copy-overwrite/scripts/npm-updater-helper-graph.json +1085 -0
  68. package/dist/codex/scripts/block-no-verify.sh +89 -5
  69. package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
  70. package/dist/core/lisa-owned-hash-ledger.js +598 -0
  71. package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
  72. package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
  73. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  74. package/dist/core/upstream-evidence-manifest.js +157 -11
  75. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  76. package/dist/opencode/plugin-templates/block-no-verify.sh +89 -5
  77. package/package.json +4 -4
  78. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  79. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  80. package/plugins/lisa/hooks/block-no-verify.agy.sh +89 -5
  81. package/plugins/lisa/hooks/block-no-verify.sh +89 -5
  82. package/plugins/lisa-agy/hooks/block-no-verify.agy.sh +89 -5
  83. package/plugins/lisa-agy/plugin.json +1 -1
  84. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  85. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  86. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  87. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  88. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  89. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  90. package/plugins/lisa-copilot/hooks/block-no-verify.sh +89 -5
  91. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  92. package/plugins/lisa-cursor/hooks/block-no-verify.sh +89 -5
  93. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  94. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  95. package/plugins/lisa-expo-agy/plugin.json +1 -1
  96. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  97. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  98. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  99. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  100. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  101. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  102. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  103. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  104. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  105. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  106. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  107. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  108. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  109. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  110. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  111. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  112. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  113. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  114. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  115. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  116. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  117. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  118. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  119. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  120. package/plugins/lisa-rails-agy/plugin.json +1 -1
  121. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  122. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  123. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  124. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  125. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  126. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  127. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  128. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  129. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  130. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  131. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  132. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  133. package/plugins/src/base/hooks/block-no-verify.agy.sh +89 -5
  134. package/plugins/src/base/hooks/block-no-verify.sh +89 -5
  135. package/scripts/check-shipped-surface-removals.mjs +96 -24
  136. package/scripts/generate-npm-updater-helper-graph.mjs +184 -0
  137. package/scripts/two-channel-couplings.json +31 -7
  138. package/typescript/copy-contents/.husky/commit-msg +18 -0
  139. package/typescript/copy-overwrite/.prettierignore +2 -0
@@ -152,6 +152,7 @@ fi
152
152
 
153
153
  if ! BLOCK_NO_VERIFY_COMMAND="$command_str" python3 - <<'PY'
154
154
  import os
155
+ import io
155
156
  import re
156
157
  import shlex
157
158
  import sys
@@ -1284,6 +1285,57 @@ def git_skips_verification(text, depth=0):
1284
1285
  return False
1285
1286
 
1286
1287
 
1288
+ def git_config_reads_key(tokens, index):
1289
+ """Whether this key is a read operand of this exact Git config invocation.
1290
+
1291
+ Keep the command boundary: a query cannot authorize the next command or
1292
+ turn a later setting into a read. Unknown options remain conservative.
1293
+ """
1294
+ start = index
1295
+ while start > 0 and tokens[start - 1] not in COMMAND_SEPARATORS:
1296
+ start -= 1
1297
+ end = index + 1
1298
+ while end < len(tokens) and tokens[end] not in COMMAND_SEPARATORS:
1299
+ end += 1
1300
+ program, args, opaque = command_word(tokens[start:end])
1301
+ if opaque or program != "git":
1302
+ return False
1303
+ found = subcommand_after_git(args, 0)
1304
+ if not found or found[0] != "config":
1305
+ return False
1306
+ argv = found[1]
1307
+ key_offset = index - (end - len(argv))
1308
+ read = bool(argv and argv[0] == "get")
1309
+ cursor = 1 if read else 0
1310
+ operands = []
1311
+ read_actions = {"--get", "--get-all", "--get-regexp", "--get-urlmatch"}
1312
+ modifiers = {
1313
+ "--local", "--global", "--system", "--worktree", "--includes",
1314
+ "--no-includes", "--show-origin", "--show-scope", "--null", "-z",
1315
+ "--name-only", "--all", "--regexp",
1316
+ }
1317
+ value_options = {"--file", "-f", "--blob", "--type", "--default", "--value"}
1318
+ while cursor < len(argv):
1319
+ token = argv[cursor]
1320
+ if token in read_actions:
1321
+ if read:
1322
+ return False
1323
+ read = True
1324
+ elif token in value_options:
1325
+ if cursor + 1 >= len(argv):
1326
+ return False
1327
+ cursor += 1
1328
+ elif token in modifiers:
1329
+ pass
1330
+ elif token.startswith("-"):
1331
+ if not any(token.startswith(option + "=") for option in value_options):
1332
+ return False
1333
+ else:
1334
+ operands.append(cursor)
1335
+ cursor += 1
1336
+ return bool(operands and operands[0] == key_offset and (read or len(operands) == 1))
1337
+
1338
+
1287
1339
  def token_bypass(tokens):
1288
1340
  """Whether any token disables hooks by environment or by git config.
1289
1341
 
@@ -1295,7 +1347,7 @@ def token_bypass(tokens):
1295
1347
  option, and an option belongs to an argv.
1296
1348
 
1297
1349
  Args:
1298
- tokens: Punctuation-stripped tokens of one command or script.
1350
+ tokens: Operator-aware tokens of one command or script.
1299
1351
 
1300
1352
  Returns:
1301
1353
  True when a token disables verification.
@@ -1321,7 +1373,9 @@ def token_bypass(tokens):
1321
1373
  if lowered.startswith("core.hookspath="):
1322
1374
  if not is_permitted_hooks_path(token.split("=", 1)[1]):
1323
1375
  return True
1324
- if lowered == "core.hookspath" and i + 1 < len(tokens):
1376
+ if (lowered == "core.hookspath" and i + 1 < len(tokens)
1377
+ and tokens[i + 1] not in COMMAND_SEPARATORS
1378
+ and not git_config_reads_key(tokens, i)):
1325
1379
  if not is_permitted_hooks_path(tokens[i + 1]):
1326
1380
  return True
1327
1381
  # `git --config-env=core.hooksPath=SOMEVAR` sets the same config, reading
@@ -1388,8 +1442,22 @@ def token_bypass(tokens):
1388
1442
  return False
1389
1443
 
1390
1444
 
1445
+ class OperatorStream(io.StringIO):
1446
+ """Remember punctuation read while shlex is inside a quote or escape."""
1447
+
1448
+ lexer = None
1449
+ literal_operator = False
1450
+
1451
+ def read(self, size=-1):
1452
+ value = super().read(size)
1453
+ if (self.lexer is not None and self.lexer.state in {"'", '"', "\\"}
1454
+ and any(char in "();|&<>" for char in value)):
1455
+ self.literal_operator = True
1456
+ return value
1457
+
1458
+
1391
1459
  def flat_tokens(text):
1392
- """Punctuation-stripped tokens, or None when the text does not lex.
1460
+ """Operator-aware tokens without printed data, or None on a lex failure.
1393
1461
 
1394
1462
  Args:
1395
1463
  text: A command line or a script's contents.
@@ -1398,9 +1466,25 @@ def flat_tokens(text):
1398
1466
  The token list, or None.
1399
1467
  """
1400
1468
  try:
1401
- tokens = shell_tokens(text)
1469
+ stream = OperatorStream(line_boundaries_as_separators(text))
1470
+ lexer = shlex.shlex(stream, posix=True, punctuation_chars=True)
1471
+ lexer.whitespace_split = True
1472
+ lexer.commenters = ""
1473
+ stream.lexer = lexer
1474
+ tokens = []
1475
+ while True:
1476
+ stream.literal_operator = False
1477
+ token = lexer.get_token()
1478
+ if token is None:
1479
+ break
1480
+ # shlex otherwise makes quoted ";" indistinguishable from a real
1481
+ # command boundary. Keep literal destinations as data, so a setter
1482
+ # cannot masquerade as a one-operand configuration read.
1483
+ if token in COMMAND_SEPARATORS and stream.literal_operator:
1484
+ token = "\x00" + token
1485
+ tokens.append(token)
1402
1486
  return [
1403
- token.strip("();|&")
1487
+ token
1404
1488
  for index, token in enumerate(tokens)
1405
1489
  if not printed_argument(tokens, index)
1406
1490
  ]
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -152,6 +152,7 @@ fi
152
152
 
153
153
  if ! BLOCK_NO_VERIFY_COMMAND="$command_str" python3 - <<'PY'
154
154
  import os
155
+ import io
155
156
  import re
156
157
  import shlex
157
158
  import sys
@@ -1284,6 +1285,57 @@ def git_skips_verification(text, depth=0):
1284
1285
  return False
1285
1286
 
1286
1287
 
1288
+ def git_config_reads_key(tokens, index):
1289
+ """Whether this key is a read operand of this exact Git config invocation.
1290
+
1291
+ Keep the command boundary: a query cannot authorize the next command or
1292
+ turn a later setting into a read. Unknown options remain conservative.
1293
+ """
1294
+ start = index
1295
+ while start > 0 and tokens[start - 1] not in COMMAND_SEPARATORS:
1296
+ start -= 1
1297
+ end = index + 1
1298
+ while end < len(tokens) and tokens[end] not in COMMAND_SEPARATORS:
1299
+ end += 1
1300
+ program, args, opaque = command_word(tokens[start:end])
1301
+ if opaque or program != "git":
1302
+ return False
1303
+ found = subcommand_after_git(args, 0)
1304
+ if not found or found[0] != "config":
1305
+ return False
1306
+ argv = found[1]
1307
+ key_offset = index - (end - len(argv))
1308
+ read = bool(argv and argv[0] == "get")
1309
+ cursor = 1 if read else 0
1310
+ operands = []
1311
+ read_actions = {"--get", "--get-all", "--get-regexp", "--get-urlmatch"}
1312
+ modifiers = {
1313
+ "--local", "--global", "--system", "--worktree", "--includes",
1314
+ "--no-includes", "--show-origin", "--show-scope", "--null", "-z",
1315
+ "--name-only", "--all", "--regexp",
1316
+ }
1317
+ value_options = {"--file", "-f", "--blob", "--type", "--default", "--value"}
1318
+ while cursor < len(argv):
1319
+ token = argv[cursor]
1320
+ if token in read_actions:
1321
+ if read:
1322
+ return False
1323
+ read = True
1324
+ elif token in value_options:
1325
+ if cursor + 1 >= len(argv):
1326
+ return False
1327
+ cursor += 1
1328
+ elif token in modifiers:
1329
+ pass
1330
+ elif token.startswith("-"):
1331
+ if not any(token.startswith(option + "=") for option in value_options):
1332
+ return False
1333
+ else:
1334
+ operands.append(cursor)
1335
+ cursor += 1
1336
+ return bool(operands and operands[0] == key_offset and (read or len(operands) == 1))
1337
+
1338
+
1287
1339
  def token_bypass(tokens):
1288
1340
  """Whether any token disables hooks by environment or by git config.
1289
1341
 
@@ -1295,7 +1347,7 @@ def token_bypass(tokens):
1295
1347
  option, and an option belongs to an argv.
1296
1348
 
1297
1349
  Args:
1298
- tokens: Punctuation-stripped tokens of one command or script.
1350
+ tokens: Operator-aware tokens of one command or script.
1299
1351
 
1300
1352
  Returns:
1301
1353
  True when a token disables verification.
@@ -1321,7 +1373,9 @@ def token_bypass(tokens):
1321
1373
  if lowered.startswith("core.hookspath="):
1322
1374
  if not is_permitted_hooks_path(token.split("=", 1)[1]):
1323
1375
  return True
1324
- if lowered == "core.hookspath" and i + 1 < len(tokens):
1376
+ if (lowered == "core.hookspath" and i + 1 < len(tokens)
1377
+ and tokens[i + 1] not in COMMAND_SEPARATORS
1378
+ and not git_config_reads_key(tokens, i)):
1325
1379
  if not is_permitted_hooks_path(tokens[i + 1]):
1326
1380
  return True
1327
1381
  # `git --config-env=core.hooksPath=SOMEVAR` sets the same config, reading
@@ -1388,8 +1442,22 @@ def token_bypass(tokens):
1388
1442
  return False
1389
1443
 
1390
1444
 
1445
+ class OperatorStream(io.StringIO):
1446
+ """Remember punctuation read while shlex is inside a quote or escape."""
1447
+
1448
+ lexer = None
1449
+ literal_operator = False
1450
+
1451
+ def read(self, size=-1):
1452
+ value = super().read(size)
1453
+ if (self.lexer is not None and self.lexer.state in {"'", '"', "\\"}
1454
+ and any(char in "();|&<>" for char in value)):
1455
+ self.literal_operator = True
1456
+ return value
1457
+
1458
+
1391
1459
  def flat_tokens(text):
1392
- """Punctuation-stripped tokens, or None when the text does not lex.
1460
+ """Operator-aware tokens without printed data, or None on a lex failure.
1393
1461
 
1394
1462
  Args:
1395
1463
  text: A command line or a script's contents.
@@ -1398,9 +1466,25 @@ def flat_tokens(text):
1398
1466
  The token list, or None.
1399
1467
  """
1400
1468
  try:
1401
- tokens = shell_tokens(text)
1469
+ stream = OperatorStream(line_boundaries_as_separators(text))
1470
+ lexer = shlex.shlex(stream, posix=True, punctuation_chars=True)
1471
+ lexer.whitespace_split = True
1472
+ lexer.commenters = ""
1473
+ stream.lexer = lexer
1474
+ tokens = []
1475
+ while True:
1476
+ stream.literal_operator = False
1477
+ token = lexer.get_token()
1478
+ if token is None:
1479
+ break
1480
+ # shlex otherwise makes quoted ";" indistinguishable from a real
1481
+ # command boundary. Keep literal destinations as data, so a setter
1482
+ # cannot masquerade as a one-operand configuration read.
1483
+ if token in COMMAND_SEPARATORS and stream.literal_operator:
1484
+ token = "\x00" + token
1485
+ tokens.append(token)
1402
1486
  return [
1403
- token.strip("();|&")
1487
+ token
1404
1488
  for index, token in enumerate(tokens)
1405
1489
  if not printed_argument(tokens, index)
1406
1490
  ]
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "Expo and React Native-specific skills, agents, rules, and MCP servers.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "Harper/Fabric-specific Lisa rules for TypeScript component apps.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "NestJS-specific skills and migration write-protection hooks.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, across Claude and Codex.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "Ruby on Rails-specific skills and hooks for RuboCop and ast-grep scanning on edit.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "TypeScript-specific hooks for formatting, linting, and ast-grep scanning on edit.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "Distributable LLM Wiki kernel — ingest, query, lint, and maintain a git-native markdown knowledge base across Claude and Codex.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "4.70.4",
3
+ "version": "4.71.0",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"