@codyswann/lisa 2.329.0 → 2.330.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/all/copy-overwrite/scripts/lisa-enforcement-fallback.sh +4 -2
- package/all/copy-overwrite/scripts/lisa-hooks/block-instruction-file-edits.sh +142 -0
- package/all/merge/.claude/settings.json +9 -0
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +21 -6
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/dist/opencode/hooks-installer.d.ts.map +1 -1
- package/dist/opencode/hooks-installer.js +1 -41
- package/dist/opencode/hooks-installer.js.map +1 -1
- package/dist/opencode/plugin-catalog.d.ts +25 -0
- package/dist/opencode/plugin-catalog.d.ts.map +1 -0
- package/dist/opencode/plugin-catalog.js +47 -0
- package/dist/opencode/plugin-catalog.js.map +1 -0
- package/dist/opencode/plugin-templates/lisa-block-instruction-file-edits.ts +72 -0
- package/package.json +1 -1
- package/plugins/lisa/.claude-plugin/plugin.json +14 -1
- package/plugins/lisa/.codex-plugin/hooks.json +13 -0
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/hooks/block-instruction-file-edits.agy.sh +58 -0
- package/plugins/lisa/hooks/block-instruction-file-edits.sh +142 -0
- package/plugins/lisa-agy/hooks/block-instruction-file-edits.agy.sh +58 -0
- package/plugins/lisa-agy/hooks/block-instruction-file-edits.sh +142 -0
- package/plugins/lisa-agy/hooks.json +13 -0
- 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 +14 -1
- package/plugins/lisa-copilot/hooks/block-instruction-file-edits.sh +142 -0
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/hooks/block-instruction-file-edits.sh +142 -0
- package/plugins/lisa-cursor/hooks/hooks.json +8 -0
- 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/.claude-plugin/plugin.json +13 -0
- package/plugins/src/base/hooks/block-instruction-file-edits.agy.sh +58 -0
- package/plugins/src/base/hooks/block-instruction-file-edits.sh +142 -0
- package/scripts/build-plugins.sh +2 -1
- package/scripts/generate-agy-plugin-artifacts.mjs +11 -0
- package/scripts/lib/per-agent-hook-filter.mjs +10 -0
- package/scripts/lisa-enforcement-fallback.sh +4 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks-installer.d.ts","sourceRoot":"","sources":["../../src/opencode/hooks-installer.ts"],"names":[],"mappings":"AAuCA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"hooks-installer.d.ts","sourceRoot":"","sources":["../../src/opencode/hooks-installer.ts"],"names":[],"mappings":"AAuCA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAOrD,gFAAgF;AAChF,eAAO,MAAM,sBAAsB,WAAW,CAAC;AAE/C,sEAAsE;AACtE,eAAO,MAAM,wBAAwB,kBAAkB,CAAC;AAKxD,wEAAwE;AACxE,eAAO,MAAM,0BAA0B,eAAe,CAAC;AAEvD,2EAA2E;AAC3E,eAAO,MAAM,gCAAgC,oCAAoE,CAAC;AAqBlH,gDAAgD;AAChD,MAAM,WAAW,0BAA0B;IACzC,uEAAuE;IACvE,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,mEAAmE;IACnE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,6EAA6E;IAC7E,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,yEAAyE;IACzE,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,SAAS,WAAW,EAAE,EACrC,oBAAoB,EAAE,SAAS,MAAM,EAAE,GACtC,OAAO,CAAC,0BAA0B,CAAC,CAyDrC;AAgGD;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAyCpE;AAiGD;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAa5B"}
|
|
@@ -32,6 +32,7 @@ import { copyFile, readFile, readdir, rm, writeFile } from "node:fs/promises";
|
|
|
32
32
|
import * as path from "node:path";
|
|
33
33
|
import { fileURLToPath } from "node:url";
|
|
34
34
|
import { applyEdits, modify, parse as parseJsonc, } from "jsonc-parser";
|
|
35
|
+
import { PLUGIN_CATALOG } from "./plugin-catalog.js";
|
|
35
36
|
import { mirrorLisaRules } from "../core/lisa-rules-mirror.js";
|
|
36
37
|
import { OPENCODE_CONFIG_DIR } from "./manifest.js";
|
|
37
38
|
import { OPENCODE_SCHEMA_URL } from "./settings-installer.js";
|
|
@@ -58,47 +59,6 @@ const NO_VERIFY_DENY_PATTERNS = {
|
|
|
58
59
|
"*HUSKY_SKIP_HOOKS=*": "deny",
|
|
59
60
|
"*core.hooksPath*/dev/null*": "deny",
|
|
60
61
|
};
|
|
61
|
-
/**
|
|
62
|
-
* Plugin catalog — the OpenCode counterpart of the Codex HOOK_CATALOG. Adding a
|
|
63
|
-
* plugin? Drop a template in `plugin-templates/`, add an entry here, add tests.
|
|
64
|
-
*/
|
|
65
|
-
const PLUGIN_CATALOG = [
|
|
66
|
-
{
|
|
67
|
-
id: "parity-safety-net",
|
|
68
|
-
templateFilename: "lisa-parity-safety-net.ts",
|
|
69
|
-
forProjectTypes: ["*"],
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
id: "session-bootstrap",
|
|
73
|
-
templateFilename: "lisa-session-bootstrap.ts",
|
|
74
|
-
forProjectTypes: ["*"],
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
id: "block-suppress-directives",
|
|
78
|
-
templateFilename: "lisa-block-suppress-directives.ts",
|
|
79
|
-
forProjectTypes: ["typescript"],
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
id: "lint-on-edit",
|
|
83
|
-
templateFilename: "lisa-lint-on-edit.ts",
|
|
84
|
-
forProjectTypes: ["typescript"],
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
id: "sg-scan-on-edit",
|
|
88
|
-
templateFilename: "lisa-sg-scan-on-edit.ts",
|
|
89
|
-
forProjectTypes: ["typescript", "rails"],
|
|
90
|
-
},
|
|
91
|
-
{
|
|
92
|
-
id: "block-migration-edits",
|
|
93
|
-
templateFilename: "lisa-block-migration-edits.ts",
|
|
94
|
-
forProjectTypes: ["nestjs"],
|
|
95
|
-
},
|
|
96
|
-
{
|
|
97
|
-
id: "rubocop-on-edit",
|
|
98
|
-
templateFilename: "lisa-rubocop-on-edit.ts",
|
|
99
|
-
forProjectTypes: ["rails"],
|
|
100
|
-
},
|
|
101
|
-
];
|
|
102
62
|
/** Canonical policy files used by universal OpenCode adapters. */
|
|
103
63
|
const PLUGIN_SUPPORT_FILES = [
|
|
104
64
|
"parity-safety-net.sh",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks-installer.js","sourceRoot":"","sources":["../../src/opencode/hooks-installer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EACL,UAAU,EACV,MAAM,EACN,KAAK,IAAI,UAAU,GAEpB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAEhE,gFAAgF;AAChF,MAAM,CAAC,MAAM,sBAAsB,GAAG,QAAQ,CAAC;AAE/C,sEAAsE;AACtE,MAAM,CAAC,MAAM,wBAAwB,GAAG,eAAe,CAAC;AAExD,iFAAiF;AACjF,MAAM,kBAAkB,GAAG,OAAO,CAAC;AAEnC,wEAAwE;AACxE,MAAM,CAAC,MAAM,0BAA0B,GAAG,YAAY,CAAC;AAEvD,2EAA2E;AAC3E,MAAM,CAAC,MAAM,gCAAgC,GAAG,GAAG,mBAAmB,IAAI,0BAA0B,aAAa,CAAC;AAElH;;;;;GAKG;AACH,MAAM,uBAAuB,GAAqC;IAChE,eAAe,EAAE,MAAM;IACvB,WAAW,EAAE,MAAM;IACnB,qBAAqB,EAAE,MAAM;IAC7B,4BAA4B,EAAE,MAAM;CACrC,CAAC;
|
|
1
|
+
{"version":3,"file":"hooks-installer.js","sourceRoot":"","sources":["../../src/opencode/hooks-installer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The OpenCode plugin catalog — which Lisa-shipped `.opencode/plugin/lisa-*.ts`
|
|
3
|
+
* templates ship, and for which project types.
|
|
4
|
+
*
|
|
5
|
+
* Extracted from `hooks-installer.ts` so the closed registry stays one
|
|
6
|
+
* auditable list that can grow without pushing the installer past its
|
|
7
|
+
* line budget. The installer consumes it; nothing else should.
|
|
8
|
+
* @module opencode/plugin-catalog
|
|
9
|
+
*/
|
|
10
|
+
import type { ProjectType } from "../core/config.js";
|
|
11
|
+
/** One Lisa-shipped OpenCode plugin template. */
|
|
12
|
+
export interface PluginCatalogEntry {
|
|
13
|
+
/** Stable identifier (also the basename without the `lisa-`/`.ts`) */
|
|
14
|
+
readonly id: string;
|
|
15
|
+
/** Template filename in `plugin-templates/` and the dest filename verbatim */
|
|
16
|
+
readonly templateFilename: string;
|
|
17
|
+
/** Project types this plugin ships for. `["*"]` ships for every stack. */
|
|
18
|
+
readonly forProjectTypes: readonly (ProjectType | "*")[];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Plugin catalog — the OpenCode counterpart of the Codex HOOK_CATALOG. Adding a
|
|
22
|
+
* plugin? Drop a template in `plugin-templates/`, add an entry here, add tests.
|
|
23
|
+
*/
|
|
24
|
+
export declare const PLUGIN_CATALOG: readonly PluginCatalogEntry[];
|
|
25
|
+
//# sourceMappingURL=plugin-catalog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-catalog.d.ts","sourceRoot":"","sources":["../../src/opencode/plugin-catalog.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,iDAAiD;AACjD,MAAM,WAAW,kBAAkB;IACjC,sEAAsE;IACtE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,8EAA8E;IAC9E,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,0EAA0E;IAC1E,QAAQ,CAAC,eAAe,EAAE,SAAS,CAAC,WAAW,GAAG,GAAG,CAAC,EAAE,CAAC;CAC1D;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,kBAAkB,EAyCvD,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin catalog — the OpenCode counterpart of the Codex HOOK_CATALOG. Adding a
|
|
3
|
+
* plugin? Drop a template in `plugin-templates/`, add an entry here, add tests.
|
|
4
|
+
*/
|
|
5
|
+
export const PLUGIN_CATALOG = [
|
|
6
|
+
{
|
|
7
|
+
id: "parity-safety-net",
|
|
8
|
+
templateFilename: "lisa-parity-safety-net.ts",
|
|
9
|
+
forProjectTypes: ["*"],
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
id: "session-bootstrap",
|
|
13
|
+
templateFilename: "lisa-session-bootstrap.ts",
|
|
14
|
+
forProjectTypes: ["*"],
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
id: "block-instruction-file-edits",
|
|
18
|
+
templateFilename: "lisa-block-instruction-file-edits.ts",
|
|
19
|
+
forProjectTypes: ["*"],
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: "block-suppress-directives",
|
|
23
|
+
templateFilename: "lisa-block-suppress-directives.ts",
|
|
24
|
+
forProjectTypes: ["typescript"],
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
id: "lint-on-edit",
|
|
28
|
+
templateFilename: "lisa-lint-on-edit.ts",
|
|
29
|
+
forProjectTypes: ["typescript"],
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
id: "sg-scan-on-edit",
|
|
33
|
+
templateFilename: "lisa-sg-scan-on-edit.ts",
|
|
34
|
+
forProjectTypes: ["typescript", "rails"],
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
id: "block-migration-edits",
|
|
38
|
+
templateFilename: "lisa-block-migration-edits.ts",
|
|
39
|
+
forProjectTypes: ["nestjs"],
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
id: "rubocop-on-edit",
|
|
43
|
+
templateFilename: "lisa-rubocop-on-edit.ts",
|
|
44
|
+
forProjectTypes: ["rails"],
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
//# sourceMappingURL=plugin-catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-catalog.js","sourceRoot":"","sources":["../../src/opencode/plugin-catalog.ts"],"names":[],"mappings":"AAqBA;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAkC;IAC3D;QACE,EAAE,EAAE,mBAAmB;QACvB,gBAAgB,EAAE,2BAA2B;QAC7C,eAAe,EAAE,CAAC,GAAG,CAAC;KACvB;IACD;QACE,EAAE,EAAE,mBAAmB;QACvB,gBAAgB,EAAE,2BAA2B;QAC7C,eAAe,EAAE,CAAC,GAAG,CAAC;KACvB;IACD;QACE,EAAE,EAAE,8BAA8B;QAClC,gBAAgB,EAAE,sCAAsC;QACxD,eAAe,EAAE,CAAC,GAAG,CAAC;KACvB;IACD;QACE,EAAE,EAAE,2BAA2B;QAC/B,gBAAgB,EAAE,mCAAmC;QACrD,eAAe,EAAE,CAAC,YAAY,CAAC;KAChC;IACD;QACE,EAAE,EAAE,cAAc;QAClB,gBAAgB,EAAE,sBAAsB;QACxC,eAAe,EAAE,CAAC,YAAY,CAAC;KAChC;IACD;QACE,EAAE,EAAE,iBAAiB;QACrB,gBAAgB,EAAE,yBAAyB;QAC3C,eAAe,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC;KACzC;IACD;QACE,EAAE,EAAE,uBAAuB;QAC3B,gBAAgB,EAAE,+BAA+B;QACjD,eAAe,EAAE,CAAC,QAAQ,CAAC;KAC5B;IACD;QACE,EAAE,EAAE,iBAAiB;QACrB,gBAAgB,EAAE,yBAAyB;QAC3C,eAAe,EAAE,CAAC,OAAO,CAAC;KAC3B;CACF,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lisa-managed OpenCode plugin (tool.execute.before).
|
|
3
|
+
*
|
|
4
|
+
* Blocks agent writes to the session-instruction files (`AGENTS.md`,
|
|
5
|
+
* `CLAUDE.md`, `.github/copilot-instructions.md`). These are human-authored and
|
|
6
|
+
* curated: every line is loaded into every agent's context in every future
|
|
7
|
+
* session for the project. Agents appending their own findings is how they grow
|
|
8
|
+
* into hundreds of lines of stale, ticket-specific trivia.
|
|
9
|
+
*
|
|
10
|
+
* Port of Lisa's canonical hook `block-instruction-file-edits.sh`. OpenCode
|
|
11
|
+
* exposes only `edit` / `write` filesystem tools (no `apply_patch`), so the file
|
|
12
|
+
* path comes straight from `output.args.filePath`. Throwing in
|
|
13
|
+
* `tool.execute.before` cancels the tool call and surfaces the message to the
|
|
14
|
+
* agent.
|
|
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 /**
|
|
21
|
+
*
|
|
22
|
+
*/
|
|
23
|
+
const LisaBlockInstructionFileEdits = async () => {
|
|
24
|
+
const INSTRUCTION_FILES = new Set([
|
|
25
|
+
"agents.md",
|
|
26
|
+
"claude.md",
|
|
27
|
+
"copilot-instructions.md",
|
|
28
|
+
]);
|
|
29
|
+
return {
|
|
30
|
+
"tool.execute.before": async (
|
|
31
|
+
input: { tool: string },
|
|
32
|
+
output: { args?: { filePath?: string; content?: string } }
|
|
33
|
+
) => {
|
|
34
|
+
if (input.tool !== "edit" && input.tool !== "write") return;
|
|
35
|
+
const filePath = String(output.args?.filePath ?? "");
|
|
36
|
+
if (!filePath) return;
|
|
37
|
+
if (/(^|\/)(node_modules|dist)\//.test(filePath)) return;
|
|
38
|
+
// The operator's explicit override, named in the refusal below.
|
|
39
|
+
if (process.env["LISA_ALLOW_INSTRUCTION_FILE_WRITE"]) return;
|
|
40
|
+
// Lisa's own marker-bounded regions replace in place and cannot grow the
|
|
41
|
+
// file, so they are never the unbounded append this guard exists to stop.
|
|
42
|
+
if (String(output.args?.content ?? "").includes("<!-- LISA_")) return;
|
|
43
|
+
const base = (filePath.split("/").pop() ?? "").toLowerCase();
|
|
44
|
+
if (!INSTRUCTION_FILES.has(base)) return;
|
|
45
|
+
throw new Error(
|
|
46
|
+
[
|
|
47
|
+
`block-instruction-file-edits: refusing to write ${filePath}.`,
|
|
48
|
+
"",
|
|
49
|
+
"WHY: this is a session-instruction file, not a place to record what",
|
|
50
|
+
"you just learned. Every line in it loads into the context of every",
|
|
51
|
+
"agent, in every future session, in this project, forever. It is",
|
|
52
|
+
"human-curated on purpose.",
|
|
53
|
+
"",
|
|
54
|
+
"WHERE IT GOES INSTEAD — take the first one that fits:",
|
|
55
|
+
"",
|
|
56
|
+
"1. Every agent needs it every session, only in this project? That is a",
|
|
57
|
+
" project rule — capture it with /lisa:persist-learning so it lands in",
|
|
58
|
+
" the learnings ledger. The gardener (/lisa:learnings:audit) proposes",
|
|
59
|
+
" promotion into .claude/rules/PROJECT_RULES.md as a human-gated ticket.",
|
|
60
|
+
"2. It changes how an existing skill behaves? Edit that skill's SKILL.md.",
|
|
61
|
+
"3. It is true beyond this project? Propose it upstream via",
|
|
62
|
+
" /lisa:cross-pollinate, or open an issue on CodySwannGT/lisa.",
|
|
63
|
+
"4. Otherwise it is background, not a standing instruction — write it",
|
|
64
|
+
" into the project documentation (wiki/ or docs/).",
|
|
65
|
+
"",
|
|
66
|
+
"If a human explicitly asked for this edit, re-run with",
|
|
67
|
+
"LISA_ALLOW_INSTRUCTION_FILE_WRITE=1 set.",
|
|
68
|
+
].join("\n")
|
|
69
|
+
);
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
};
|
package/package.json
CHANGED
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
"brace-expansion": ">=5.0.9"
|
|
116
116
|
},
|
|
117
117
|
"name": "@codyswann/lisa",
|
|
118
|
-
"version": "2.
|
|
118
|
+
"version": "2.330.0",
|
|
119
119
|
"description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
|
|
120
120
|
"main": "dist/index.js",
|
|
121
121
|
"exports": {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.330.0",
|
|
4
4
|
"description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -106,6 +106,19 @@
|
|
|
106
106
|
{
|
|
107
107
|
"type": "command",
|
|
108
108
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/block-shell-json-parsing.sh"
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"type": "command",
|
|
112
|
+
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/block-instruction-file-edits.sh"
|
|
113
|
+
}
|
|
114
|
+
]
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"matcher": "Write|Edit|MultiEdit",
|
|
118
|
+
"hooks": [
|
|
119
|
+
{
|
|
120
|
+
"type": "command",
|
|
121
|
+
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/block-instruction-file-edits.sh"
|
|
109
122
|
}
|
|
110
123
|
]
|
|
111
124
|
},
|
|
@@ -46,6 +46,19 @@
|
|
|
46
46
|
{
|
|
47
47
|
"type": "command",
|
|
48
48
|
"command": "${PLUGIN_ROOT}/hooks/block-shell-json-parsing.sh"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"type": "command",
|
|
52
|
+
"command": "${PLUGIN_ROOT}/hooks/block-instruction-file-edits.sh"
|
|
53
|
+
}
|
|
54
|
+
]
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"matcher": "Write|Edit|MultiEdit",
|
|
58
|
+
"hooks": [
|
|
59
|
+
{
|
|
60
|
+
"type": "command",
|
|
61
|
+
"command": "${PLUGIN_ROOT}/hooks/block-instruction-file-edits.sh"
|
|
49
62
|
}
|
|
50
63
|
]
|
|
51
64
|
},
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Antigravity (agy) PreToolUse adapter for Lisa's instruction-file guard.
|
|
3
|
+
#
|
|
4
|
+
# agy sends `{toolCall:{name:"run_command",args:{CommandLine:"..."}}}` and
|
|
5
|
+
# expects an allow/deny JSON object on stdout. The canonical hook consumes the
|
|
6
|
+
# Claude Bash-hook envelope and communicates denial with exit status 2. This
|
|
7
|
+
# adapter only translates protocols; all classification stays in the canonical
|
|
8
|
+
# block-instruction-file-edits.sh beside it (same delegation pattern as
|
|
9
|
+
# block-shell-json-parsing.agy.sh).
|
|
10
|
+
#
|
|
11
|
+
# Scope note: agy plugin hooks match `run_command`, so only the Bash arm of the
|
|
12
|
+
# guard reaches agy — an agy file-edit tool call writing AGENTS.md cannot be
|
|
13
|
+
# intercepted. That gap is accepted and recorded here rather than papered over.
|
|
14
|
+
#
|
|
15
|
+
# Fail-open on missing runtimes: a missed refusal here costs context bloat in a
|
|
16
|
+
# markdown file, not data loss.
|
|
17
|
+
set -uo pipefail
|
|
18
|
+
|
|
19
|
+
allow() {
|
|
20
|
+
printf '%s\n' '{"decision":"allow"}'
|
|
21
|
+
exit 0
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
deny() {
|
|
25
|
+
local reason="$1"
|
|
26
|
+
if command -v jq >/dev/null 2>&1; then
|
|
27
|
+
jq -cn --arg reason "$reason" '{decision:"deny",reason:$reason}'
|
|
28
|
+
else
|
|
29
|
+
printf '%s\n' '{"decision":"allow"}'
|
|
30
|
+
fi
|
|
31
|
+
exit 0
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
input="$(cat 2>/dev/null || true)"
|
|
35
|
+
[ -z "$input" ] && allow
|
|
36
|
+
command -v jq >/dev/null 2>&1 || allow
|
|
37
|
+
|
|
38
|
+
tool_name="$(printf '%s' "$input" | jq -r '.toolCall.name // empty' 2>/dev/null || true)"
|
|
39
|
+
[ "$tool_name" != "run_command" ] && allow
|
|
40
|
+
command_str="$(printf '%s' "$input" | jq -r '.toolCall.args.CommandLine // empty' 2>/dev/null || true)"
|
|
41
|
+
[ -z "$command_str" ] && allow
|
|
42
|
+
|
|
43
|
+
hook_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
44
|
+
canonical_hook="$hook_dir/block-instruction-file-edits.sh"
|
|
45
|
+
[ -r "$canonical_hook" ] || allow
|
|
46
|
+
|
|
47
|
+
canonical_input="$(jq -cn --arg command "$command_str" '{tool_name:"Bash",tool_input:{command:$command}}')"
|
|
48
|
+
canonical_output=""
|
|
49
|
+
canonical_status=0
|
|
50
|
+
if canonical_output="$(printf '%s' "$canonical_input" | /bin/bash "$canonical_hook" 2>&1)"; then
|
|
51
|
+
canonical_status=0
|
|
52
|
+
else
|
|
53
|
+
canonical_status=$?
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
[ "$canonical_status" -eq 0 ] && allow
|
|
57
|
+
[ -n "$canonical_output" ] || canonical_output="Blocked: AGENTS.md / CLAUDE.md are human-authored session-instruction files."
|
|
58
|
+
deny "$canonical_output"
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# PreToolUse hook: refuse agent writes to the session-instruction files.
|
|
3
|
+
#
|
|
4
|
+
# `AGENTS.md`, `CLAUDE.md`, and `.github/copilot-instructions.md` are the files
|
|
5
|
+
# every agent loads at session start. They are human-authored and curated on
|
|
6
|
+
# purpose — Lisa's own contract says so in two places:
|
|
7
|
+
# - plugins/src/base/rules/reference/project-learnings.md
|
|
8
|
+
# - plugins/src/base/skills/lisa-debrief-apply/SKILL.md ("CLAUDE.md is
|
|
9
|
+
# human-authored ... apply never writes to any of the three")
|
|
10
|
+
#
|
|
11
|
+
# Nothing enforced it, so agents appended their own findings anyway: one fleet
|
|
12
|
+
# repo reached 949 lines of ticket-keyed trap dumps in `AGENTS.md` while its
|
|
13
|
+
# learnings ledger held 22. Every one of those lines is charged to the context
|
|
14
|
+
# of every later session in that project, forever. Prose did not hold; this is
|
|
15
|
+
# the executable control that does.
|
|
16
|
+
#
|
|
17
|
+
# Blocked signatures:
|
|
18
|
+
# 1. Write / Edit / MultiEdit / NotebookEdit whose target basename is one of
|
|
19
|
+
# the instruction files;
|
|
20
|
+
# 2. Bash output redirection (`>`, `>>`), `tee`, or `sed -i` aimed at one.
|
|
21
|
+
# Reads (`cat AGENTS.md`, `rg pattern AGENTS.md`) never fire.
|
|
22
|
+
#
|
|
23
|
+
# Exemptions (allowed):
|
|
24
|
+
# - `LISA_ALLOW_INSTRUCTION_FILE_WRITE` set — the operator's explicit override,
|
|
25
|
+
# named in the refusal so a human who really wants the edit can take it;
|
|
26
|
+
# - payloads carrying a `<!-- LISA_` marker: Lisa's own marker-bounded regions
|
|
27
|
+
# (the agy project-learnings bridge, cross-pollinate's rule section) replace
|
|
28
|
+
# in place on re-run and cannot grow the file;
|
|
29
|
+
# - paths under `node_modules/` or `dist/` — vendored copies, not the host's.
|
|
30
|
+
set -euo pipefail
|
|
31
|
+
|
|
32
|
+
input="$(cat)"
|
|
33
|
+
|
|
34
|
+
command -v jq >/dev/null 2>&1 || exit 0
|
|
35
|
+
|
|
36
|
+
# The operator's override. Checked before anything else so it is always the
|
|
37
|
+
# cheapest way out of a refusal a human deliberately wants to overrule.
|
|
38
|
+
if [ -n "${LISA_ALLOW_INSTRUCTION_FILE_WRITE:-}" ]; then
|
|
39
|
+
exit 0
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
tool_name="$(printf '%s' "$input" | jq -r '.tool_name // empty')"
|
|
43
|
+
[ -n "$tool_name" ] || exit 0
|
|
44
|
+
|
|
45
|
+
# Lisa's own bounded bridges write marked regions. A payload carrying a marker
|
|
46
|
+
# is replacing a delimited block, not appending prose, so it cannot be the
|
|
47
|
+
# unbounded growth this guard exists to stop.
|
|
48
|
+
if printf '%s' "$input" | grep -q '<!-- LISA_'; then
|
|
49
|
+
exit 0
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
# Basename match, case-insensitively: `agents.md` and `AGENTS.md` are the same
|
|
53
|
+
# file on the macOS checkouts this fleet runs on.
|
|
54
|
+
is_instruction_file() {
|
|
55
|
+
local candidate="$1"
|
|
56
|
+
case "$candidate" in
|
|
57
|
+
*/node_modules/* | node_modules/* | */dist/* | dist/*) return 1 ;;
|
|
58
|
+
esac
|
|
59
|
+
local base="${candidate##*/}"
|
|
60
|
+
case "$(printf '%s' "$base" | tr '[:upper:]' '[:lower:]')" in
|
|
61
|
+
agents.md | claude.md | copilot-instructions.md) return 0 ;;
|
|
62
|
+
esac
|
|
63
|
+
return 1
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
refuse() {
|
|
67
|
+
local target="$1"
|
|
68
|
+
cat >&2 <<EOF
|
|
69
|
+
BLOCKED: refusing to write \`$target\`.
|
|
70
|
+
|
|
71
|
+
WHY: this is a session-instruction file, not a place to record what you just
|
|
72
|
+
learned. Every line in it is loaded into the context of every agent, in every
|
|
73
|
+
future session, in this project, forever. It is human-curated on purpose. An
|
|
74
|
+
agent appending its own findings is how these files grow into hundreds of lines
|
|
75
|
+
of stale, ticket-specific trivia that every later session pays for and half of
|
|
76
|
+
which was only ever true once.
|
|
77
|
+
|
|
78
|
+
WHERE IT GOES INSTEAD — take the first one that fits:
|
|
79
|
+
|
|
80
|
+
1. Every agent genuinely needs this in every session, and only in this project.
|
|
81
|
+
That is a project rule — but do not write it yourself. Capture it with
|
|
82
|
+
\`/lisa:persist-learning\` so it lands in the learnings ledger with provenance
|
|
83
|
+
and a confidence score. The gardener (\`/lisa:learnings:audit\`) then proposes
|
|
84
|
+
promotion into \`.claude/rules/PROJECT_RULES.md\` as a human-gated ticket.
|
|
85
|
+
|
|
86
|
+
2. It changes how an existing skill should behave. Edit that skill's SKILL.md.
|
|
87
|
+
Knowledge belongs next to the procedure it modifies, not in a global preamble.
|
|
88
|
+
|
|
89
|
+
3. It is true beyond this project. Propose it upstream to Lisa via
|
|
90
|
+
\`/lisa:cross-pollinate\`, or open an issue on CodySwannGT/lisa. A local copy of
|
|
91
|
+
a general rule silently drifts the moment upstream changes.
|
|
92
|
+
|
|
93
|
+
4. None of the above — it is background someone may want to look up, not a
|
|
94
|
+
standing instruction. Write it into the project documentation (\`wiki/\` or
|
|
95
|
+
\`docs/\`).
|
|
96
|
+
|
|
97
|
+
If a human explicitly asked for this edit, they can re-run with
|
|
98
|
+
\`LISA_ALLOW_INSTRUCTION_FILE_WRITE=1\` set, which bypasses this guard.
|
|
99
|
+
EOF
|
|
100
|
+
exit 2
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
case "$tool_name" in
|
|
104
|
+
Write | Edit | MultiEdit | NotebookEdit | Update)
|
|
105
|
+
# `file_path` covers Write/Edit; `edits[].file_path` covers the MultiEdit
|
|
106
|
+
# shapes that carry a path per edit; `notebook_path` covers NotebookEdit.
|
|
107
|
+
paths="$(printf '%s' "$input" | jq -r '
|
|
108
|
+
[ .tool_input.file_path?,
|
|
109
|
+
.tool_input.path?,
|
|
110
|
+
.tool_input.notebook_path?,
|
|
111
|
+
(.tool_input.edits? // [] | .[].file_path?)
|
|
112
|
+
] | map(select(. != null and . != "")) | .[]' 2>/dev/null || true)"
|
|
113
|
+
while IFS= read -r candidate; do
|
|
114
|
+
[ -n "$candidate" ] || continue
|
|
115
|
+
if is_instruction_file "$candidate"; then
|
|
116
|
+
refuse "$candidate"
|
|
117
|
+
fi
|
|
118
|
+
done <<EOF
|
|
119
|
+
$paths
|
|
120
|
+
EOF
|
|
121
|
+
;;
|
|
122
|
+
Bash)
|
|
123
|
+
command_str="$(printf '%s' "$input" | jq -r '.tool_input.command // empty')"
|
|
124
|
+
[ -n "$command_str" ] || exit 0
|
|
125
|
+
# Fast path: no instruction filename mentioned means nothing to classify.
|
|
126
|
+
if ! printf '%s' "$command_str" |
|
|
127
|
+
grep -Eqi '(agents|claude|copilot-instructions)\.md'; then
|
|
128
|
+
exit 0
|
|
129
|
+
fi
|
|
130
|
+
# Write signatures only. A bare mention (`cat AGENTS.md`, `rg x AGENTS.md`)
|
|
131
|
+
# is a read and must stay allowed — the filename has to appear as the target
|
|
132
|
+
# of a redirection, a tee, or an in-place sed.
|
|
133
|
+
write_target='[^ |;&]*(agents|claude|copilot-instructions)\.md'
|
|
134
|
+
if printf '%s' "$command_str" |
|
|
135
|
+
grep -Eqi ">>?[[:space:]]*['\"]?$write_target|tee([[:space:]]+-[a-z]+)*[[:space:]]+['\"]?$write_target|sed[[:space:]]+[^|;&]*-i[^|;&]*$write_target"; then
|
|
136
|
+
refuse "$(printf '%s' "$command_str" |
|
|
137
|
+
grep -Eoi "$write_target" | head -1)"
|
|
138
|
+
fi
|
|
139
|
+
;;
|
|
140
|
+
esac
|
|
141
|
+
|
|
142
|
+
exit 0
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Antigravity (agy) PreToolUse adapter for Lisa's instruction-file guard.
|
|
3
|
+
#
|
|
4
|
+
# agy sends `{toolCall:{name:"run_command",args:{CommandLine:"..."}}}` and
|
|
5
|
+
# expects an allow/deny JSON object on stdout. The canonical hook consumes the
|
|
6
|
+
# Claude Bash-hook envelope and communicates denial with exit status 2. This
|
|
7
|
+
# adapter only translates protocols; all classification stays in the canonical
|
|
8
|
+
# block-instruction-file-edits.sh beside it (same delegation pattern as
|
|
9
|
+
# block-shell-json-parsing.agy.sh).
|
|
10
|
+
#
|
|
11
|
+
# Scope note: agy plugin hooks match `run_command`, so only the Bash arm of the
|
|
12
|
+
# guard reaches agy — an agy file-edit tool call writing AGENTS.md cannot be
|
|
13
|
+
# intercepted. That gap is accepted and recorded here rather than papered over.
|
|
14
|
+
#
|
|
15
|
+
# Fail-open on missing runtimes: a missed refusal here costs context bloat in a
|
|
16
|
+
# markdown file, not data loss.
|
|
17
|
+
set -uo pipefail
|
|
18
|
+
|
|
19
|
+
allow() {
|
|
20
|
+
printf '%s\n' '{"decision":"allow"}'
|
|
21
|
+
exit 0
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
deny() {
|
|
25
|
+
local reason="$1"
|
|
26
|
+
if command -v jq >/dev/null 2>&1; then
|
|
27
|
+
jq -cn --arg reason "$reason" '{decision:"deny",reason:$reason}'
|
|
28
|
+
else
|
|
29
|
+
printf '%s\n' '{"decision":"allow"}'
|
|
30
|
+
fi
|
|
31
|
+
exit 0
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
input="$(cat 2>/dev/null || true)"
|
|
35
|
+
[ -z "$input" ] && allow
|
|
36
|
+
command -v jq >/dev/null 2>&1 || allow
|
|
37
|
+
|
|
38
|
+
tool_name="$(printf '%s' "$input" | jq -r '.toolCall.name // empty' 2>/dev/null || true)"
|
|
39
|
+
[ "$tool_name" != "run_command" ] && allow
|
|
40
|
+
command_str="$(printf '%s' "$input" | jq -r '.toolCall.args.CommandLine // empty' 2>/dev/null || true)"
|
|
41
|
+
[ -z "$command_str" ] && allow
|
|
42
|
+
|
|
43
|
+
hook_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
44
|
+
canonical_hook="$hook_dir/block-instruction-file-edits.sh"
|
|
45
|
+
[ -r "$canonical_hook" ] || allow
|
|
46
|
+
|
|
47
|
+
canonical_input="$(jq -cn --arg command "$command_str" '{tool_name:"Bash",tool_input:{command:$command}}')"
|
|
48
|
+
canonical_output=""
|
|
49
|
+
canonical_status=0
|
|
50
|
+
if canonical_output="$(printf '%s' "$canonical_input" | /bin/bash "$canonical_hook" 2>&1)"; then
|
|
51
|
+
canonical_status=0
|
|
52
|
+
else
|
|
53
|
+
canonical_status=$?
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
[ "$canonical_status" -eq 0 ] && allow
|
|
57
|
+
[ -n "$canonical_output" ] || canonical_output="Blocked: AGENTS.md / CLAUDE.md are human-authored session-instruction files."
|
|
58
|
+
deny "$canonical_output"
|