@codyswann/lisa 2.151.0 → 2.152.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/dist/core/lisa.d.ts.map +1 -1
  2. package/dist/core/lisa.js +17 -10
  3. package/dist/core/lisa.js.map +1 -1
  4. package/dist/opencode/hooks-installer.d.ts +54 -0
  5. package/dist/opencode/hooks-installer.d.ts.map +1 -0
  6. package/dist/opencode/hooks-installer.js +300 -0
  7. package/dist/opencode/hooks-installer.js.map +1 -0
  8. package/dist/opencode/plugin-templates/lisa-block-migration-edits.ts +44 -0
  9. package/dist/opencode/plugin-templates/lisa-block-suppress-directives.ts +57 -0
  10. package/dist/opencode/plugin-templates/lisa-lint-on-edit.ts +53 -0
  11. package/dist/opencode/plugin-templates/lisa-rubocop-on-edit.ts +54 -0
  12. package/dist/opencode/plugin-templates/lisa-session-bootstrap.ts +76 -0
  13. package/dist/opencode/plugin-templates/lisa-sg-scan-on-edit.ts +50 -0
  14. package/package.json +2 -2
  15. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  16. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  17. package/plugins/lisa-agy/plugin.json +1 -1
  18. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  19. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  20. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  21. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  22. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  23. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  24. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  25. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  26. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  27. package/plugins/lisa-expo-agy/plugin.json +1 -1
  28. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  29. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  30. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  31. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  32. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  33. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  34. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  35. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  36. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  37. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  38. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  39. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  40. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  41. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  42. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  43. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  44. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  45. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  46. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  47. package/plugins/lisa-rails-agy/plugin.json +1 -1
  48. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  49. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  50. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  51. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  52. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  53. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  54. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  55. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  56. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  57. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  58. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  59. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  60. package/scripts/copy-opencode-plugin-templates.mjs +29 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks-installer.js","sourceRoot":"","sources":["../../src/opencode/hooks-installer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Lisa-managed OpenCode plugin (tool.execute.before).
