@codyswann/lisa 4.9.2 → 4.9.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/all/copy-overwrite/scripts/lisa-gates.mjs +2 -2
  2. package/dist/cli/{doctor-learnings-merge-driver.d.ts → doctor-merge-drivers.d.ts} +6 -6
  3. package/dist/cli/doctor-merge-drivers.d.ts.map +1 -0
  4. package/dist/cli/doctor-merge-drivers.js +163 -0
  5. package/dist/cli/doctor-merge-drivers.js.map +1 -0
  6. package/dist/cli/doctor.js +2 -2
  7. package/dist/cli/doctor.js.map +1 -1
  8. package/dist/core/gitattributes-merge-drivers.d.ts +28 -0
  9. package/dist/core/gitattributes-merge-drivers.d.ts.map +1 -0
  10. package/dist/core/gitattributes-merge-drivers.js +62 -0
  11. package/dist/core/gitattributes-merge-drivers.js.map +1 -0
  12. package/dist/core/learnings-merge-driver-install.d.ts +0 -13
  13. package/dist/core/learnings-merge-driver-install.d.ts.map +1 -1
  14. package/dist/core/learnings-merge-driver-install.js +0 -16
  15. package/dist/core/learnings-merge-driver-install.js.map +1 -1
  16. package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
  17. package/dist/core/lisa-owned-hash-ledger.js +2 -0
  18. package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
  19. package/dist/core/merge-driver-registration.d.ts +26 -0
  20. package/dist/core/merge-driver-registration.d.ts.map +1 -0
  21. package/dist/core/merge-driver-registration.js +38 -0
  22. package/dist/core/merge-driver-registration.js.map +1 -0
  23. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  24. package/dist/core/upstream-evidence-manifest.js +15 -3
  25. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  26. package/package.json +3 -2
  27. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  28. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  29. package/plugins/lisa-agy/plugin.json +1 -1
  30. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  31. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  32. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  33. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  34. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  35. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  36. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  37. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  38. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  39. package/plugins/lisa-expo-agy/plugin.json +1 -1
  40. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  41. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  42. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  43. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  44. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  45. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  46. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  47. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  48. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  49. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  50. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  51. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  52. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  53. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  54. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  55. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  56. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  57. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  58. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  59. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  60. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  61. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  62. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  63. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  64. package/plugins/lisa-rails-agy/plugin.json +1 -1
  65. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  66. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  67. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  68. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  69. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  70. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  71. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  72. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  73. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  74. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  75. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  76. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  77. package/scripts/check-merge-driver-registration.mjs +142 -0
  78. package/scripts/install-generated-artifact-merge-driver.mjs +200 -0
  79. package/scripts/lib/gitattributes-merge-drivers.mjs +52 -0
  80. package/scripts/merge-generated-artifact.mjs +519 -0
  81. package/dist/cli/doctor-learnings-merge-driver.d.ts.map +0 -1
  82. package/dist/cli/doctor-learnings-merge-driver.js +0 -73
  83. package/dist/cli/doctor-learnings-merge-driver.js.map +0 -1
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "build:dist:in-place": "tsc && node scripts/copy-codex-scripts.mjs && node scripts/copy-opencode-plugin-templates.mjs",
6
6
  "test:integration": "vitest run tests/integration",
7
7
  "test:integration:push": "vitest run tests/integration --exclude='**/mutation-gate-bite.test.ts' --exclude='**/mutation-gate-diff-bite.test.ts' --exclude='**/mutation-sigterm-control.test.ts'",
8
- "postinstall": "bash ./scripts/install-claude-plugins.sh || true; [ -d dist/configs ] || tsc || true",
8
+ "postinstall": "bash ./scripts/install-claude-plugins.sh || true; node ./scripts/install-generated-artifact-merge-driver.mjs || true; [ -d dist/configs ] || tsc || true",
9
9
  "pretest": "[ -d dist/configs ] || bun run build",
10
10
  "test": "vitest run",
11
11
  "test:unit": "vitest run --exclude='**/integration/**'",
@@ -52,6 +52,7 @@
52
52
  "check:conflict-markers": "node all/copy-overwrite/scripts/check-conflict-markers.mjs",
53
53
  "check:vacuous-required-checks": "node typescript/copy-overwrite/scripts/check-skipped-required-checks.mjs --vacuity",
54
54
  "check:orphan-processes": "node scripts/check-orphan-test-processes.mjs",
55
+ "check:merge-drivers": "node scripts/check-merge-driver-registration.mjs",
55
56
  "check:template-workflow-refs": "node scripts/check-template-workflow-refs.mjs",
56
57
  "check:workflow-package-paths": "node scripts/check-workflow-package-paths.mjs",
57
58
  "check:delivery-deletion-conflicts": "node scripts/check-delivery-deletion-conflicts.mjs",
@@ -148,7 +149,7 @@
148
149
  "zod-validation-error": "^4.0.0"
