@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.
- package/dist/core/lisa.d.ts.map +1 -1
- package/dist/core/lisa.js +17 -10
- package/dist/core/lisa.js.map +1 -1
- package/dist/opencode/hooks-installer.d.ts +54 -0
- package/dist/opencode/hooks-installer.d.ts.map +1 -0
- package/dist/opencode/hooks-installer.js +300 -0
- package/dist/opencode/hooks-installer.js.map +1 -0
- package/dist/opencode/plugin-templates/lisa-block-migration-edits.ts +44 -0
- package/dist/opencode/plugin-templates/lisa-block-suppress-directives.ts +57 -0
- package/dist/opencode/plugin-templates/lisa-lint-on-edit.ts +53 -0
- package/dist/opencode/plugin-templates/lisa-rubocop-on-edit.ts +54 -0
- package/dist/opencode/plugin-templates/lisa-session-bootstrap.ts +76 -0
- package/dist/opencode/plugin-templates/lisa-sg-scan-on-edit.ts +50 -0
- 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-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-cursor/.claude-plugin/plugin.json +1 -1
- 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-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/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.
|
|
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-openclaw",
|
|
3
|
-
"version": "2.
|
|
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.
|
|
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.
|
|
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.
|
|
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"
|