3
+ *
4
+ * Blocks edits to TypeORM migration files. Use `bun run migration:generate`
5
+ * to regenerate from entity diffs instead — hand-written migrations drift from
6
+ * entity metadata and break the schema/migration contract.
7
+ *
8
+ * Port of Lisa's Codex hook `block-migration-edits.sh`. OpenCode exposes only
9
+ * `edit` / `write` filesystem tools (no `apply_patch`), so the file path comes
10
+ * straight from `output.args.filePath`. Throwing in `tool.execute.before`
11
+ * cancels the tool call and surfaces the message to the agent (verified-by-run
12
+ * on opencode 1.16.2).
13
+ *
14
+ * NOTE: This file is a template Lisa copies verbatim into a host project's
15
+ * `.opencode/plugin/`. It is intentionally excluded from this repo's tsconfig
16
+ * and eslint config — it runs under OpenCode's Bun runtime, not here.
17
+ */
18
+ export /**
19
+ *
20
+ */
21
+ const LisaBlockMigrationEdits = async () => {
22
+ const MIGRATION_RE = /\/migrations\/[^/]*\d[^/]*-[^/]*\.ts$/;
23
+ return {
24
+ "tool.execute.before": async (
25
+ input: { tool: string },
26
+ output: { args?: { filePath?: string } }
27
+ ) => {
28
+ if (input.tool !== "edit" && input.tool !== "write") return;
29
+ const filePath = String(output.args?.filePath ?? "");
30
+ if (!filePath || !MIGRATION_RE.test(filePath)) return;
31
+ throw new Error(
32
+ [
33
+ `block-migration-edits: refusing to modify ${filePath}.`,
34
+ "",
35
+ "TypeORM migrations must be regenerated from entity diffs:",
36
+ " bun run migration:generate -- src/database/migrations/<descriptive-name>",
37
+ "",
38
+ "Hand-written migrations drift from entity metadata and break the",
39
+ "schema contract. Modify the entity, run the generator, then commit.",
40
+ ].join("\n")
41
+ );
42
+ },
43
+ };
44
+ };
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Lisa-managed OpenCode plugin (tool.execute.before).
3
+ *
4
+ * Blocks adding error-suppression directives (@ts-ignore, @ts-nocheck,
5
+ * eslint-disable, biome-ignore, prettier-ignore) to JS/TS source. Suppressing
6
+ * the type checker, linter, or formatter hides real defects — fix the
7
+ * underlying error. @ts-expect-error is intentionally NOT matched (it is the
8
+ * safer alternative).
9
+ *
10
+ * Port of Lisa's Codex hook `block-suppress-directives.sh`. OpenCode exposes
11
+ * `edit` (oldString/newString) and `write` (content) tools — there is no
12
+ * multi-file apply_patch — so the new text comes straight from the tool args.
13
+ * Throwing in `tool.execute.before` cancels the call and surfaces the message
14
+ * to the agent (verified-by-run on opencode 1.16.2).
15
+ *
16
+ * NOTE: This file is a template Lisa copies verbatim into a host project's
17
+ * `.opencode/plugin/`. It is intentionally excluded from this repo's tsconfig
18
+ * and eslint config — it runs under OpenCode's Bun runtime, not here.
19
+ */
20
+ export const LisaBlockSuppressDirectives = async () => {
21
+ // Comment-syntax-only match: // or /* opener, optional whitespace, directive.
22
+ const DIRECTIVE_RE =
23
+ /(\/\/|\/\*)\s*(@ts-(ignore|nocheck)|eslint-disable|biome-ignore|prettier-ignore)/;
24
+ const JS_TS = new Set(["ts", "tsx", "js", "jsx", "mjs", "cjs"]);
25
+ const extOf = (p: string) => p.split(".").pop()?.toLowerCase() ?? "";
26
+ return {
27
+ "tool.execute.before": async (
28
+ input: { tool: string },
29
+ output: {
30
+ args?: { filePath?: string; content?: string; newString?: string };
31
+ }
32
+ ) => {
33
+ if (input.tool !== "edit" && input.tool !== "write") return;
34
+ const filePath = String(output.args?.filePath ?? "");
35
+ if (!filePath || !JS_TS.has(extOf(filePath))) return;
36
+ const newText =
37
+ input.tool === "write"
38
+ ? String(output.args?.content ?? "")
39
+ : String(output.args?.newString ?? "");
40
+ if (!DIRECTIVE_RE.test(newText)) return;
41
+ throw new Error(
42
+ [
43
+ `block-suppress-directives: refusing to add an error-suppression directive to ${filePath}.`,
44
+ "",
45
+ "@ts-ignore / @ts-nocheck / eslint-disable / biome-ignore / prettier-ignore",
46
+ "silence the type checker, linter, or formatter instead of fixing the problem.",
47
+ "Fix the underlying type/lint error — add the missing annotation, narrow the",
48
+ "type, or restructure the code so the rule passes.",
49
+ "",
50
+ "Suppression is a last resort. If there is genuinely no other way, STOP and get",
51
+ "the user's approval first, prefer @ts-expect-error over @ts-ignore, scope the",
52
+ 'disable to one line and one rule, and add a "-- <reason>" description.',
53
+ ].join("\n")
54
+ );
55
+ },
56
+ };
57
+ };
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Lisa-managed OpenCode plugin (tool.execute.after).
3
+ *
4
+ * Runs ESLint --fix on every just-edited JS/TS file, then re-checks. If
5
+ * unfixable problems remain, throws so OpenCode marks the tool call failed and
6
+ * the agent self-corrects (the equivalent of the Codex hook's non-zero exit).
7
+ * Fails open when ESLint isn't installed.
8
+ *
9
+ * Port of Lisa's Codex hook `lint-on-edit.sh`. OpenCode passes the edited file
10
+ * via `input.args.filePath`; `tool.execute.after` runs after a successful
11
+ * edit/write (verified-by-run on opencode 1.16.2: a throw here surfaces the
12
+ * message to the agent).
13
+ *
14
+ * NOTE: This file is a template Lisa copies verbatim into a host project's
15
+ * `.opencode/plugin/`. It is intentionally excluded from this repo's tsconfig
16
+ * and eslint config — it runs under OpenCode's Bun runtime, not here.
17
+ */
18
+ export const LisaLintOnEdit = async ({
19
+ $,
20
+ directory,
21
+ }: {
22
+ $: (strings: TemplateStringsArray, ...exprs: unknown[]) => any;
23
+ directory: string;
24
+ }) => {
25
+ const EXTS = new Set(["ts", "tsx", "js", "jsx", "mjs", "cjs"]);
26
+ const extOf = (p: string) => p.split(".").pop()?.toLowerCase() ?? "";
27
+ const { existsSync } = await import("node:fs");
28
+ const resolveBin = (name: string): string | null => {
29
+ const local = `${directory}/node_modules/.bin/${name}`;
30
+ if (existsSync(local)) return local;
31
+ return Bun.which(name);
32
+ };
33
+ return {
34
+ "tool.execute.after": async (input: {
35
+ tool: string;
36
+ args?: { filePath?: string };
37
+ }) => {
38
+ if (input.tool !== "edit" && input.tool !== "write") return;
39
+ const filePath = String(input.args?.filePath ?? "");
40
+ if (!filePath || !EXTS.has(extOf(filePath))) return;
41
+ const eslint = resolveBin("eslint");
42
+ if (!eslint) return; // fail open — no ESLint installed
43
+ await $`${eslint} --fix ${filePath}`.quiet().nothrow();
44
+ const res = await $`${eslint} --quiet ${filePath}`.quiet().nothrow();
45
+ if (res.exitCode === 0) return;
46
+ const out =
47
+ `${res.stdout?.toString() ?? ""}${res.stderr?.toString() ?? ""}`.trim();
48
+ throw new Error(
49
+ `lint-on-edit: ESLint reported unfixable problems in ${filePath}:\n${out}`
50
+ );
51
+ },
52
+ };
53
+ };
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Lisa-managed OpenCode plugin (tool.execute.after).
3
+ *
4
+ * Runs RuboCop -a (safe autocorrect) on every just-edited Ruby file, then
5
+ * re-checks for remaining unfixable offenses. If any remain, throws so OpenCode
6
+ * marks the tool call failed and the agent fixes them. Prefers `bundle exec
7
+ * rubocop` when a Gemfile is present. Fails open when RuboCop isn't installed.
8
+ *
9
+ * Port of Lisa's Codex hook `rubocop-on-edit.sh`.
10
+ *
11
+ * NOTE: This file is a template Lisa copies verbatim into a host project's
12
+ * `.opencode/plugin/`. It is intentionally excluded from this repo's tsconfig
13
+ * and eslint config — it runs under OpenCode's Bun runtime, not here.
14
+ */
15
+ export const LisaRubocopOnEdit = async ({
16
+ $,
17
+ directory,
18
+ }: {
19
+ $: (strings: TemplateStringsArray, ...exprs: unknown[]) => any;
20
+ directory: string;
21
+ }) => {
22
+ const EXTS = new Set(["rb", "rake"]);
23
+ const extOf = (p: string) => p.split(".").pop()?.toLowerCase() ?? "";
24
+ const { existsSync } = await import("node:fs");
25
+ const resolveRunner = (): string[] | null => {
26
+ const bundle = Bun.which("bundle");
27
+ if (bundle && existsSync(`${directory}/Gemfile`)) {
28
+ return [bundle, "exec", "rubocop"];
29
+ }
30
+ const rubocop = Bun.which("rubocop");
31
+ return rubocop ? [rubocop] : null;
32
+ };
33
+ return {
34
+ "tool.execute.after": async (input: {
35
+ tool: string;
36
+ args?: { filePath?: string };
37
+ }) => {
38
+ if (input.tool !== "edit" && input.tool !== "write") return;
39
+ const filePath = String(input.args?.filePath ?? "");
40
+ if (!filePath || !EXTS.has(extOf(filePath))) return;
41
+ const runner = resolveRunner();
42
+ if (!runner) return; // fail open — no RuboCop installed
43
+ const [bin, ...rest] = runner;
44
+ await $`${bin} ${rest} -a ${filePath}`.quiet().nothrow();
45
+ const res = await $`${bin} ${rest} ${filePath}`.quiet().nothrow();
46
+ if (res.exitCode === 0) return;
47
+ const out =
48
+ `${res.stdout?.toString() ?? ""}${res.stderr?.toString() ?? ""}`.trim();
49
+ throw new Error(
50
+ `rubocop-on-edit: RuboCop reported unfixable offenses in ${filePath}:\n${out}`
51
+ );
52
+ },
53
+ };
54
+ };
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Lisa-managed OpenCode plugin (session bootstrap).
3
+ *
4
+ * OpenCode runs a plugin's factory function once when it loads the plugin at
5
+ * session start, which is the natural home for Lisa's Codex SessionStart hooks:
6
+ * - install-pkgs.sh → install dependencies when node_modules is missing
7
+ * - setup-jira-cli.sh → write jira-cli config from environment variables
8
+ *
9
+ * Both are fully fail-open (wrapped in try/catch) so a package-manager or
10
+ * filesystem hiccup never bricks OpenCode startup, mirroring the Codex scripts.
11
+ * install only runs on the first session of a fresh checkout (node_modules
12
+ * absent), so the common case is a cheap no-op.
13
+ *
14
+ * NOTE: This file is a template Lisa copies verbatim into a host project's
15
+ * `.opencode/plugin/`. It is intentionally excluded from this repo's tsconfig
16
+ * and eslint config — it runs under OpenCode's Bun runtime, not here.
17
+ */
18
+ export const LisaSessionBootstrap = async ({
19
+ $,
20
+ worktree,
21
+ }: {
22
+ $: (strings: TemplateStringsArray, ...exprs: unknown[]) => any;
23
+ worktree: string;
24
+ }) => {
25
+ const root = worktree;
26
+ const { existsSync, mkdirSync, writeFileSync } = await import("node:fs");
27
+
28
+ // install-pkgs: bootstrap dependencies when they're missing.
29
+ try {
30
+ if (
31
+ existsSync(`${root}/package.json`) &&
32
+ !existsSync(`${root}/node_modules`)
33
+ ) {
34
+ const has = (f: string) => existsSync(`${root}/${f}`);
35
+ const install = async (cmd: string) => {
36
+ if (Bun.which(cmd)) {
37
+ await $`${cmd} install`.cwd(root).quiet().nothrow();
38
+ }
39
+ };
40
+ if (has("bun.lockb") || has("bun.lock")) await install("bun");
41
+ else if (has("pnpm-lock.yaml")) await install("pnpm");
42
+ else if (has("yarn.lock")) await install("yarn");
43
+ else await install("npm");
44
+ }
45
+ } catch {
46
+ // fail open — never block startup on a dependency-install error
47
+ }
48
+
49
+ // setup-jira-cli: write jira-cli config from environment variables.
50
+ try {
51
+ const server = process.env.JIRA_SERVER;
52
+ const login = process.env.JIRA_LOGIN;
53
+ const home = process.env.HOME;
54
+ if (server && login && home) {
55
+ const dir = `${home}/.config/.jira`;
56
+ mkdirSync(dir, { recursive: true });
57
+ const config = [
58
+ `installation: ${process.env.JIRA_INSTALLATION ?? "cloud"}`,
59
+ `server: ${server}`,
60
+ `login: ${login}`,
61
+ `project: ${process.env.JIRA_PROJECT ?? ""}`,
62
+ `board: "${process.env.JIRA_BOARD ?? ""}"`,
63
+ "auth_type: basic",
64
+ "epic:",
65
+ " name: Epic Name",
66
+ " link: Epic Link",
67
+ "",
68
+ ].join("\n");
69
+ writeFileSync(`${dir}/.config.yml`, config);
70
+ }
71
+ } catch {
72
+ // fail open — never block startup on a jira-cli config error
73
+ }
74
+
75
+ return {};
76
+ };
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Lisa-managed OpenCode plugin (tool.execute.after).
3
+ *
4
+ * Runs `ast-grep scan` on every just-edited source file (TypeScript/JS or
5
+ * Ruby) when the project ships an `sgconfig.yml`. If ast-grep reports findings,
6
+ * throws so OpenCode marks the tool call failed and the agent fixes them.
7
+ * Fails open when ast-grep or sgconfig.yml is absent.
8
+ *
9
+ * Port of Lisa's Codex hook `sg-scan-on-edit.sh`.
10
+ *
11
+ * NOTE: This file is a template Lisa copies verbatim into a host project's
12
+ * `.opencode/plugin/`. It is intentionally excluded from this repo's tsconfig
13
+ * and eslint config — it runs under OpenCode's Bun runtime, not here.
14
+ */
15
+ export const LisaSgScanOnEdit = async ({
16
+ $,
17
+ directory,
18
+ }: {
19
+ $: (strings: TemplateStringsArray, ...exprs: unknown[]) => any;
20
+ directory: string;
21
+ }) => {
22
+ const EXTS = new Set(["ts", "tsx", "js", "jsx", "mjs", "cjs", "rb", "rake"]);
23
+ const extOf = (p: string) => p.split(".").pop()?.toLowerCase() ?? "";
24
+ const { existsSync } = await import("node:fs");
25
+ const resolveBin = (): string | null => {
26
+ const local = `${directory}/node_modules/.bin/ast-grep`;
27
+ if (existsSync(local)) return local;
28
+ return Bun.which("ast-grep") ?? Bun.which("sg");
29
+ };
30
+ return {
31
+ "tool.execute.after": async (input: {
32
+ tool: string;
33
+ args?: { filePath?: string };
34
+ }) => {
35
+ if (input.tool !== "edit" && input.tool !== "write") return;
36
+ const filePath = String(input.args?.filePath ?? "");
37
+ if (!filePath || !EXTS.has(extOf(filePath))) return;
38
+ if (!existsSync(`${directory}/sgconfig.yml`)) return; // fail open
39
+ const astGrep = resolveBin();
40
+ if (!astGrep) return; // fail open — no ast-grep installed
41
+ const res = await $`${astGrep} scan ${filePath}`.quiet().nothrow();
42
+ if (res.exitCode === 0) return;
43
+ const out =
44
+ `${res.stdout?.toString() ?? ""}${res.stderr?.toString() ?? ""}`.trim();
45
+ throw new Error(
46
+ `sg-scan-on-edit: ast-grep reported findings in ${filePath}:\n${out}`
47
+ );
48
+ },
49
+ };
50
+ };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "scripts": {
3
3
  "build": "bun run build:dist && bun run build:plugins",
4
- "build:dist": "tsc && node scripts/copy-codex-scripts.mjs",
4
+ "build:dist": "tsc && node scripts/copy-codex-scripts.mjs && node scripts/copy-opencode-plugin-templates.mjs",
5
5
  "test:integration": "vitest run tests/integration",
6
6
  "postinstall": "bash ./scripts/install-claude-plugins.sh || true; [ -d dist/configs ] || tsc || true",
7
7
  "pretest": "[ -d dist/configs ] || bun run build",
@@ -84,7 +84,7 @@
84
84
  "lodash": ">=4.18.1"
85
85
  },
86
86
  "name": "@codyswann/lisa",
87
- "version": "2.151.0",
87
+ "version": "2.152.0",
88
88
  "description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
89
89
  "main": "dist/index.js",
90
90
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.151.0",
3
+ "version": "2.152.0",
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": "2.151.0",
3
+ "version": "2.152.0",
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": "2.151.0",
3
+ "version": "2.152.0",
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": "2.151.0",
3
+ "version": "2.152.0",
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": "2.151.0",
3
+ "version": "2.152.0",
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": "2.151.0",
3
+ "version": "2.152.0",
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": "2.151.0",
3
+ "version": "2.152.0",
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": "2.151.0",
3
+ "version": "2.152.0",
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": "2.151.0",
3
+ "version": "2.152.0",
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": "2.151.0",
3
+ "version": "2.152.0",
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-expo",
3
- "version": "2.151.0",
3
+ "version": "2.152.0",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.151.0",
3
+ "version": "2.152.0",
4
4
  "description": "Expo and React Native-specific skills, agents, rules, and MCP servers.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.151.0",
3
+ "version": "2.152.0",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.151.0",
3
+ "version": "2.152.0",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.151.0",
3
+ "version": "2.152.0",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.151.0",
3
+ "version": "2.152.0",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.151.0",
3
+ "version": "2.152.0",
4
4
  "description": "Harper/Fabric-specific Lisa rules for TypeScript component apps.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.151.0",
3
+ "version": "2.152.0",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.151.0",
3
+ "version": "2.152.0",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.151.0",
3
+ "version": "2.152.0",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.151.0",
3
+ "version": "2.152.0",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.151.0",
3
+ "version": "2.152.0",
4
4
  "description": "NestJS-specific skills and migration write-protection hooks.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.151.0",
3
+ "version": "2.152.0",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.151.0",
3
+ "version": "2.152.0",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.151.0",
3
+ "version": "2.152.0",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.151.0",
3
+ "version": "2.152.0",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.151.0",
3
+ "version": "2.152.0",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, across Claude and Codex.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.151.0",
3
+ "version": "2.152.0",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.151.0",
3
+ "version": "2.152.0",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"