149
150
  },
150
151
  "name": "@codyswann/lisa",
151
- "version": "4.9.2",
152
+ "version": "4.9.4",
152
153
  "description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
153
154
  "main": "dist/index.js",
154
155
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "4.9.2",
3
+ "version": "4.9.4",
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": "4.9.2",
3
+ "version": "4.9.4",
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": "4.9.2",
3
+ "version": "4.9.4",
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": "4.9.2",
3
+ "version": "4.9.4",
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": "4.9.2",
3
+ "version": "4.9.4",
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": "4.9.2",
3
+ "version": "4.9.4",
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": "4.9.2",
3
+ "version": "4.9.4",
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": "4.9.2",
3
+ "version": "4.9.4",
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": "4.9.2",
3
+ "version": "4.9.4",
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": "4.9.2",
3
+ "version": "4.9.4",
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": "4.9.2",
3
+ "version": "4.9.4",
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": "4.9.2",
3
+ "version": "4.9.4",
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": "4.9.2",
3
+ "version": "4.9.4",
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": "4.9.2",
3
+ "version": "4.9.4",
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": "4.9.2",
3
+ "version": "4.9.4",
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": "4.9.2",
3
+ "version": "4.9.4",
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": "4.9.2",
3
+ "version": "4.9.4",
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": "4.9.2",
3
+ "version": "4.9.4",
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": "4.9.2",
3
+ "version": "4.9.4",
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": "4.9.2",
3
+ "version": "4.9.4",
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": "4.9.2",
3
+ "version": "4.9.4",
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": "4.9.2",
3
+ "version": "4.9.4",
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": "4.9.2",
3
+ "version": "4.9.4",
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": "4.9.2",
3
+ "version": "4.9.4",
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": "4.9.2",
3
+ "version": "4.9.4",
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": "4.9.2",
3
+ "version": "4.9.4",
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": "4.9.2",
3
+ "version": "4.9.4",
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": "4.9.2",
3
+ "version": "4.9.4",
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": "4.9.2",
3
+ "version": "4.9.4",
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": "4.9.2",
3
+ "version": "4.9.4",
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-phaser",
3
- "version": "4.9.2",
3
+ "version": "4.9.4",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "4.9.2",
3
+ "version": "4.9.4",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "4.9.2",
3
+ "version": "4.9.4",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "4.9.2",
3
+ "version": "4.9.4",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "4.9.2",
3
+ "version": "4.9.4",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "4.9.2",
3
+ "version": "4.9.4",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "4.9.2",
3
+ "version": "4.9.4",
4
4
  "description": "Ruby on Rails-specific skills and hooks for RuboCop and ast-grep scanning on edit.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "4.9.2",
3
+ "version": "4.9.4",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "4.9.2",
3
+ "version": "4.9.4",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "4.9.2",
3
+ "version": "4.9.4",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "4.9.2",
3
+ "version": "4.9.4",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "4.9.2",
3
+ "version": "4.9.4",
4
4
  "description": "TypeScript-specific hooks for formatting, linting, and ast-grep scanning on edit.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "4.9.2",
3
+ "version": "4.9.4",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "4.9.2",
3
+ "version": "4.9.4",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "4.9.2",
3
+ "version": "4.9.4",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "4.9.2",
3
+ "version": "4.9.4",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "4.9.2",
3
+ "version": "4.9.4",
4
4
  "description": "Distributable LLM Wiki kernel — ingest, query, lint, and maintain a git-native markdown knowledge base across Claude and Codex.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "4.9.2",
