@codyswann/lisa 2.192.0 → 2.193.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 (78) hide show
  1. package/dist/configs/eslint/harper-fabric.d.ts.map +1 -1
  2. package/dist/configs/eslint/harper-fabric.js +69 -1
  3. package/dist/configs/eslint/harper-fabric.js.map +1 -1
  4. package/harper-fabric/copy-contents/.prettierignore +1 -0
  5. package/harper-fabric/copy-contents/gitignore +7 -0
  6. package/harper-fabric/copy-overwrite/knip.json +1 -0
  7. package/harper-fabric/copy-overwrite/tsconfig.eslint.json +1 -0
  8. package/harper-fabric/merge/.oxlintrc.json +1 -0
  9. package/oxlint/harper-fabric.json +1 -0
  10. package/package.json +1 -1
  11. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  12. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  13. package/plugins/lisa-agy/plugin.json +1 -1
  14. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  15. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  16. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  17. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  18. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  19. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  20. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  21. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  22. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  23. package/plugins/lisa-expo-agy/plugin.json +1 -1
  24. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  25. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  26. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  27. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  28. package/plugins/lisa-harper-fabric/generated-artifact-globs.txt +1 -0
  29. package/plugins/lisa-harper-fabric/hooks/block-generated-artifact-edits.sh +51 -0
  30. package/plugins/lisa-harper-fabric/rules/harper-fabric.md +1 -1
  31. package/plugins/lisa-harper-fabric/skills/harper-build-and-deploy/SKILL.md +20 -5
  32. package/plugins/lisa-harper-fabric-agy/generated-artifact-globs.txt +1 -0
  33. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  34. package/plugins/lisa-harper-fabric-agy/skills/harper-build-and-deploy/SKILL.md +20 -5
  35. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  36. package/plugins/lisa-harper-fabric-copilot/generated-artifact-globs.txt +1 -0
  37. package/plugins/lisa-harper-fabric-copilot/hooks/block-generated-artifact-edits.sh +51 -0
  38. package/plugins/lisa-harper-fabric-copilot/rules/harper-fabric.md +1 -1
  39. package/plugins/lisa-harper-fabric-copilot/skills/harper-build-and-deploy/SKILL.md +20 -5
  40. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  41. package/plugins/lisa-harper-fabric-cursor/generated-artifact-globs.txt +1 -0
  42. package/plugins/lisa-harper-fabric-cursor/hooks/block-generated-artifact-edits.sh +51 -0
  43. package/plugins/lisa-harper-fabric-cursor/rules/harper-fabric.mdc +1 -1
  44. package/plugins/lisa-harper-fabric-cursor/skills/harper-build-and-deploy/SKILL.md +20 -5
  45. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  46. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  47. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  48. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  49. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  50. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  51. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  52. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  53. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  54. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  55. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  56. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  57. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  58. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  59. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  60. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  61. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  62. package/plugins/lisa-rails-agy/plugin.json +1 -1
  63. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  64. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  65. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  66. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  67. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  68. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  69. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  70. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  71. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  72. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  73. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  74. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  75. package/plugins/src/harper-fabric/generated-artifact-globs.txt +1 -0
  76. package/plugins/src/harper-fabric/hooks/block-generated-artifact-edits.sh +51 -0
  77. package/plugins/src/harper-fabric/rules/harper-fabric.md +1 -1
  78. package/plugins/src/harper-fabric/skills/harper-build-and-deploy/SKILL.md +20 -5
