@codyswann/lisa 1.81.2 → 1.81.4
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/dist/utils/ignore-patterns.d.ts.map +1 -1
- package/dist/utils/ignore-patterns.js +25 -10
- package/dist/utils/ignore-patterns.js.map +1 -1
- package/expo/copy-overwrite/knip.json +0 -1
- package/expo/package-lisa/package.lisa.json +0 -1
- package/package.json +1 -1
- package/plugins/lisa/.claude-plugin/plugin.json +1 -5
- package/plugins/lisa/rules/intent-routing.md +5 -5
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/src/base/.claude-plugin/plugin.json +0 -4
- package/plugins/src/base/rules/intent-routing.md +5 -5
- package/scripts/test-intent-routing.sh +4 -4
- package/typescript/copy-overwrite/audit.ignore.config.json +5 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ignore-patterns.d.ts","sourceRoot":"","sources":["../../src/utils/ignore-patterns.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ignore-patterns.d.ts","sourceRoot":"","sources":["../../src/utils/ignore-patterns.ts"],"names":[],"mappings":"AAyCA;;GAEG;AACH,eAAO,MAAM,mBAAmB,gBAAgB,CAAC;AAEjD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,iCAAiC;IACjC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,iDAAiD;IACjD,QAAQ,CAAC,YAAY,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC;CAC1D;AAsED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,cAAc,CAAC,CAkBzB"}
|
|
@@ -1,13 +1,28 @@
|
|
|
1
1
|
import { readFile } from "node:fs/promises";
|
|
2
2
|
import * as path from "node:path";
|
|
3
|
-
// minimatch
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
|
|
3
|
+
// minimatch is imported as a namespace to support both v3 (CJS) and v9+ (ESM)
|
|
4
|
+
// interoperably. In downstream projects, bun may hoist whichever version a
|
|
5
|
+
// transitive dependency requires (e.g. @ts-morph/common pulls v10), so Lisa
|
|
6
|
+
// cannot assume a specific export shape:
|
|
7
|
+
// - v3: CJS `module.exports = fn` — ESM interop exposes as `.default`
|
|
8
|
+
// - v9+: Native ESM with a named `minimatch` export and no default
|
|
9
|
+
// The `minimatchFn` local below picks whichever callable the resolved version
|
|
10
|
+
// provides so Lisa works regardless of which minimatch is hoisted top-level.
|
|
11
|
+
import * as minimatchModule from "minimatch";
|
|
10
12
|
import { pathExists } from "./file-operations.js";
|
|
13
|
+
/**
|
|
14
|
+
* Resolve the minimatch predicate across v3 (CJS default export) and v9+
|
|
15
|
+
* (native ESM named export). Throws if neither is available so callers see
|
|
16
|
+
* a clear error instead of "undefined is not a function" at match time.
|
|
17
|
+
*/
|
|
18
|
+
const minimatchFn = (() => {
|
|
19
|
+
const mod = minimatchModule;
|
|
20
|
+
const candidate = typeof mod.default === "function" ? mod.default : mod.minimatch;
|
|
21
|
+
if (typeof candidate !== "function") {
|
|
22
|
+
throw new TypeError("minimatch module did not expose a callable export; expected v3 default or v9+ named export");
|
|
23
|
+
}
|
|
24
|
+
return candidate;
|
|
25
|
+
})();
|
|
11
26
|
/**
|
|
12
27
|
* Name of the ignore file that projects can use to skip Lisa files
|
|
13
28
|
*/
|
|
@@ -49,18 +64,18 @@ function matchesAnyPattern(relativePath, patterns) {
|
|
|
49
64
|
return true;
|
|
50
65
|
}
|
|
51
66
|
// Handle glob patterns
|
|
52
|
-
if (
|
|
67
|
+
if (minimatchFn(normalizedPath, pattern, { dot: true })) {
|
|
53
68
|
return true;
|
|
54
69
|
}
|
|
55
70
|
// Handle patterns that should match anywhere in path
|
|
56
71
|
if (!pattern.includes("/")) {
|
|
57
72
|
// Pattern without slashes matches any path segment
|
|
58
73
|
const segments = normalizedPath.split("/");
|
|
59
|
-
return segments.some(segment =>
|
|
74
|
+
return segments.some(segment => minimatchFn(segment, pattern, { dot: true }));
|
|
60
75
|
}
|
|
61
76
|
// Handle patterns starting with **/ (match anywhere)
|
|
62
77
|
if (pattern.startsWith("**/")) {
|
|
63
|
-
return
|
|
78
|
+
return minimatchFn(normalizedPath, pattern, { dot: true });
|
|
64
79
|
}
|
|
65
80
|
return false;
|
|
66
81
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ignore-patterns.js","sourceRoot":"","sources":["../../src/utils/ignore-patterns.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,
|
|
1
|
+
{"version":3,"file":"ignore-patterns.js","sourceRoot":"","sources":["../../src/utils/ignore-patterns.ts"],"names":[],"mappings":"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"}
|
|
@@ -106,7 +106,6 @@
|
|
|
106
106
|
"react-native-reanimated": "~4.2.1",
|
|
107
107
|
"react-native-safe-area-context": "^5.6.2",
|
|
108
108
|
"react-native-screens": "~4.19.0",
|
|
109
|
-
"react-native-store-version": "^1.4.1",
|
|
110
109
|
"react-native-svg": "^15.15.1",
|
|
111
110
|
"react-native-web": "^0.21.2",
|
|
112
111
|
"tailwindcss": "^3.4.7",
|
package/package.json
CHANGED
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"lodash": ">=4.18.1"
|
|
77
77
|
},
|
|
78
78
|
"name": "@codyswann/lisa",
|
|
79
|
-
"version": "1.81.
|
|
79
|
+
"version": "1.81.4",
|
|
80
80
|
"description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
|
|
81
81
|
"main": "dist/index.js",
|
|
82
82
|
"exports": {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa",
|
|
3
|
-
"version": "1.81.
|
|
3
|
+
"version": "1.81.4",
|
|
4
4
|
"description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -13,10 +13,6 @@
|
|
|
13
13
|
{
|
|
14
14
|
"type": "command",
|
|
15
15
|
"command": "command -v entire >/dev/null 2>&1 && entire hooks claude-code user-prompt-submit || true"
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
"type": "prompt",
|
|
19
|
-
"prompt": "Classify this user request into exactly one flow. Output ONLY valid JSON.\n\nFlows:\n- Research: User needs requirements defined, wants a PRD, exploring a problem space, open-ended feature idea\n- Plan: User has requirements and wants them broken into tickets/work items\n- Implement/Build: User has a specific feature/story/task to code\n- Implement/Fix: User has a bug to fix, something is broken\n- Implement/Improve: User wants to refactor, optimize, or improve existing code\n- Implement/Investigate: User wants to understand why something works a certain way (spike)\n- Verify: User has code ready to ship (PR, deploy, merge)\n- None: Simple question, config change, one-off task, or not enough context to classify\n\nOutput format: {\"hookSpecificOutput\":{\"hookEventName\":\"UserPromptSubmit\",\"additionalContext\":\"Flow classification: [FLOW]. Reason: [one sentence].\"}}\n\nUser request: $ARGUMENTS"
|
|
20
16
|
}
|
|
21
17
|
]
|
|
22
18
|
}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
# Intent Routing
|
|
2
2
|
|
|
3
|
-
MANDATORY:
|
|
3
|
+
MANDATORY: On the **first user message of a session**, classify the request using the Flow Classification Protocol below and state the chosen flow before doing any other work. Do not respond to the substance of the request, do not start work, do not ask questions until you have stated which flow applies. Once a flow is established, treat it as fixed for the remainder of the session — **do not re-classify on subsequent messages**, even if a follow-up looks vague or conversational ("wait, what did you just do?", "now run the tests", "thanks"). Subsequent messages operate within the established flow unless the user explicitly changes scope. Skipping classification leads to unstructured responses that bypass readiness gates.
|
|
4
4
|
|
|
5
5
|
Each flow has a readiness gate that MUST pass before work begins. If the gate fails, stop and ask for what is missing.
|
|
6
6
|
|
|
7
7
|
## Flow Classification Protocol
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
This protocol runs **once per session**, on the first user message. After that, every later message inherits the established flow — do not re-run classification.
|
|
10
10
|
|
|
11
11
|
1. If the user invoked a slash command (`/fix`, `/build`, `/plan`, etc.), the flow is already determined -- skip classification.
|
|
12
|
-
2.
|
|
13
|
-
3. If
|
|
12
|
+
2. Read the user's request and match it against the flow definitions below.
|
|
13
|
+
3. If you cannot confidently classify the request:
|
|
14
14
|
- **Interactive session** (user is present): present a multiple choice using AskUserQuestion with options: Research, Plan, Implement, Verify, No flow.
|
|
15
15
|
- **Headless/non-interactive session** (running with `-p` flag, in a CI pipeline, or as a scheduled agent): do NOT ask the user. Classify to the best of your ability from available context (ticket content, prompt text, current branch state). If you truly cannot classify, default to "No flow" and proceed with the request as-is.
|
|
16
|
-
4. Once a flow is selected, check its readiness gate before proceeding.
|
|
16
|
+
4. Once a flow is selected, state it explicitly (e.g., *"Flow: Implement/Fix"*) and check its readiness gate before proceeding.
|
|
17
17
|
5. If you are a subagent: your parent agent has already determined the flow -- do NOT ask the user to choose a flow. Execute your assigned work within the established flow context.
|
|
18
18
|
|
|
19
19
|
## Readiness Gate Protocol
|
|
@@ -11,10 +11,6 @@
|
|
|
11
11
|
{
|
|
12
12
|
"type": "command",
|
|
13
13
|
"command": "command -v entire >/dev/null 2>&1 && entire hooks claude-code user-prompt-submit || true"
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
"type": "prompt",
|
|
17
|
-
"prompt": "Classify this user request into exactly one flow. Output ONLY valid JSON.\n\nFlows:\n- Research: User needs requirements defined, wants a PRD, exploring a problem space, open-ended feature idea\n- Plan: User has requirements and wants them broken into tickets/work items\n- Implement/Build: User has a specific feature/story/task to code\n- Implement/Fix: User has a bug to fix, something is broken\n- Implement/Improve: User wants to refactor, optimize, or improve existing code\n- Implement/Investigate: User wants to understand why something works a certain way (spike)\n- Verify: User has code ready to ship (PR, deploy, merge)\n- None: Simple question, config change, one-off task, or not enough context to classify\n\nOutput format: {\"hookSpecificOutput\":{\"hookEventName\":\"UserPromptSubmit\",\"additionalContext\":\"Flow classification: [FLOW]. Reason: [one sentence].\"}}\n\nUser request: $ARGUMENTS"
|
|
18
14
|
}
|
|
19
15
|
]
|
|
20
16
|
}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
# Intent Routing
|
|
2
2
|
|
|
3
|
-
MANDATORY:
|
|
3
|
+
MANDATORY: On the **first user message of a session**, classify the request using the Flow Classification Protocol below and state the chosen flow before doing any other work. Do not respond to the substance of the request, do not start work, do not ask questions until you have stated which flow applies. Once a flow is established, treat it as fixed for the remainder of the session — **do not re-classify on subsequent messages**, even if a follow-up looks vague or conversational ("wait, what did you just do?", "now run the tests", "thanks"). Subsequent messages operate within the established flow unless the user explicitly changes scope. Skipping classification leads to unstructured responses that bypass readiness gates.
|
|
4
4
|
|
|
5
5
|
Each flow has a readiness gate that MUST pass before work begins. If the gate fails, stop and ask for what is missing.
|
|
6
6
|
|
|
7
7
|
## Flow Classification Protocol
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
This protocol runs **once per session**, on the first user message. After that, every later message inherits the established flow — do not re-run classification.
|
|
10
10
|
|
|
11
11
|
1. If the user invoked a slash command (`/fix`, `/build`, `/plan`, etc.), the flow is already determined -- skip classification.
|
|
12
|
-
2.
|
|
13
|
-
3. If
|
|
12
|
+
2. Read the user's request and match it against the flow definitions below.
|
|
13
|
+
3. If you cannot confidently classify the request:
|
|
14
14
|
- **Interactive session** (user is present): present a multiple choice using AskUserQuestion with options: Research, Plan, Implement, Verify, No flow.
|
|
15
15
|
- **Headless/non-interactive session** (running with `-p` flag, in a CI pipeline, or as a scheduled agent): do NOT ask the user. Classify to the best of your ability from available context (ticket content, prompt text, current branch state). If you truly cannot classify, default to "No flow" and proceed with the request as-is.
|
|
16
|
-
4. Once a flow is selected, check its readiness gate before proceeding.
|
|
16
|
+
4. Once a flow is selected, state it explicitly (e.g., *"Flow: Implement/Fix"*) and check its readiness gate before proceeding.
|
|
17
17
|
5. If you are a subagent: your parent agent has already determined the flow -- do NOT ask the user to choose a flow. Execute your assigned work within the established flow context.
|
|
18
18
|
|
|
19
19
|
## Readiness Gate Protocol
|
|
@@ -146,11 +146,11 @@ else
|
|
|
146
146
|
fail "plugin.json is not valid JSON"
|
|
147
147
|
fi
|
|
148
148
|
|
|
149
|
-
# Check
|
|
150
|
-
if jq -e '.hooks.UserPromptSubmit[].hooks[] | select(.type == "prompt")' "$PLUGIN_JSON" >/dev/null 2>&1; then
|
|
151
|
-
pass "
|
|
149
|
+
# Check user-prompt-submit command hook is registered in UserPromptSubmit
|
|
150
|
+
if jq -e '.hooks.UserPromptSubmit[].hooks[] | select(.type == "command" and (.command | test("user-prompt-submit")))' "$PLUGIN_JSON" >/dev/null 2>&1; then
|
|
151
|
+
pass "user-prompt-submit command hook registered in UserPromptSubmit"
|
|
152
152
|
else
|
|
153
|
-
fail "
|
|
153
|
+
fail "user-prompt-submit command hook not found in UserPromptSubmit"
|
|
154
154
|
fi
|
|
155
155
|
|
|
156
156
|
# Check inject-flow-context is registered in SubagentStart
|
|
@@ -87,6 +87,11 @@
|
|
|
87
87
|
"id": "GHSA-36jr-mh4h-2g58",
|
|
88
88
|
"package": "d3-color",
|
|
89
89
|
"reason": "ReDoS — transitive via react-native-svg-charts, color parsing not user-controlled"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"id": "GHSA-chqc-8p9q-pq6q",
|
|
93
|
+
"package": "basic-ftp",
|
|
94
|
+
"reason": "FTP command injection via CRLF — devDep only via @lhci/cli > proxy-agent > pac-proxy-agent > get-uri, no FTP usage in production code"
|
|
90
95
|
}
|
|
91
96
|
]
|
|
92
97
|
}
|