3
+ "version": "4.9.4",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "4.9.2",
3
+ "version": "4.9.4",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "4.9.2",
3
+ "version": "4.9.4",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -0,0 +1,142 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Report every merge driver this checkout's `.gitattributes` asks for and does
4
+ * not have registered (issue CodySwannGT/lisa#3084).
5
+ *
6
+ * ## Why this is a deliverable and not a nicety
7
+ *
8
+ * A `.gitattributes` mapping can be committed, reviewed, merged and shipped
9
+ * while the driver it names never runs. Git falls back to its built-in text
10
+ * merge and **says nothing about the driver being absent** — reproduced in a
11
+ * scratch repo: the merge exits 1 and the file comes back carrying ordinary
12
+ * seven-character conflict fences, exactly as if no mapping existed. Shipping a
13
+ * merge strategy that is present in the repository and absent at runtime would
14
+ * leave #3084 exactly where it was while appearing fixed, and appearing fixed is
15
+ * worse than open, because nobody looks again.
16
+ *
17
+ * ## Why it is not wired into CI
18
+ *
19
+ * CI checks out and never merges locally, so a CI runner legitimately has no
20
+ * driver registered and reddening it would trade a real signal for noise. The
21
+ * condition this reports matters on the machines that MERGE. Registration on
22
+ * those machines is automatic — `postinstall` runs
23
+ * `install-generated-artifact-merge-driver.mjs`, and `lisa apply` runs the
24
+ * learnings driver's migration — so this is the backstop that names the
25
+ * condition when automation did not reach a checkout, not the primary defence.
26
+ *
27
+ * CLI:
28
+ * node scripts/check-merge-driver-registration.mjs [--root <dir>]
29
+ *
30
+ * Exit codes:
31
+ * 0 — every mapped driver is registered, or nothing is mapped.
32
+ * 1 — at least one mapped driver has no registered command here.
33
+ * 2 — operational error: `--root` missing its value, not a git repository,
34
+ * or git unavailable.
35
+ *
36
+ * @module scripts/check-merge-driver-registration
37
+ */
38
+ import { readFileSync } from "node:fs";
39
+ import path from "node:path";
40
+ import process from "node:process";
41
+ import { execFileSync } from "node:child_process";
42
+
43
+ import { mergeDriversIn } from "./lib/gitattributes-merge-drivers.mjs";
44
+ import { invokedAsScript } from "./lib/invoked-as-script.mjs";
45
+
46
+ /**
47
+ * Run a fixed git command, never through a shell.
48
+ * @param {readonly string[]} args - Literal git arguments
49
+ * @param {string} cwd - Working directory
50
+ * @returns {{ok: true, stdout: string} | {ok: false}} Trimmed stdout, or a failure
51
+ */
52
+ function git(args, cwd) {
53
+ try {
54
+ return {
55
+ ok: true,
56
+ stdout: execFileSync("git", [...args], {
57
+ cwd,
58
+ encoding: "utf8",
59
+ stdio: ["ignore", "pipe", "ignore"],
60
+ }).trim(),
61
+ };
62
+ } catch {
63
+ return { ok: false };
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Classify one checkout's merge-driver registrations.
69
+ * @param {string} root - Directory to inspect
70
+ * @returns {{mapped: string[], unregistered: string[]} | undefined} Roster, or undefined when not a repository
71
+ */
72
+ export function inspectMergeDrivers(root) {
73
+ const toplevel = git(["rev-parse", "--show-toplevel"], root);
74
+ if (!toplevel.ok || toplevel.stdout === "") return undefined;
75
+ let contents = "";
76
+ try {
77
+ contents = readFileSync(
78
+ path.join(toplevel.stdout, ".gitattributes"),
79
+ "utf8"
80
+ );
81
+ } catch {
82
+ contents = "";
83
+ }
84
+ const mapped = mergeDriversIn(contents);
85
+ const unregistered = mapped.filter(name => {
86
+ // Deliberately scope-agnostic: registration is written locally, but git
87
+ // resolves a driver from ANY config scope, so asking with `--local` would
88
+ // report a working global registration as missing.
89
+ const value = git(
90
+ ["config", "--get", `merge.${name}.driver`],
91
+ toplevel.stdout
92
+ );
93
+ return !value.ok || value.stdout === "";
94
+ });
95
+ return { mapped, unregistered };
96
+ }
97
+
98
+ /**
99
+ * Run the check.
100
+ * @param {readonly string[]} argv - Arguments after the script name
101
+ * @param {(message: string) => void} [log] - Sink for output
102
+ * @returns {number} Process exit code
103
+ */
104
+ export function runCheckMergeDrivers(
105
+ argv,
106
+ log = message => process.stdout.write(`${message}\n`)
107
+ ) {
108
+ const at = argv.indexOf("--root");
109
+ if (at !== -1 && argv[at + 1] === undefined) {
110
+ log("check-merge-driver-registration: --root requires a directory");
111
+ return 2;
112
+ }
113
+ const root = at === -1 ? process.cwd() : argv[at + 1];
114
+ const report = inspectMergeDrivers(root);
115
+ if (report === undefined) {
116
+ log(`check-merge-driver-registration: ${root} is not a git repository`);
117
+ return 2;
118
+ }
119
+ if (report.mapped.length === 0) {
120
+ log("No .gitattributes merge driver is mapped here; nothing to register.");
121
+ return 0;
122
+ }
123
+ if (report.unregistered.length === 0) {
124
+ log(
125
+ `All ${report.mapped.length} mapped merge driver(s) are registered here.`
126
+ );
127
+ return 0;
128
+ }
129
+ for (const name of report.unregistered) {
130
+ log(
131
+ `.gitattributes maps at least one path to the "${name}" merge driver, but merge.${name}.driver is not registered in this checkout — git silently falls back to its built-in text merge, so those paths conflict on every merge as if the mapping did not exist.`
132
+ );
133
+ }
134
+ log(
135
+ "Fix: run `bun install` here (Lisa's postinstall registers lisa-generated-artifact), or `lisa install-merge-driver` for lisa-learnings."
136
+ );
137
+ return 1;
138
+ }
139
+
140
+ if (invokedAsScript(import.meta.url)) {
141
+ process.exit(runCheckMergeDrivers(process.argv.slice(2)));
142
+ }