@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.
- package/all/copy-overwrite/scripts/lisa-environment-prepare.mjs +31 -12
- package/all/copy-overwrite/scripts/lisa-gates.mjs +2 -1
- package/all/copy-overwrite/scripts/lisa-hooks/block-no-verify.sh +18 -3
- package/all/copy-overwrite/scripts/lisa-run-gates.mjs +73 -19
- package/dist/codex/scripts/block-no-verify.sh +13 -2
- package/dist/configs/coverage-scope.d.ts +39 -0
- package/dist/configs/coverage-scope.d.ts.map +1 -0
- package/dist/configs/coverage-scope.js +41 -0
- package/dist/configs/coverage-scope.js.map +1 -0
- package/dist/configs/jest/base.d.ts +4 -0
- package/dist/configs/jest/base.d.ts.map +1 -1
- package/dist/configs/jest/base.js +24 -6
- package/dist/configs/jest/base.js.map +1 -1
- package/dist/configs/vitest/base.d.ts +23 -0
- package/dist/configs/vitest/base.d.ts.map +1 -1
- package/dist/configs/vitest/base.js +25 -6
- package/dist/configs/vitest/base.js.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.js +8 -0
- package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +16 -11
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/dist/opencode/plugin-templates/block-no-verify.sh +18 -3
- package/dist/opencode/plugin-templates/lisa-session-bootstrap.ts +10 -1
- package/expo/package-lisa/package.lisa.json +1 -1
- package/nestjs/package-lisa/package.lisa.json +1 -1
- package/package.json +2 -2
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/hooks/block-no-verify.agy.sh +13 -2
- package/plugins/lisa/hooks/block-no-verify.sh +18 -3
- package/plugins/lisa-agy/hooks/block-no-verify.agy.sh +13 -2
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/hooks/block-no-verify.sh +18 -3
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/hooks/block-no-verify.sh +18 -3
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/src/base/hooks/block-no-verify.agy.sh +13 -2
- package/plugins/src/base/hooks/block-no-verify.sh +18 -3
- package/typescript/copy-contents/.husky/pre-push +8 -1
- package/typescript/copy-overwrite/scripts/lisa-mutation.mjs +19 -1
- package/typescript/package-lisa/package.lisa.json +1 -1
|
@@ -60,15 +60,24 @@ def strip_heredocs(text: str) -> str:
|
|
|
60
60
|
output = []
|
|
61
61
|
pending = []
|
|
62
62
|
marker_pattern = re.compile(
|
|
63
|
-
r
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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||{};
|
|
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",
|