@@ -1 +1 @@
1
- {"version":3,"file":"harper-fabric.d.ts","sourceRoot":"","sources":["../../../src/configs/eslint/harper-fabric.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,EACL,cAAc,EACd,iBAAiB,EAElB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,CAAC;AAE7C;;GAEG;AACH,eAAO,MAAM,0BAA0B,UAUtC,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,eAAe,EACf,cAA2C,EAC3C,UAA8B,GAC/B,EAAE;IACD,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,UAAU,CAAC,EAAE,OAAO,iBAAiB,CAAC;CACvC,GAAG,MAAM,CAAC,MAAM,EAAE,CAkClB"}
1
+ {"version":3,"file":"harper-fabric.d.ts","sourceRoot":"","sources":["../../../src/configs/eslint/harper-fabric.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,EACL,cAAc,EACd,iBAAiB,EAElB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,CAAC;AAE7C;;GAEG;AACH,eAAO,MAAM,0BAA0B,UAetC,CAAC;AAwCF;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,eAAe,EACf,cAA2C,EAC3C,UAA8B,GAC/B,EAAE;IACD,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,UAAU,CAAC,EAAE,OAAO,iBAAiB,CAAC;CACvC,GAAG,MAAM,CAAC,MAAM,EAAE,CA4DlB"}
@@ -11,9 +11,51 @@ export const defaultHarperFabricIgnores = [
11
11
  "*.config.local.ts",
12
12
  "harper-app/resources.js",
13
13
  "harper-app/resource-*.js",
14
+ // Root-level compiled Harper modules (resources.js, resource-*.js, and any
15
+ // other build output emitted straight into harper-app/). The single-star does
16
+ // not cross a directory separator, so hand-written shims one level down
17
+ // (harper-app/<route>/index.js) are still linted.
18
+ "harper-app/*.js",
14
19
  "harper-app/web/**",
15
20
  "harper-app/lib/**",
16
21
  ];
22
+ /**
23
+ * Platform built-ins declared trusted-immutable leaves for the
24
+ * `type-declaration-immutability` check. `Date`/`URL` and the DOM
25
+ * node/element/event types expose mutating methods, so `is-immutable-type`
26
+ * rates them "Mutable" — and because Harper row types hold `Date` (returned
27
+ * in-process) and any web layer holds DOM refs in its readonly option bags,
28
+ * that caps nearly every type below `ReadonlyDeep`. A readonly field holding
29
+ * one of these is not a mutation vector, so treating them as opaque immutable
30
+ * leaves is the standard `is-immutable-type` override pattern. Project-specific
31
+ * leaf types belong in the consumer's `eslint.config.local.ts`.
32
+ */
33
+ const immutabilityLeafOverrides = [
34
+ "Date",
35
+ "URL",
36
+ "Node",
37
+ "Element",
38
+ "HTMLElement",
39
+ "SVGElement",
40
+ "Event",
41
+ "EventTarget",
42
+ "Blob",
43
+ "HTMLInputElement",
44
+ "HTMLSelectElement",
45
+ "HTMLTextAreaElement",
46
+ "HTMLButtonElement",
47
+ "HTMLAnchorElement",
48
+ "HTMLFormElement",
49
+ "HTMLImageElement",
50
+ "HTMLDivElement",
51
+ "HTMLSpanElement",
52
+ "KeyboardEvent",
53
+ "MouseEvent",
54
+ "InputEvent",
55
+ "SubmitEvent",
56
+ "FocusEvent",
57
+ "PointerEvent",
58
+ ].map(type => ({ type, to: "Immutable" }));
17
59
  /**
18
60
  * Creates the Harper/Fabric ESLint configuration.
19
61
  * @param options - Configuration options
@@ -31,12 +73,32 @@ export function getHarperFabricConfig({ tsconfigRootDir, ignorePatterns = defaul
31
73
  }),
32
74
  {
33
75
  files: ["src/**/*.ts"],
76
+ settings: { immutability: { overrides: immutabilityLeafOverrides } },
34
77
  rules: {
35
78
  "functional/immutable-data": "error",
36
79
  "functional/no-let": "error",
37
80
  "functional/prefer-readonly-type": "error",
38
81
  "functional/readonly-type": "error",
39
- "functional/type-declaration-immutability": "error",
82
+ // Enforced at `ReadonlyDeep` (every property recursively `readonly`),
83
+ // NOT the plugin default of `Immutable`. `Immutable` additionally
84
+ // rejects function-typed properties, `Record`/index-signature bags,
85
+ // and mutable-method built-ins (`Date`, DOM types) — none of which a
86
+ // Harper app can shed without restructuring legitimate shapes, which
87
+ // is why projects were forced to disable this rule wholesale.
88
+ // `ReadonlyDeep` + the platform-leaf overrides above is the strongest
89
+ // achievable bar and the real immutability guarantee.
90
+ "functional/type-declaration-immutability": [
91
+ "error",
92
+ {
93
+ rules: [
94
+ {
95
+ identifiers: [".+"],
96
+ immutability: "ReadonlyDeep",
97
+ comparator: "AtLeast",
98
+ },
99
+ ],
100
+ },
101
+ ],
40
102
  },
41
103
  },
42
104
  {
@@ -47,6 +109,12 @@ export function getHarperFabricConfig({ tsconfigRootDir, ignorePatterns = defaul
47
109
  "functional/prefer-readonly-type": "off",
48
110
  "functional/readonly-type": "off",
49
111
  "functional/type-declaration-immutability": "off",
112
+ // Statement-order is a production-code discipline. Smoke/integration
113
+ // tests interleave arrange-act-assert with sequential awaited UI/HTTP
114
+ // interactions where the await ORDER is the test logic — reordering
115
+ // would change behavior. Exempt tests, consistent with the
116
+ // immutability relaxations above.
117
+ "code-organization/enforce-statement-order": "off",
50
118
  },
51
119
  },
52
120
  {
@@ -1 +1 @@
1
- {"version":3,"file":"harper-fabric.js","sourceRoot":"","sources":["../../../src/configs/eslint/harper-fabric.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,CAAC;AAE7C;;GAEG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,GAAG,cAAc;IACjB,WAAW;IACX,UAAU;IACV,WAAW;IACX,mBAAmB;IACnB,yBAAyB;IACzB,0BAA0B;IAC1B,mBAAmB;IACnB,mBAAmB;CACpB,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CAAC,EACpC,eAAe,EACf,cAAc,GAAG,0BAA0B,EAC3C,UAAU,GAAG,iBAAiB,GAK/B;IACC,OAAO;QACL,GAAG,mBAAmB,CAAC;YACrB,eAAe;YACf,cAAc;YACd,UAAU;SACX,CAAC;QACF;YACE,KAAK,EAAE,CAAC,aAAa,CAAC;YACtB,KAAK,EAAE;gBACL,2BAA2B,EAAE,OAAO;gBACpC,mBAAmB,EAAE,OAAO;gBAC5B,iCAAiC,EAAE,OAAO;gBAC1C,0BAA0B,EAAE,OAAO;gBACnC,0CAA0C,EAAE,OAAO;aACpD;SACF;QACD;YACE,KAAK,EAAE,CAAC,oBAAoB,EAAE,oBAAoB,CAAC;YACnD,KAAK,EAAE;gBACL,2BAA2B,EAAE,KAAK;gBAClC,mBAAmB,EAAE,KAAK;gBAC1B,iCAAiC,EAAE,KAAK;gBACxC,0BAA0B,EAAE,KAAK;gBACjC,0CAA0C,EAAE,KAAK;aAClD;SACF;QACD;YACE,KAAK,EAAE,CAAC,qBAAqB,EAAE,eAAe,CAAC;YAC/C,KAAK,EAAE;gBACL,sBAAsB,EAAE,KAAK;aAC9B;SACF;KACiB,CAAC;AACvB,CAAC"}
1
+ {"version":3,"file":"harper-fabric.js","sourceRoot":"","sources":["../../../src/configs/eslint/harper-fabric.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,CAAC;AAE7C;;GAEG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,GAAG,cAAc;IACjB,WAAW;IACX,UAAU;IACV,WAAW;IACX,mBAAmB;IACnB,yBAAyB;IACzB,0BAA0B;IAC1B,2EAA2E;IAC3E,8EAA8E;IAC9E,wEAAwE;IACxE,kDAAkD;IAClD,iBAAiB;IACjB,mBAAmB;IACnB,mBAAmB;CACpB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,yBAAyB,GAAG;IAChC,MAAM;IACN,KAAK;IACL,MAAM;IACN,SAAS;IACT,aAAa;IACb,YAAY;IACZ,OAAO;IACP,aAAa;IACb,MAAM;IACN,kBAAkB;IAClB,mBAAmB;IACnB,qBAAqB;IACrB,mBAAmB;IACnB,mBAAmB;IACnB,iBAAiB;IACjB,kBAAkB;IAClB,gBAAgB;IAChB,iBAAiB;IACjB,eAAe;IACf,YAAY;IACZ,YAAY;IACZ,aAAa;IACb,YAAY;IACZ,cAAc;CACf,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;AAE3C;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CAAC,EACpC,eAAe,EACf,cAAc,GAAG,0BAA0B,EAC3C,UAAU,GAAG,iBAAiB,GAK/B;IACC,OAAO;QACL,GAAG,mBAAmB,CAAC;YACrB,eAAe;YACf,cAAc;YACd,UAAU;SACX,CAAC;QACF;YACE,KAAK,EAAE,CAAC,aAAa,CAAC;YACtB,QAAQ,EAAE,EAAE,YAAY,EAAE,EAAE,SAAS,EAAE,yBAAyB,EAAE,EAAE;YACpE,KAAK,EAAE;gBACL,2BAA2B,EAAE,OAAO;gBACpC,mBAAmB,EAAE,OAAO;gBAC5B,iCAAiC,EAAE,OAAO;gBAC1C,0BAA0B,EAAE,OAAO;gBACnC,sEAAsE;gBACtE,kEAAkE;gBAClE,oEAAoE;gBACpE,qEAAqE;gBACrE,qEAAqE;gBACrE,8DAA8D;gBAC9D,sEAAsE;gBACtE,sDAAsD;gBACtD,0CAA0C,EAAE;oBAC1C,OAAO;oBACP;wBACE,KAAK,EAAE;4BACL;gCACE,WAAW,EAAE,CAAC,IAAI,CAAC;gCACnB,YAAY,EAAE,cAAc;gCAC5B,UAAU,EAAE,SAAS;6BACtB;yBACF;qBACF;iBACF;aACF;SACF;QACD;YACE,KAAK,EAAE,CAAC,oBAAoB,EAAE,oBAAoB,CAAC;YACnD,KAAK,EAAE;gBACL,2BAA2B,EAAE,KAAK;gBAClC,mBAAmB,EAAE,KAAK;gBAC1B,iCAAiC,EAAE,KAAK;gBACxC,0BAA0B,EAAE,KAAK;gBACjC,0CAA0C,EAAE,KAAK;gBACjD,qEAAqE;gBACrE,sEAAsE;gBACtE,oEAAoE;gBACpE,2DAA2D;gBAC3D,kCAAkC;gBAClC,2CAA2C,EAAE,KAAK;aACnD;SACF;QACD;YACE,KAAK,EAAE,CAAC,qBAAqB,EAAE,eAAe,CAAC;YAC/C,KAAK,EAAE;gBACL,sBAAsB,EAAE,KAAK;aAC9B;SACF;KACiB,CAAC;AACvB,CAAC"}
@@ -4,6 +4,7 @@
4
4
  # source formatting inputs.
5
5
  harper-app/resources.js
6
6
  harper-app/resource-*.js
7
+ harper-app/*.js
7
8
  harper-app/web/**
8
9
  harper-app/lib/**
9
10
  research/articles/
@@ -1,6 +1,13 @@
1
1
  # BEGIN: AI GUARDRAILS HARPER-FABRIC
2
+ # Compiled Harper modules are emitted straight into harper-app/ from src/. The
3
+ # root-level `harper-app/*.js` rule covers resources.js, resource-*.js, and any
4
+ # other build output (e.g. detail-shell-negotiation.js) without matching
5
+ # hand-written shims nested one level down (harper-app/<route>/index.js). If you
6
+ # keep a hand-written .js at the harper-app root (e.g. an SEO shell), re-include
7
+ # it with a `!harper-app/<file>.js` line placed BELOW this managed block.
2
8
  harper-app/resources.js
3
9
  harper-app/resource-*.js
10
+ harper-app/*.js
4
11
  harper-app/web/**
5
12
  harper-app/lib/**
6
13
  .lisabak/
@@ -15,6 +15,7 @@
15
15
  "**/node_modules/**",
16
16
  "harper-app/resources.js",
17
17
  "harper-app/resource-*.js",
18
+ "harper-app/*.js",
18
19
  "harper-app/web/**",
19
20
  "harper-app/lib/**"
20
21
  ],
@@ -22,6 +22,7 @@
22
22
  "coverage",
23
23
  "harper-app/resources.js",
24
24
  "harper-app/resource-*.js",
25
+ "harper-app/*.js",
25
26
  "harper-app/web/**",
26
27
  "harper-app/lib/**"
27
28
  ]
@@ -12,6 +12,7 @@
12
12
  "**/generated/**",
13
13
  "harper-app/resources.js",
14
14
  "harper-app/resource-*.js",
15
+ "harper-app/*.js",
15
16
  "harper-app/web/**",
16
17
  "harper-app/lib/**"
17
18
  ]
@@ -7,6 +7,7 @@
7
7
  "node_modules/**",
8
8
  "harper-app/resources.js",
9
9
  "harper-app/resource-*.js",
10
+ "harper-app/*.js",
10
11
  "harper-app/web/**",
11
12
  "harper-app/lib/**"
12
13
  ]
package/package.json CHANGED
@@ -95,7 +95,7 @@
95
95
  "ws": ">=8.20.1"
96
96
  },
97
97
  "name": "@codyswann/lisa",
98
- "version": "2.192.0",
98
+ "version": "2.193.0",
99
99
  "description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
100
100
  "main": "dist/index.js",
101
101
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.192.0",
3
+ "version": "2.193.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.192.0",
3
+ "version": "2.193.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.192.0",
3
+ "version": "2.193.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.192.0",
3
+ "version": "2.193.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.192.0",
3
+ "version": "2.193.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.192.0",
3
+ "version": "2.193.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.192.0",
3
+ "version": "2.193.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.192.0",
3
+ "version": "2.193.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.192.0",
3
+ "version": "2.193.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.192.0",
3
+ "version": "2.193.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.192.0",
3
+ "version": "2.193.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.192.0",
3
+ "version": "2.193.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.192.0",
3
+ "version": "2.193.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.192.0",
3
+ "version": "2.193.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.192.0",
3
+ "version": "2.193.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.192.0",
3
+ "version": "2.193.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.192.0",
3
+ "version": "2.193.0",
4
4
  "description": "Harper/Fabric-specific Lisa rules for TypeScript component apps.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,4 +1,5 @@
1
1
  harper-app/resources.js
2
2
  harper-app/resource-*.js
3
+ harper-app/*.js
3
4
  harper-app/web/**
4
5
  harper-app/lib/**
@@ -33,6 +33,7 @@ matches_glob() {
33
33
  local file="$1"
34
34
  local glob="$2"
35
35
 
36
+ # Recursive directory globs: "dir/**" matches everything under dir.
36
37
  if [ "${glob: -3}" = "/**" ]; then
37
38
  local dir="${glob%/**}"
38
39
  case "$file" in
@@ -41,6 +42,38 @@ matches_glob() {
41
42
  return 1
42
43
  fi
43
44
 
45
+ # Single-star globs like "harper-app/*.js": the star must not cross a
46
+ # directory separator, so a broadened root-level pattern protects compiled
47
+ # modules emitted straight into harper-app/ (resources.js, resource-*.js, and
48
+ # any other build output such as detail-shell-negotiation.js) WITHOUT matching
49
+ # hand-written files nested one level down (e.g. harper-app/<route>/index.js).
50
+ case "$glob" in
51
+ */\** | \**)
52
+ local base_glob="${glob##*/}"
53
+ local dir_glob=""
54
+ case "$glob" in
55
+ */*) dir_glob="${glob%/*}" ;;
56
+ esac
57
+ local file_base="${file##*/}"
58
+ local file_dir=""
59
+ case "$file" in
60
+ */*) file_dir="${file%/*}" ;;
61
+ esac
62
+ case "$file_base" in
63
+ $base_glob) ;;
64
+ *) return 1 ;;
65
+ esac
66
+ [ -z "$dir_glob" ] && return 0
67
+ # Match the directory exactly, or as a suffix so absolute/prefixed paths
68
+ # (e.g. /repo/harper-app/foo.js) still resolve.
69
+ case "$file_dir" in
70
+ $dir_glob | */"$dir_glob") return 0 ;;
71
+ esac
72
+ return 1
73
+ ;;
74
+ esac
75
+
76
+ # Literal (wildcard-free) globs.
44
77
  case "$file" in
45
78
  $glob | */$glob) return 0 ;;
46
79
  esac
@@ -50,6 +83,24 @@ matches_glob() {
50
83
 
51
84
  NORMALIZED_FILE=$(normalize_path "$FILE_PATH")
52
85
 
86
+ # Project-owned allowlist of hand-written files that live under harper-app/ and
87
+ # must NOT be treated as generated (e.g. a hand-authored SEO shell, or route
88
+ # index.js shims kept at the harper-app root). The broadened root-level
89
+ # `harper-app/*.js` protection would otherwise block editing them. One glob per
90
+ # line (same syntax as the globs file); blank lines and `#` comments ignored.
91
+ # Prefer naming compiled resource modules `resource-*.ts` so their JS output is
92
+ # unambiguously generated and never needs allowlisting.
93
+ ALLOWLIST_FILE="${CLAUDE_PROJECT_DIR:-.}/.lisa/harper-generated-artifact-allowlist.txt"
94
+ if [ -f "$ALLOWLIST_FILE" ]; then
95
+ while IFS= read -r allow || [ -n "$allow" ]; do
96
+ [ -n "$allow" ] || continue
97
+ case "$allow" in \#*) continue ;; esac
98
+ if matches_glob "$NORMALIZED_FILE" "$allow"; then
99
+ exit 0
100
+ fi
101
+ done <"$ALLOWLIST_FILE"
102
+ fi
103
+
53
104
  while IFS= read -r glob || [ -n "$glob" ]; do
54
105
  [ -n "$glob" ] || continue
55
106
  case "$glob" in \#*) continue ;; esac
@@ -13,7 +13,7 @@ These rules apply to Harper/Fabric component apps managed by Lisa.
13
13
  - TypeScript under `src/` is the source of truth for Harper resources, browser modules, shared libraries, and operational scripts.
14
14
  - `harper-app/config.yaml`, `harper-app/schema.graphql`, HTML, CSS, docs, and research fixtures are source assets.
15
15
  - `harper-app/config.yaml` does not merge with Harper defaults. Keep every required top-level extension declared when editing it; the Harper Fabric hook blocks accidental extension drops unless the removal is documented in `.lisa/harper-config-extension-allowlist.json`.
16
- - `harper-app/resources.js` and `harper-app/web/**/*.js` are generated deploy artifacts. Never edit them directly; change the matching TypeScript and run `bun run build`.
16
+ - Every `.js` at the harper-app root (`harper-app/*.js` — `resources.js`, `resource-*.js`, and any other compiled module) plus `harper-app/web/**/*.js` and `harper-app/lib/**` are generated deploy artifacts. Never edit them directly; change the matching TypeScript and run `bun run build`. Name compiled resource modules `resource-*.ts` so their output is unambiguously generated; a hand-written `.js` kept at the harper-app root must be re-included in `.gitignore` and listed in `.lisa/harper-generated-artifact-allowlist.txt` so the block hook allows editing it.
17
17
  - Deployment, bootstrap, smoke, seed, verify, preview, token, crawl, ingest, and extraction commands must run from compiled JavaScript or generated Harper assets, not stale checked-in JavaScript.
18
18
 
19
19
  ## Harper/Fabric Deploy Surface
@@ -50,15 +50,30 @@ What the build actually does:
50
50
 
51
51
  Generated Harper deploy artifacts usually include:
52
52
 
53
- - `harper-app/resources.js`
54
- - `harper-app/resource-*.js`
53
+ - `harper-app/*.js` — every compiled module the build emits to the harper-app
54
+ root (`resources.js`, `resource-*.js`, and any other output such as a route
55
+ negotiation module). The single-star does **not** cross a directory separator,
56
+ so it does not match hand-written shims one level down.
55
57
  - `harper-app/web/**`
56
58
  - `harper-app/lib/**`
57
59
 
60
+ The guard surfaces (`generated-artifact-globs.txt` for the PreToolUse block hook,
61
+ `.gitignore`, `.prettierignore`, the ESLint/oxlint/knip ignores, and
62
+ `tsconfig.eslint.json`) all key off `harper-app/*.js` so a newly-named compiled
63
+ module is protected automatically. **Name compiled resource modules
64
+ `resource-*.ts`** so their JS output is unambiguously generated.
65
+
66
+ If you keep a *hand-written* `.js` at the harper-app root (e.g. an SEO shell),
67
+ the root-level rule would otherwise treat it as generated: re-include it with a
68
+ `!harper-app/<file>.js` line below the managed gitignore block, and add it to
69
+ `.lisa/harper-generated-artifact-allowlist.txt` so the block hook lets you edit
70
+ it. Hand-written shims nested under `harper-app/<route>/index.js` need no
71
+ exemption — the root-level rule never matches them.
72
+
58
73
  Every lint, format, dead-code, search, or generated-artifact guard must ignore
59
- those generated paths unless it is explicitly validating the build output itself.
60
- When a new generated path appears, add it to every relevant ignore surface in the
61
- same change; partial ignores fail later gates in non-obvious ways.
74
+ generated paths unless it is explicitly validating the build output itself. When
75
+ a new generated *directory* appears, add it to every relevant ignore surface in
76
+ the same change; partial ignores fail later gates in non-obvious ways.
62
77
 
63
78
  - **TypeScript under `src/` is source.** `bun run build` produces the deployable
64
79
  Harper assets from it.
@@ -1,4 +1,5 @@
1
1
  harper-app/resources.js
2
2
  harper-app/resource-*.js
3
+ harper-app/*.js
3
4
  harper-app/web/**
4
5
  harper-app/lib/**
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.192.0",
3
+ "version": "2.193.0",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -50,15 +50,30 @@ What the build actually does:
50
50
 
51
51
  Generated Harper deploy artifacts usually include:
52
52
 
53
- - `harper-app/resources.js`
54
- - `harper-app/resource-*.js`
53
+ - `harper-app/*.js` — every compiled module the build emits to the harper-app
54
+ root (`resources.js`, `resource-*.js`, and any other output such as a route
55
+ negotiation module). The single-star does **not** cross a directory separator,
56
+ so it does not match hand-written shims one level down.
55
57
  - `harper-app/web/**`
56
58
  - `harper-app/lib/**`
57
59
 
60
+ The guard surfaces (`generated-artifact-globs.txt` for the PreToolUse block hook,
61
+ `.gitignore`, `.prettierignore`, the ESLint/oxlint/knip ignores, and
62
+ `tsconfig.eslint.json`) all key off `harper-app/*.js` so a newly-named compiled
63
+ module is protected automatically. **Name compiled resource modules
64
+ `resource-*.ts`** so their JS output is unambiguously generated.
65
+
66
+ If you keep a *hand-written* `.js` at the harper-app root (e.g. an SEO shell),
67
+ the root-level rule would otherwise treat it as generated: re-include it with a
68
+ `!harper-app/<file>.js` line below the managed gitignore block, and add it to
69
+ `.lisa/harper-generated-artifact-allowlist.txt` so the block hook lets you edit
70
+ it. Hand-written shims nested under `harper-app/<route>/index.js` need no
71
+ exemption — the root-level rule never matches them.
72
+
58
73
  Every lint, format, dead-code, search, or generated-artifact guard must ignore
59
- those generated paths unless it is explicitly validating the build output itself.
60
- When a new generated path appears, add it to every relevant ignore surface in the
61
- same change; partial ignores fail later gates in non-obvious ways.
74
+ generated paths unless it is explicitly validating the build output itself. When
75
+ a new generated *directory* appears, add it to every relevant ignore surface in
76
+ the same change; partial ignores fail later gates in non-obvious ways.
62
77
 
63
78
  - **TypeScript under `src/` is source.** `bun run build` produces the deployable
64
79
  Harper assets from it.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.192.0",
3
+ "version": "2.193.0",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,4 +1,5 @@
1
1
  harper-app/resources.js
2
2
  harper-app/resource-*.js
3
+ harper-app/*.js
3
4
  harper-app/web/**
4
5
  harper-app/lib/**
@@ -33,6 +33,7 @@ matches_glob() {
33
33
  local file="$1"
34
34
  local glob="$2"
35
35
 
36
+ # Recursive directory globs: "dir/**" matches everything under dir.
36
37
  if [ "${glob: -3}" = "/**" ]; then
37
38
  local dir="${glob%/**}"
38
39
  case "$file" in
@@ -41,6 +42,38 @@ matches_glob() {
41
42
  return 1
42
43
  fi
43
44
 
45
+ # Single-star globs like "harper-app/*.js": the star must not cross a
46
+ # directory separator, so a broadened root-level pattern protects compiled
47
+ # modules emitted straight into harper-app/ (resources.js, resource-*.js, and
48
+ # any other build output such as detail-shell-negotiation.js) WITHOUT matching
49
+ # hand-written files nested one level down (e.g. harper-app/<route>/index.js).
50
+ case "$glob" in
51
+ */\** | \**)
52
+ local base_glob="${glob##*/}"
53
+ local dir_glob=""
54
+ case "$glob" in
55
+ */*) dir_glob="${glob%/*}" ;;
56
+ esac
57
+ local file_base="${file##*/}"
58
+ local file_dir=""
59
+ case "$file" in
60
+ */*) file_dir="${file%/*}" ;;
61
+ esac
62
+ case "$file_base" in
63
+ $base_glob) ;;
64
+ *) return 1 ;;
65
+ esac
66
+ [ -z "$dir_glob" ] && return 0
67
+ # Match the directory exactly, or as a suffix so absolute/prefixed paths
68
+ # (e.g. /repo/harper-app/foo.js) still resolve.
69
+ case "$file_dir" in
70
+ $dir_glob | */"$dir_glob") return 0 ;;
71
+ esac
72
+ return 1
73
+ ;;
74
+ esac
75
+
76
+ # Literal (wildcard-free) globs.
44
77
  case "$file" in
