@codyswann/lisa 4.10.9 → 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 (88) hide show
  1. package/all/copy-overwrite/scripts/lisa-environment-prepare.mjs +31 -12
  2. package/all/copy-overwrite/scripts/lisa-gates.mjs +2 -1
  3. package/all/copy-overwrite/scripts/lisa-hooks/block-no-verify.sh +18 -3
  4. package/all/copy-overwrite/scripts/lisa-run-gates.mjs +73 -19
  5. package/dist/codex/scripts/block-no-verify.sh +13 -2
  6. package/dist/configs/coverage-scope.d.ts +39 -0
  7. package/dist/configs/coverage-scope.d.ts.map +1 -0
  8. package/dist/configs/coverage-scope.js +41 -0
  9. package/dist/configs/coverage-scope.js.map +1 -0
  10. package/dist/configs/jest/base.d.ts +4 -0
  11. package/dist/configs/jest/base.d.ts.map +1 -1
  12. package/dist/configs/jest/base.js +24 -6
  13. package/dist/configs/jest/base.js.map +1 -1
  14. package/dist/configs/vitest/base.d.ts +23 -0
  15. package/dist/configs/vitest/base.d.ts.map +1 -1
  16. package/dist/configs/vitest/base.js +25 -6
  17. package/dist/configs/vitest/base.js.map +1 -1
  18. package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
  19. package/dist/core/lisa-owned-hash-ledger.js +8 -0
  20. package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
  21. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  22. package/dist/core/upstream-evidence-manifest.js +16 -11
  23. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  24. package/dist/opencode/plugin-templates/block-no-verify.sh +18 -3
  25. package/dist/opencode/plugin-templates/lisa-session-bootstrap.ts +10 -1
  26. package/expo/package-lisa/package.lisa.json +1 -1
  27. package/nestjs/package-lisa/package.lisa.json +1 -1
  28. package/package.json +2 -2
  29. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  30. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  31. package/plugins/lisa/hooks/block-no-verify.agy.sh +13 -2
  32. package/plugins/lisa/hooks/block-no-verify.sh +18 -3
  33. package/plugins/lisa-agy/hooks/block-no-verify.agy.sh +13 -2
  34. package/plugins/lisa-agy/plugin.json +1 -1
  35. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  36. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  37. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  38. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  39. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  40. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  41. package/plugins/lisa-copilot/hooks/block-no-verify.sh +18 -3
  42. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  43. package/plugins/lisa-cursor/hooks/block-no-verify.sh +18 -3
  44. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  45. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  46. package/plugins/lisa-expo-agy/plugin.json +1 -1
  47. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  48. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  49. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  50. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  51. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  52. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  53. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  54. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  55. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  56. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  57. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  58. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  59. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  60. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  61. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  62. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  63. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  64. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  65. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  66. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  67. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  68. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  69. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  70. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  71. package/plugins/lisa-rails-agy/plugin.json +1 -1
  72. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  73. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  74. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  75. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  76. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  77. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  78. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  79. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  80. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  81. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  82. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  83. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  84. package/plugins/src/base/hooks/block-no-verify.agy.sh +13 -2
  85. package/plugins/src/base/hooks/block-no-verify.sh +18 -3
  86. package/typescript/copy-contents/.husky/pre-push +8 -1
  87. package/typescript/copy-overwrite/scripts/lisa-mutation.mjs +19 -1
  88. package/typescript/package-lisa/package.lisa.json +1 -1
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "4.10.9",
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.9",
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.9",
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.9",
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.9",
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.9",
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.9",
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.9",
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.9",
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.9",
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.9",
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.9",
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.9",
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.9",
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.9",
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.9",
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.9",
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:
@@ -545,8 +545,15 @@ fi
545
545
  # without node, whereas jq may legitimately be absent — the audit block above
546
546
  # says so in as many words. Deciding this with jq would hand every jq-less
547
547
  # machine the slow path without a word.
548
+ # The unit script is selected only when it carries LISA_COVERAGE_SCOPE=unit.
549
+ # That marker is not decoration: the threshold factory reads it and enforces the
550
+ # `unit` block, so a `test:cov:unit` without it is measured against the floor
551
+ # written for the FULL suite while running a strictly smaller population. That
552
+ # is a gate whose thresholds describe a different population than the one it
553
+ # measured, and the honest command for such a project is still `test:cov` —
554
+ # slower, but answering to the floor that was configured for what it runs.
548
555
  COVERAGE_SCRIPT="test:cov"
549
- if node -e 'const s=require("./package.json").scripts||{};process.exit(s["test:cov:unit"]?0:1)' >/dev/null 2>&1; then
556
+ if node -e 'const s=require("./package.json").scripts||{};const u=s["test:cov:unit"];process.exit(typeof u==="string"&&u.includes("LISA_COVERAGE_SCOPE=unit")?0:1)' >/dev/null 2>&1; then
550
557
  COVERAGE_SCRIPT="test:cov:unit"
551
558
  fi
552
559
 
@@ -1073,12 +1073,30 @@ export const readGate = cwd => {
1073
1073
 
1074
1074
  /**
1075
1075
  * A boolean environment override, or undefined when unset.
1076
+ *
1077
+ * A variable that is SET BUT EMPTY reads as unset, for the same reason
1078
+ * {@link resolveTimeoutShareCeiling} treats an empty share ceiling that way: an
1079
+ * empty value is what GitHub Actions produces when an unset workflow input is
1080
+ * mapped into `env:` — `MUTATION_ENABLED: ${{ inputs.mutation }}` on a caller
1081
+ * that passes nothing sets the variable to "". The declaration is the caller's
1082
+ * and the emptiness is the harness's, so reading the harness's silence as a
1083
+ * deliberate `false` lets an absent input beat a project whose
1084
+ * `mutation.gate.json` says `enabled: true`. The gate stands down, the run goes
1085
+ * green, and nothing anywhere says the gate was asked to.
1086
+ *
1087
+ * Empty was also the only spelling with that asymmetry: every other unrecognised
1088
+ * value — `"yes"`, `"maybe"` — is an operator writing something, and answering
1089
+ * `false` to it is a real reading of a real input. Nobody types the empty string.
1090
+ *
1091
+ * `false` stays reachable, because `false` stays typeable. What changes is that
1092
+ * disabling a gate has to be asked for in a character rather than arrived at
1093
+ * through an absent one.
1076
1094
  * @param {string} name - Variable name.
1077
1095
  * @returns {boolean | undefined} The override.
1078
1096
  */
1079
1097
  export const envFlag = name => {
1080
1098
  const value = process.env[name];
1081
- if (value === undefined) return undefined;
1099
+ if (value === undefined || value.trim() === "") return undefined;
1082
1100
  return value === "true" || value === "1";
1083
1101
  };
1084
1102
 
@@ -9,7 +9,7 @@
9
9
  "test:unit": "vitest run --exclude='**/integration/**'",
10
10
  "test:integration:lisa": "vitest run '.integration.' 'integration/'",
11
11
  "test:cov": "vitest run --coverage",
12
- "test:cov:unit": "vitest run --coverage --exclude='**/integration/**'",
12
+ "test:cov:unit": "LISA_COVERAGE_SCOPE=unit vitest run --coverage --exclude='**/integration/**'",
13
13
  "test:mutation": "node scripts/lisa-mutation.mjs",
14
14
  "test:watch": "vitest",
15
15
  "lint:fix": "oxlint --fix && eslint . --fix",