@codyswann/lisa 4.10.10 → 4.10.11

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 (67) hide show
  1. package/all/copy-overwrite/scripts/lisa-gates.mjs +2 -1
  2. package/all/copy-overwrite/scripts/lisa-hooks/block-no-verify.sh +18 -3
  3. package/dist/codex/scripts/block-no-verify.sh +13 -2
  4. package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
  5. package/dist/core/lisa-owned-hash-ledger.js +4 -0
  6. package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
  7. package/dist/core/upstream-evidence-manifest.js +4 -4
  8. package/dist/opencode/plugin-templates/block-no-verify.sh +18 -3
  9. package/dist/opencode/plugin-templates/lisa-session-bootstrap.ts +10 -1
  10. package/package.json +1 -1
  11. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  12. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  13. package/plugins/lisa/hooks/block-no-verify.agy.sh +13 -2
  14. package/plugins/lisa/hooks/block-no-verify.sh +18 -3
  15. package/plugins/lisa-agy/hooks/block-no-verify.agy.sh +13 -2
  16. package/plugins/lisa-agy/plugin.json +1 -1
  17. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  18. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  19. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  20. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  21. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  22. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  23. package/plugins/lisa-copilot/hooks/block-no-verify.sh +18 -3
  24. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  25. package/plugins/lisa-cursor/hooks/block-no-verify.sh +18 -3
  26. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  27. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  28. package/plugins/lisa-expo-agy/plugin.json +1 -1
  29. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  30. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  31. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  32. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  33. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  34. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  35. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  36. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  37. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  38. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  39. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  40. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  41. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  42. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  43. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  44. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  45. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  46. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  47. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  48. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  49. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  50. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  51. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  52. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  53. package/plugins/lisa-rails-agy/plugin.json +1 -1
  54. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  55. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  56. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  57. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  58. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  59. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  60. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  61. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  62. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  63. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  64. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  65. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  66. package/plugins/src/base/hooks/block-no-verify.agy.sh +13 -2
  67. package/plugins/src/base/hooks/block-no-verify.sh +18 -3
@@ -3310,7 +3310,8 @@ function verifyRow({ gate, nowMs, observed, policy, row }) {
3310
3310
  }
3311
3311
  }
3312
3312
  const rank = LEVEL_RANK[row.level];