45
78
  $glob | */$glob) return 0 ;;
46
79
  esac
@@ -50,6 +83,24 @@ matches_glob() {
50
83
 
51
84
  NORMALIZED_FILE=$(normalize_path "$FILE_PATH")
52
85
 
86
+ # Project-owned allowlist of hand-written files that live under harper-app/ and
87
+ # must NOT be treated as generated (e.g. a hand-authored SEO shell, or route
88
+ # index.js shims kept at the harper-app root). The broadened root-level
89
+ # `harper-app/*.js` protection would otherwise block editing them. One glob per
90
+ # line (same syntax as the globs file); blank lines and `#` comments ignored.
91
+ # Prefer naming compiled resource modules `resource-*.ts` so their JS output is
92
+ # unambiguously generated and never needs allowlisting.
93
+ ALLOWLIST_FILE="${CLAUDE_PROJECT_DIR:-.}/.lisa/harper-generated-artifact-allowlist.txt"
94
+ if [ -f "$ALLOWLIST_FILE" ]; then
95
+ while IFS= read -r allow || [ -n "$allow" ]; do
96
+ [ -n "$allow" ] || continue
97
+ case "$allow" in \#*) continue ;; esac
98
+ if matches_glob "$NORMALIZED_FILE" "$allow"; then
99
+ exit 0
100
+ fi
101
+ done <"$ALLOWLIST_FILE"
102
+ fi
103
+
53
104
  while IFS= read -r glob || [ -n "$glob" ]; do
54
105
  [ -n "$glob" ] || continue
55
106
  case "$glob" in \#*) continue ;; esac
@@ -13,7 +13,7 @@ These rules apply to Harper/Fabric component apps managed by Lisa.
13
13
  - TypeScript under `src/` is the source of truth for Harper resources, browser modules, shared libraries, and operational scripts.
14
14
  - `harper-app/config.yaml`, `harper-app/schema.graphql`, HTML, CSS, docs, and research fixtures are source assets.
15
15
  - `harper-app/config.yaml` does not merge with Harper defaults. Keep every required top-level extension declared when editing it; the Harper Fabric hook blocks accidental extension drops unless the removal is documented in `.lisa/harper-config-extension-allowlist.json`.
16
- - `harper-app/resources.js` and `harper-app/web/**/*.js` are generated deploy artifacts. Never edit them directly; change the matching TypeScript and run `bun run build`.
16
+ - Every `.js` at the harper-app root (`harper-app/*.js` — `resources.js`, `resource-*.js`, and any other compiled module) plus `harper-app/web/**/*.js` and `harper-app/lib/**` are generated deploy artifacts. Never edit them directly; change the matching TypeScript and run `bun run build`. Name compiled resource modules `resource-*.ts` so their output is unambiguously generated; a hand-written `.js` kept at the harper-app root must be re-included in `.gitignore` and listed in `.lisa/harper-generated-artifact-allowlist.txt` so the block hook allows editing it.
17
17
  - Deployment, bootstrap, smoke, seed, verify, preview, token, crawl, ingest, and extraction commands must run from compiled JavaScript or generated Harper assets, not stale checked-in JavaScript.
18
18
 
19
19
  ## Harper/Fabric Deploy Surface