3313
- if (rank === undefined || rank < LEVEL_RANK[gate.level]) {
3313
+ const requiredRank = LEVEL_RANK[gate.level];
3314
+ if (rank === undefined || requiredRank === undefined || rank < requiredRank) {
3314
3315
  return run(
3315
3316
  REUSE_REASON.LEVEL_DOWNGRADE,
3316
3317
  `proved at ${JSON.stringify(row.level ?? null)} but this moment requires ${gate.level}`
@@ -26,7 +26,7 @@
26
26
  # Add a name here in the same commit that closes a vector. A hardening that
27
27
  # forgets to is invisible to refresh, and shows up as an unexplained diff at
28
28
  # review time instead of a named capability.
29
- # lisa-guard-capabilities: no-verify-abbrev, husky-env, hookspath-allowlist, config-env, git-config-key, git-config-parameters, git-config-parameters-append, herestring-aware, no-verify-short
29
+ # lisa-guard-capabilities: no-verify-abbrev, husky-env, hookspath-allowlist, config-env, git-config-key, git-config-parameters, git-config-parameters-append, git-config-parameters-expansion, heredoc-shell-word, herestring-aware, no-verify-short
30
30
  #
31
31
  # Shell-token matching avoids false positives from issue bodies, heredocs, and
32
32
  # commit-message prose while still catching quoted real argv values such as
@@ -104,15 +104,24 @@ def strip_heredocs(text: str) -> str:
104
104
  output = []
105
105
  pending = []
106
106
  marker_pattern = re.compile(
107
- r"(?<!<)<<-?(?!<)\s*(?:'([^']+)'|\"([^\"]+)\"|([A-Za-z_][A-Za-z0-9_]*))"
107
+ r'''(?<!<)<<-?(?!<)\s*((?:'[^']*'|"(?:[^"\\]|\\.)*"|\\.|[^\s;&|<>()])+)'''
108
108
  )
109
+
110
+ def marker_word(raw: str):
111
+ try:
112
+ words = shlex.split(raw, posix=True)
113
+ except ValueError:
114
+ return None
115
+ return words[0] if len(words) == 1 and words[0] else None
116
+
109
117
  index = 0
110
118
  while index < len(lines):
111
119
  line = lines[index]
112
120
  output.append(line)
113
121
  pending.extend(
114
- next(group for group in match.groups() if group)
122
+ marker
115
123
  for match in marker_pattern.finditer(line)
124
+ if (marker := marker_word(match.group(1))) is not None
116
125
  )
117
126
  index += 1
118
127
  while pending and index < len(lines):
@@ -454,6 +463,12 @@ for i, token in enumerate(normalized_tokens):
454
463
  # key from an unrelated value that merely contains the same text.
455
464
  if re.match(r"git_config_parameters\+?=", lowered):
456
465
  parameters = token.split("=", 1)[1]
466
+ # The guard sees the command before the shell expands assignments. A
467
+ # variable or command substitution can therefore hide hooksPath from
468
+ # this parser and reveal it only to Git. Refuse unresolved values; the
469
+ # guard cannot safely prove what configuration they will become.
470
+ if "$" in parameters or "`" in parameters:
471
+ sys.exit(1)
457
472
  try:
458
473
  configured = shlex.split(parameters, posix=True)
459
474
  except ValueError:
@@ -36,15 +36,24 @@ def strip_heredocs(text: str) -> str:
36
36
  output = []
37
37
  pending = []
38
38
  marker_pattern = re.compile(
39
- r"(?<!<)<<-?(?!<)\s*(?:'([^']+)'|\"([^\"]+)\"|([A-Za-z_][A-Za-z0-9_]*))"
39
+ r'''(?<!<)<<-?(?!<)\s*((?:'[^']*'|"(?:[^"\\]|\\.)*"|\\.|[^\s;&|<>()])+)'''
40
40
  )
41
+
42
+ def marker_word(raw: str):
43
+ try:
44
+ words = shlex.split(raw, posix=True)
45
+ except ValueError:
46
+ return None
47
+ return words[0] if len(words) == 1 and words[0] else None
48
+
41
49
  index = 0
42
50
  while index < len(lines):
43
51
  line = lines[index]
44
52
  output.append(line)
45
53
  pending.extend(
46
- next(group for group in match.groups() if group)
54
+ marker
47
55
  for match in marker_pattern.finditer(line)
56
+ if (marker := marker_word(match.group(1))) is not None
48
57
  )
49
58
  index += 1
50
59
  while pending and index < len(lines):
@@ -334,6 +343,8 @@ for i, token in enumerate(normalized_tokens):
334
343
  sys.exit(1)
335
344
  if re.match(r"git_config_parameters\+?=", lowered):
336
345
  parameters = token.split("=", 1)[1]
346
+ if "$" in parameters or "`" in parameters:
347
+ sys.exit(1)
337
348
  try:
338
349
  configured = shlex.split(parameters, posix=True)
339
350
  except ValueError:
@@ -1 +1 @@
1
- {"version":3,"file":"lisa-owned-hash-ledger.d.ts","sourceRoot":"","sources":["../../src/core/lisa-owned-hash-ledger.ts"],"names":[],"mappings":"AACA,6EAA6E;AAE7E;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAC3C,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAqpBjC,CAAC"}
1
+ {"version":3,"file":"lisa-owned-hash-ledger.d.ts","sourceRoot":"","sources":["../../src/core/lisa-owned-hash-ledger.ts"],"names":[],"mappings":"AACA,6EAA6E;AAE7E;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAC3C,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAypBjC,CAAC"}
@@ -350,6 +350,7 @@ export const LISA_OWNED_HASH_LEDGER = Object.freeze({
350
350
  "5b6c9f081f22c5aa098ec05d9a3e8df92ccbdf0b9469d361e3426210cdd25b48",
351
351
  "5d4099e9c6fe5978fba206a069ae6a68d899ef33a57e110ea65e1d4c39328ee1",
352
352
  "5f5eeda36a19fc6b99f621128b192d07ec79e4735b4514c9b20ae94a3e29c4b5",
353
+ "603189360a4c4c99c05ae9f30438396df723122b4698a43859020795fd730341",
353
354
  "60b961b1bd4a01f17fc0c19dd09b2505958bdeaa5c1030868835ac628e77d97f",
354
355
  "6725541cb96461aba72822f4f54071a0163101ea00086b242213f36eb4725a03",
355
356
  "6d9bc1c708a7cc585e7f8c4539ec28e4a29cbfd9a0c08b5a96760f8f0865453d",
@@ -388,9 +389,11 @@ export const LISA_OWNED_HASH_LEDGER = Object.freeze({
388
389
  "c5643655f16b3229646b59cf2ac74edc631959825231a8cf69575cc8268ce0c2",
389
390
  "c72ca4e9859c379aed41669415d826f459c25af94d14360eeb53b5d59bb358a1",
390
391
  "c950082c3a0e7e987a8d32455eb16103cd0516c9b907f551a93395eb2e61d253",
392
+ "c98513dba3aab3a133047c2b33ee215193fe376cec26365f98b742977558c881",
391
393
  "ca8a704ac2da24a2a10a5485e2afff456637167e0324c47ea601036f2ae7d8ec",
392
394
  "cc4270e365f53c60a5eefb58a8ac8e22be184c0821fcdcc8fe67bcfc1df5e3dd",
393
395
  "ccbbab687ee2dbc572726ae187324af34b971075b6c808e1781005b489500429",
396
+ "cd20fcf1ee211b159a3907da73876994f218d0475ea40d03fe36c702c793cc4f",
394
397
  "cd41b2f04be5ba97be8fd6e618e8bccca4c4d0823acbc8e82c239b6d45dfe020",
395
398
  "cebeb1a5a1f87d2f77fb961229be81d9180ab9dafe977559b71d527bf32397c9",
396
399
  "cf47b1251059c245f9e0f2aa35c51b5813b99dd126e369d4911ef4e3c81cd8e0",
@@ -454,6 +457,7 @@ export const LISA_OWNED_HASH_LEDGER = Object.freeze({
454
457
  "031ef7a53fc49cb18665105b834b7b50ad6a43317e0821949809e877e0562ce4",
455
458
  "08399603387ff80240777dffa4b564a9d6ee82e64a329d3790f99ccaf6dbff04",
456
459
  "18b7bb8867c5e6f719a9c503a38525f4c05e3d611717c3e1a503cf58dfb2832f",
460
+ "19ac4c32a9850dceb507dd8aac5a2646478e3ec3bbc1b8c7bf95d647b70a10f1",
457
461
  "19e520180322247dd3ab61c80b13960115ae48ccd739ec3c0b4216cd8a2555a8",
458
462
  "2df476aacebcb2544a12f459a0092e88eb28c0d00e45fd7ed909c75dfe441027",
459
463
  "33e2bd341eb992036059b0c4606db35a218adcfeca7e44d174fedf8ebdff29d2",
@@ -1 +1 @@
1
- {"version":3,"file":"lisa-owned-hash-ledger.js","sourceRoot":"","sources":["../../src/core/lisa-owned-hash-ledger.ts"],"names":[],"mappings":"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EAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAk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"}
1
+ {"version":3,"file":"lisa-owned-hash-ledger.js","sourceRoot":"","sources":["../../src/core/lisa-owned-hash-ledger.ts"],"names":[],"mappings":"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EAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAk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"}
@@ -15,11 +15,11 @@ export const UPSTREAM_EVIDENCE_MANIFEST = Object.freeze({
15
15
  "all/copy-overwrite/scripts/lisa-enforcement-fallback.sh": "b4cc14d5dc02c790ea3e51b0134b9c3d5e4a0e8ef08a652817f7485a0badde17",
16
16
  "all/copy-overwrite/scripts/lisa-environment-prepare.mjs": "5cce1e1cd585d5b82db05c0fcea9fe4e24171f54c3ddba82cde151a97e277745",
17
17
  "all/copy-overwrite/scripts/lisa-floor-collisions.mjs": "41060648b4394d417528f4f560a52f296b4df5b6ec8a5633e08afe4588b6a088",
18
- "all/copy-overwrite/scripts/lisa-gates.mjs": "95d021d8c199001bc669ffe19cc3a54590cc1cfa1524c3e278c410e47dcc4bdb",
18
+ "all/copy-overwrite/scripts/lisa-gates.mjs": "603189360a4c4c99c05ae9f30438396df723122b4698a43859020795fd730341",
19
19
  "all/copy-overwrite/scripts/lisa-hooks/block-direct-issue-create.sh": "2e030d5a394d3edb48c391db49661fb3d45545c85f88ea03d1ab07ad3787c089",
20
20
  "all/copy-overwrite/scripts/lisa-hooks/block-instruction-file-edits.sh": "3e709e1ec8a5843c00684bc477ad32ddab2c5fdb11f71d5aeec0c49609eaf025",
21
21
  "all/copy-overwrite/scripts/lisa-hooks/block-managed-file-edits.sh": "d3ef2562b718156912f0877f8a0668026f5966fcca43eb9e064aa57a4e9a4976",
22
- "all/copy-overwrite/scripts/lisa-hooks/block-no-verify.sh": "19e520180322247dd3ab61c80b13960115ae48ccd739ec3c0b4216cd8a2555a8",
22
+ "all/copy-overwrite/scripts/lisa-hooks/block-no-verify.sh": "19ac4c32a9850dceb507dd8aac5a2646478e3ec3bbc1b8c7bf95d647b70a10f1",
23
23
  "all/copy-overwrite/scripts/lisa-hooks/block-shell-json-parsing.sh": "234cb82cc9033bd04940a553d4ddc95b078e585e41777d6529d887676edc40b1",
24
24
  "all/copy-overwrite/scripts/lisa-hooks/parity-safety-net.sh": "9404c374cbd90a0860410080f1044d087c51d84bb4c0a37343c2b632c3a9d03b",
25
25
  "all/copy-overwrite/scripts/lisa-hooks/sonar-secrets.sh": "f21cdcb54b353714a92c2d1e25fd6b76318e8e8d7cb90cdb016f174923c532ef",
@@ -350,8 +350,8 @@ export const UPSTREAM_EVIDENCE_MANIFEST = Object.freeze({
350
350
  "plugins/src/base/hooks/block-instruction-file-edits.agy.sh": "aa249cae53caeb3e0fb6d6af114e2756084f45a2896332fb063a9f20e4902125",
351
351
  "plugins/src/base/hooks/block-instruction-file-edits.sh": "d47314b66d6ce85f77d6e058f861eede4462b2b0a33d54e82ff1c931167ec3f7",
352
352
  "plugins/src/base/hooks/block-managed-file-edits.sh": "9b566bd1ff465147955300ce66b75c866db461a04dc67866c22bb928c757a616",
353
- "plugins/src/base/hooks/block-no-verify.agy.sh": "e8500ca97fcf1e03c2ad856b8dace475669cf79369538ae5071ef44f90c637c6",
354
- "plugins/src/base/hooks/block-no-verify.sh": "cd7b1c12fb2111e75faa30f979c5f713885a39ce5da1dd1b2a567f5ab57913ac",
353
+ "plugins/src/base/hooks/block-no-verify.agy.sh": "9c432cb57ac40bdb211c9b9641fe079bff5daee64454eb25c70c5203a46dba80",
354
+ "plugins/src/base/hooks/block-no-verify.sh": "e68b81177c5eb62dfe8179c1a86e4a34a442ceef7f64be9f5d2ca0bce0cbf3ad",
355
355
  "plugins/src/base/hooks/block-shell-json-parsing.agy.sh": "dc688efe382e7b8fe6f6c88bb0fde851527128cae778599559f23a93f1c9ec86",
356
356
  "plugins/src/base/hooks/block-shell-json-parsing.sh": "90601e31603c440d8f19d213d63bfef8d18596c60f88cb6e28c93d12453c5c0c",
357
357
  "plugins/src/base/hooks/cleanup-stale-worktrees.sh": "c9b2fcca1b34d6f636b5289ece11b254cbb8ee2c2bac5c2e426b6f4dcfa972f2",
@@ -23,7 +23,7 @@
23
23
  # Add a name here in the same commit that closes a vector. A hardening that
24
24
  # forgets to is invisible to refresh, and shows up as an unexplained diff at
25
25
  # review time instead of a named capability.
26
- # lisa-guard-capabilities: no-verify-abbrev, husky-env, hookspath-allowlist, config-env, git-config-key, git-config-parameters, git-config-parameters-append, herestring-aware, no-verify-short
26
+ # lisa-guard-capabilities: no-verify-abbrev, husky-env, hookspath-allowlist, config-env, git-config-key, git-config-parameters, git-config-parameters-append, git-config-parameters-expansion, heredoc-shell-word, herestring-aware, no-verify-short
27
27
  #
28
28
  # Shell-token matching avoids false positives from issue bodies, heredocs, and
29
29
  # commit-message prose while still catching quoted real argv values such as
@@ -101,15 +101,24 @@ def strip_heredocs(text: str) -> str:
101
101
  output = []
102
102
  pending = []
103
103
  marker_pattern = re.compile(
104
- r"(?<!<)<<-?(?!<)\s*(?:'([^']+)'|\"([^\"]+)\"|([A-Za-z_][A-Za-z0-9_]*))"
104
+ r'''(?<!<)<<-?(?!<)\s*((?:'[^']*'|"(?:[^"\\]|\\.)*"|\\.|[^\s;&|<>()])+)'''
105
105
  )
106
+
107
+ def marker_word(raw: str):
108
+ try:
109
+ words = shlex.split(raw, posix=True)
110
+ except ValueError:
111
+ return None
112
+ return words[0] if len(words) == 1 and words[0] else None
113
+
106
114
  index = 0
107
115
  while index < len(lines):
108
116
  line = lines[index]
109
117
  output.append(line)
110
118
  pending.extend(
111
- next(group for group in match.groups() if group)
119
+ marker
112
120
  for match in marker_pattern.finditer(line)
121
+ if (marker := marker_word(match.group(1))) is not None
113
122
  )
114
123
  index += 1
115
124
  while pending and index < len(lines):
@@ -451,6 +460,12 @@ for i, token in enumerate(normalized_tokens):
451
460
  # key from an unrelated value that merely contains the same text.
452
461
  if re.match(r"git_config_parameters\+?=", lowered):
453
462
  parameters = token.split("=", 1)[1]
463
+ # The guard sees the command before the shell expands assignments. A
464
+ # variable or command substitution can therefore hide hooksPath from
465
+ # this parser and reveal it only to Git. Refuse unresolved values; the
466
+ # guard cannot safely prove what configuration they will become.
467
+ if "$" in parameters or "`" in parameters:
468
+ sys.exit(1)
454
469
  try:
455
470
  configured = shlex.split(parameters, posix=True)
456
471
  except ValueError:
@@ -71,8 +71,17 @@ export const LisaSessionBootstrap = async ({
71
71
  for (const file of [".lisa.config.local.json", ".lisa.config.json"]) {
72
72
  const configPath = `${root}/${file}`;
73
73
  if (!existsSync(configPath)) continue;
74
+ let contents: string;
74
75
  try {
75
- let value: unknown = JSON.parse(readFileSync(configPath, "utf8"));
76
+ contents = readFileSync(configPath, "utf8");
77
+ } catch (error) {
78
+ console.error(
79
+ `lisa-session-bootstrap: ${configPath} could not be read; treating it as absent: ${String(error)}`
80
+ );
81
+ continue;
82
+ }
83
+ try {
84
+ let value: unknown = JSON.parse(contents);
76
85
  for (const key of path) {
77
86
  if (!value || typeof value !== "object" || !(key in value)) {
78
87
  value = undefined;
package/package.json CHANGED
@@ -149,7 +149,7 @@
149
149
  "zod-validation-error": "^4.0.0"
150
150
  },
151
151
  "name": "@codyswann/lisa",
152
- "version": "4.10.10",
152
+ "version": "4.10.11",
153
153
  "description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
154
154
  "main": "dist/index.js",
155
155
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "4.10.10",
3
+ "version": "4.10.11",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "4.10.10",
3
+ "version": "4.10.11",
4
4
  "description": "Universal governance: agents, skills, commands, hooks, and rules for all projects.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -60,15 +60,24 @@ def strip_heredocs(text: str) -> str:
60
60
  output = []
61
61
  pending = []
62
62
  marker_pattern = re.compile(
63
- r"(?<!<)<<-?(?!<)\s*(?:'([^']+)'|\"([^\"]+)\"|([A-Za-z_][A-Za-z0-9_]*))"
63
+ r'''(?<!<)<<-?(?!<)\s*((?:'[^']*'|"(?:[^"\\]|\\.)*"|\\.|[^\s;&|<>()])+)'''
64
64
  )
65
+
66
+ def marker_word(raw: str):
67
+ try:
68
+ words = shlex.split(raw, posix=True)
69
+ except ValueError:
70
+ return None
71
+ return words[0] if len(words) == 1 and words[0] else None
72
+
65
73
  index = 0
66
74
  while index < len(lines):
67
75
  line = lines[index]
68
76
  output.append(line)
69
77
  pending.extend(
70
- next(group for group in match.groups() if group)
78
+ marker
71
79
  for match in marker_pattern.finditer(line)
80
+ if (marker := marker_word(match.group(1))) is not None
72
81
  )
73
82
  index += 1
74
83
  while pending and index < len(lines):
@@ -358,6 +367,8 @@ for i, token in enumerate(normalized_tokens):
358
367
  sys.exit(1)
359
368
  if re.match(r"git_config_parameters\+?=", lowered):
360
369
  parameters = token.split("=", 1)[1]
370
+ if "$" in parameters or "`" in parameters:
371
+ sys.exit(1)
361
372
  try:
362
373
  configured = shlex.split(parameters, posix=True)
363
374
  except ValueError:
@@ -23,7 +23,7 @@
23
23
  # Add a name here in the same commit that closes a vector. A hardening that
24
24
  # forgets to is invisible to refresh, and shows up as an unexplained diff at
25
25
  # review time instead of a named capability.
26
- # lisa-guard-capabilities: no-verify-abbrev, husky-env, hookspath-allowlist, config-env, git-config-key, git-config-parameters, git-config-parameters-append, herestring-aware, no-verify-short
26
+ # lisa-guard-capabilities: no-verify-abbrev, husky-env, hookspath-allowlist, config-env, git-config-key, git-config-parameters, git-config-parameters-append, git-config-parameters-expansion, heredoc-shell-word, herestring-aware, no-verify-short
27
27
  #
28
28
  # Shell-token matching avoids false positives from issue bodies, heredocs, and
29
29
  # commit-message prose while still catching quoted real argv values such as
@@ -101,15 +101,24 @@ def strip_heredocs(text: str) -> str:
101
101
  output = []
102
102
  pending = []
103
103
  marker_pattern = re.compile(
104
- r"(?<!<)<<-?(?!<)\s*(?:'([^']+)'|\"([^\"]+)\"|([A-Za-z_][A-Za-z0-9_]*))"
104
+ r'''(?<!<)<<-?(?!<)\s*((?:'[^']*'|"(?:[^"\\]|\\.)*"|\\.|[^\s;&|<>()])+)'''
105
105
  )
106
+
107
+ def marker_word(raw: str):
108
+ try:
109
+ words = shlex.split(raw, posix=True)
110
+ except ValueError:
111
+ return None
112
+ return words[0] if len(words) == 1 and words[0] else None
113
+
106
114
  index = 0
107
115
  while index < len(lines):
108
116
  line = lines[index]
109
117
  output.append(line)
110
118
  pending.extend(
111
- next(group for group in match.groups() if group)
119
+ marker
112
120
  for match in marker_pattern.finditer(line)
121
+ if (marker := marker_word(match.group(1))) is not None
113
122
  )
114
123
  index += 1
115
124
  while pending and index < len(lines):
@@ -451,6 +460,12 @@ for i, token in enumerate(normalized_tokens):
451
460
  # key from an unrelated value that merely contains the same text.
452
461
  if re.match(r"git_config_parameters\+?=", lowered):
453
462
  parameters = token.split("=", 1)[1]
463
+ # The guard sees the command before the shell expands assignments. A
464
+ # variable or command substitution can therefore hide hooksPath from
465
+ # this parser and reveal it only to Git. Refuse unresolved values; the
466
+ # guard cannot safely prove what configuration they will become.
467
+ if "$" in parameters or "`" in parameters:
468
+ sys.exit(1)
454
469
  try:
455
470
  configured = shlex.split(parameters, posix=True)
456
471
  except ValueError:
@@ -60,15 +60,24 @@ def strip_heredocs(text: str) -> str:
60
60
  output = []
61
61
  pending = []
62
62
  marker_pattern = re.compile(
63
- r"(?<!<)<<-?(?!<)\s*(?:'([^']+)'|\"([^\"]+)\"|([A-Za-z_][A-Za-z0-9_]*))"
63
+ r'''(?<!<)<<-?(?!<)\s*((?:'[^']*'|"(?:[^"\\]|\\.)*"|\\.|[^\s;&|<>()])+)'''
64
64
  )
65
+
66
+ def marker_word(raw: str):
67
+ try:
68
+ words = shlex.split(raw, posix=True)
69
+ except ValueError:
70
+ return None
71
+ return words[0] if len(words) == 1 and words[0] else None
72
+
65
73
  index = 0
66
74
  while index < len(lines):
67
75
  line = lines[index]
68
76
  output.append(line)
69
77
  pending.extend(
70
- next(group for group in match.groups() if group)
78
+ marker
71
79
  for match in marker_pattern.finditer(line)
80
+ if (marker := marker_word(match.group(1))) is not None
72
81
  )
73
82
  index += 1
74
83
  while pending and index < len(lines):
@@ -358,6 +367,8 @@ for i, token in enumerate(normalized_tokens):
358
367
  sys.exit(1)
359
368
  if re.match(r"git_config_parameters\+?=", lowered):
360
369
  parameters = token.split("=", 1)[1]
370
+ if "$" in parameters or "`" in parameters:
371
+ sys.exit(1)
361
372
  try:
362
373
  configured = shlex.split(parameters, posix=True)
363
374
  except ValueError:
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "4.10.10",
3
+ "version": "4.10.11",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "4.10.10",
3
+ "version": "4.10.11",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "4.10.10",
3
+ "version": "4.10.11",
4
4
  "description": "AWS CDK-specific Lisa plugin.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "4.10.10",
3
+ "version": "4.10.11",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "4.10.10",
3
+ "version": "4.10.11",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "4.10.10",
3
+ "version": "4.10.11",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "4.10.10",
3
+ "version": "4.10.11",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -23,7 +23,7 @@
23
23
  # Add a name here in the same commit that closes a vector. A hardening that
24
24
  # forgets to is invisible to refresh, and shows up as an unexplained diff at
25
25
  # review time instead of a named capability.
26
- # lisa-guard-capabilities: no-verify-abbrev, husky-env, hookspath-allowlist, config-env, git-config-key, git-config-parameters, git-config-parameters-append, herestring-aware, no-verify-short
26
+ # lisa-guard-capabilities: no-verify-abbrev, husky-env, hookspath-allowlist, config-env, git-config-key, git-config-parameters, git-config-parameters-append, git-config-parameters-expansion, heredoc-shell-word, herestring-aware, no-verify-short
27
27
  #
28
28
  # Shell-token matching avoids false positives from issue bodies, heredocs, and
29
29
  # commit-message prose while still catching quoted real argv values such as
@@ -101,15 +101,24 @@ def strip_heredocs(text: str) -> str:
101
101
  output = []
102
102
  pending = []
103
103
  marker_pattern = re.compile(
104
- r"(?<!<)<<-?(?!<)\s*(?:'([^']+)'|\"([^\"]+)\"|([A-Za-z_][A-Za-z0-9_]*))"
104
+ r'''(?<!<)<<-?(?!<)\s*((?:'[^']*'|"(?:[^"\\]|\\.)*"|\\.|[^\s;&|<>()])+)'''
105
105
  )
106
+
107
+ def marker_word(raw: str):
108
+ try:
109
+ words = shlex.split(raw, posix=True)
110
+ except ValueError:
111
+ return None
112
+ return words[0] if len(words) == 1 and words[0] else None
113
+
106
114
  index = 0
107
115
  while index < len(lines):
108
116
  line = lines[index]
109
117
  output.append(line)
110
118
  pending.extend(
111
- next(group for group in match.groups() if group)
119
+ marker
112
120
  for match in marker_pattern.finditer(line)
121
+ if (marker := marker_word(match.group(1))) is not None
113
122
  )
114
123
  index += 1
115
124
  while pending and index < len(lines):
@@ -451,6 +460,12 @@ for i, token in enumerate(normalized_tokens):
451
460
  # key from an unrelated value that merely contains the same text.
452
461
  if re.match(r"git_config_parameters\+?=", lowered):
453
462
  parameters = token.split("=", 1)[1]
463
+ # The guard sees the command before the shell expands assignments. A
464
+ # variable or command substitution can therefore hide hooksPath from
465
+ # this parser and reveal it only to Git. Refuse unresolved values; the
466
+ # guard cannot safely prove what configuration they will become.
467
+ if "$" in parameters or "`" in parameters:
468
+ sys.exit(1)
454
469
  try:
455
470
  configured = shlex.split(parameters, posix=True)
456
471
  except ValueError:
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "4.10.10",
3
+ "version": "4.10.11",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -23,7 +23,7 @@
23
23
  # Add a name here in the same commit that closes a vector. A hardening that
24
24
  # forgets to is invisible to refresh, and shows up as an unexplained diff at
25
25
  # review time instead of a named capability.
26
- # lisa-guard-capabilities: no-verify-abbrev, husky-env, hookspath-allowlist, config-env, git-config-key, git-config-parameters, git-config-parameters-append, herestring-aware, no-verify-short
26
+ # lisa-guard-capabilities: no-verify-abbrev, husky-env, hookspath-allowlist, config-env, git-config-key, git-config-parameters, git-config-parameters-append, git-config-parameters-expansion, heredoc-shell-word, herestring-aware, no-verify-short
27
27
  #
28
28
  # Shell-token matching avoids false positives from issue bodies, heredocs, and
29
29
  # commit-message prose while still catching quoted real argv values such as
@@ -101,15 +101,24 @@ def strip_heredocs(text: str) -> str:
101
101
  output = []
102
102
  pending = []
103
103
  marker_pattern = re.compile(
104
- r"(?<!<)<<-?(?!<)\s*(?:'([^']+)'|\"([^\"]+)\"|([A-Za-z_][A-Za-z0-9_]*))"
104
+ r'''(?<!<)<<-?(?!<)\s*((?:'[^']*'|"(?:[^"\\]|\\.)*"|\\.|[^\s;&|<>()])+)'''
105
105
  )
106
+
107
+ def marker_word(raw: str):
108
+ try:
109
+ words = shlex.split(raw, posix=True)
110
+ except ValueError:
111
+ return None
112
+ return words[0] if len(words) == 1 and words[0] else None
113
+
106
114
  index = 0
107
115
  while index < len(lines):
108
116
  line = lines[index]
109
117
  output.append(line)
110
118
  pending.extend(
111
- next(group for group in match.groups() if group)
119
+ marker
112
120
  for match in marker_pattern.finditer(line)
121
+ if (marker := marker_word(match.group(1))) is not None
113
122
  )
114
123
  index += 1
115
124
  while pending and index < len(lines):
@@ -451,6 +460,12 @@ for i, token in enumerate(normalized_tokens):
451
460
  # key from an unrelated value that merely contains the same text.
452
461
  if re.match(r"git_config_parameters\+?=", lowered):
453
462
  parameters = token.split("=", 1)[1]
463
+ # The guard sees the command before the shell expands assignments. A
464
+ # variable or command substitution can therefore hide hooksPath from
465
+ # this parser and reveal it only to Git. Refuse unresolved values; the
466
+ # guard cannot safely prove what configuration they will become.
467
+ if "$" in parameters or "`" in parameters:
468
+ sys.exit(1)
454
469
  try:
455
470
  configured = shlex.split(parameters, posix=True)
456
471
  except ValueError:
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "4.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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.10.10",
3
+ "version": "4.10.11",
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"
@@ -60,15 +60,24 @@ def strip_heredocs(text: str) -> str:
60
60
  output = []
61
61
  pending = []
62
62
  marker_pattern = re.compile(
63
- r"(?<!<)<<-?(?!<)\s*(?:'([^']+)'|\"([^\"]+)\"|([A-Za-z_][A-Za-z0-9_]*))"
63
+ r'''(?<!<)<<-?(?!<)\s*((?:'[^']*'|"(?:[^"\\]|\\.)*"|\\.|[^\s;&|<>()])+)'''
64
64
  )
65
+
66
+ def marker_word(raw: str):
67
+ try:
68
+ words = shlex.split(raw, posix=True)
69
+ except ValueError:
70
+ return None
71
+ return words[0] if len(words) == 1 and words[0] else None
72
+
65
73
  index = 0
66
74
  while index < len(lines):
67
75
  line = lines[index]
68
76
  output.append(line)
69
77
  pending.extend(
70
- next(group for group in match.groups() if group)
78
+ marker
71
79
  for match in marker_pattern.finditer(line)
80
+ if (marker := marker_word(match.group(1))) is not None
72
81
  )
73
82
  index += 1
74
83
  while pending and index < len(lines):
@@ -358,6 +367,8 @@ for i, token in enumerate(normalized_tokens):
358
367
  sys.exit(1)
359
368
  if re.match(r"git_config_parameters\+?=", lowered):
360
369
  parameters = token.split("=", 1)[1]
370
+ if "$" in parameters or "`" in parameters:
371
+ sys.exit(1)
361
372
  try:
362
373
  configured = shlex.split(parameters, posix=True)
363
374
  except ValueError:
@@ -23,7 +23,7 @@
23
23
  # Add a name here in the same commit that closes a vector. A hardening that
24
24
  # forgets to is invisible to refresh, and shows up as an unexplained diff at
25
25
  # review time instead of a named capability.
26
- # lisa-guard-capabilities: no-verify-abbrev, husky-env, hookspath-allowlist, config-env, git-config-key, git-config-parameters, git-config-parameters-append, herestring-aware, no-verify-short
26
+ # lisa-guard-capabilities: no-verify-abbrev, husky-env, hookspath-allowlist, config-env, git-config-key, git-config-parameters, git-config-parameters-append, git-config-parameters-expansion, heredoc-shell-word, herestring-aware, no-verify-short
27
27
  #
28
28
  # Shell-token matching avoids false positives from issue bodies, heredocs, and
29
29
  # commit-message prose while still catching quoted real argv values such as
@@ -101,15 +101,24 @@ def strip_heredocs(text: str) -> str:
101
101
  output = []
102
102
  pending = []
103
103
  marker_pattern = re.compile(
104
- r"(?<!<)<<-?(?!<)\s*(?:'([^']+)'|\"([^\"]+)\"|([A-Za-z_][A-Za-z0-9_]*))"
104
+ r'''(?<!<)<<-?(?!<)\s*((?:'[^']*'|"(?:[^"\\]|\\.)*"|\\.|[^\s;&|<>()])+)'''
105
105
  )
106
+
107
+ def marker_word(raw: str):
108
+ try:
109
+ words = shlex.split(raw, posix=True)
110
+ except ValueError:
111
+ return None
112
+ return words[0] if len(words) == 1 and words[0] else None
113
+
106
114
  index = 0
107
115
  while index < len(lines):
108
116
  line = lines[index]
109
117
  output.append(line)
110
118
  pending.extend(
111
- next(group for group in match.groups() if group)
119
+ marker
112
120
  for match in marker_pattern.finditer(line)
121
+ if (marker := marker_word(match.group(1))) is not None
113
122
  )
114
123
  index += 1
115
124
  while pending and index < len(lines):
@@ -451,6 +460,12 @@ for i, token in enumerate(normalized_tokens):
451
460
  # key from an unrelated value that merely contains the same text.
452
461
  if re.match(r"git_config_parameters\+?=", lowered):
453
462
  parameters = token.split("=", 1)[1]
463
+ # The guard sees the command before the shell expands assignments. A
464
+ # variable or command substitution can therefore hide hooksPath from
465
+ # this parser and reveal it only to Git. Refuse unresolved values; the
466
+ # guard cannot safely prove what configuration they will become.
467
+ if "$" in parameters or "`" in parameters:
468
+ sys.exit(1)
454
469
  try:
455
470
  configured = shlex.split(parameters, posix=True)
456
471
  except ValueError: