@codyswann/lisa 4.38.8 → 4.39.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 (74) hide show
  1. package/all/deletions.json +136 -1
  2. package/cdk/deletions.json +8 -1
  3. package/dist/core/config.d.ts +33 -0
  4. package/dist/core/config.d.ts.map +1 -1
  5. package/dist/core/config.js.map +1 -1
  6. package/dist/core/deletion-basis.d.ts +107 -0
  7. package/dist/core/deletion-basis.d.ts.map +1 -0
  8. package/dist/core/deletion-basis.js +81 -0
  9. package/dist/core/deletion-basis.js.map +1 -0
  10. package/dist/core/lisa.d.ts.map +1 -1
  11. package/dist/core/lisa.js +18 -0
  12. package/dist/core/lisa.js.map +1 -1
  13. package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
  14. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  15. package/dist/core/upstream-evidence-manifest.js +13 -8
  16. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  17. package/expo/deletions.json +37 -1
  18. package/harper-fabric/deletions.json +6 -1
  19. package/nestjs/deletions.json +12 -1
  20. package/package.json +6 -5
  21. package/phaser/deletions.json +6 -1
  22. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  23. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  24. package/plugins/lisa-agy/plugin.json +1 -1
  25. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  26. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  27. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  28. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  29. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  30. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  31. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  32. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  33. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  34. package/plugins/lisa-expo-agy/plugin.json +1 -1
  35. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  36. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  37. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  38. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  39. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  40. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  41. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  42. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  43. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  44. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  45. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  46. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  47. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  48. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  49. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  50. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  51. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  52. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  53. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  54. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  55. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  56. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  57. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  58. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  59. package/plugins/lisa-rails-agy/plugin.json +1 -1
  60. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  61. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  62. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  63. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  64. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  65. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  66. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  67. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  68. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  69. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  70. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  71. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  72. package/rails/deletions.json +18 -1
  73. package/scripts/check-deletion-basis.mjs +126 -0
  74. package/typescript/deletions.json +48 -0
@@ -0,0 +1,126 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Refuse a `deletions.json` that declares a path without saying why it may go.
4
+ *
5
+ * This is the AUTHORING gate. `Lisa.processDeletionsFile` has its own runtime
6
+ * fail-safe that keeps an unclassified path in a consumer's repository; the two
7
+ * are deliberately separate mechanisms. The runtime rule protects a consumer
8
+ * whatever manifest they happen to have, including one authored before either
9
+ * existed. This one stops an unclassified path being written here in the first
10
+ * place, so the manifest cannot silently regrow the problem the moment somebody
11
+ * adds entry 256.
12
+ *
13
+ * Without this, the whole change is a one-time sweep. With it, it is a standing
14
+ * property.
15
+ *
16
+ * Also reports the outstanding `needs-review` count, because that number is the
17
+ * debt this change deliberately took on and it should be visible on every run
18
+ * rather than discovered later.
19
+ *
20
+ * Usage: node scripts/check-deletion-basis.mjs
21
+ * @module scripts/check-deletion-basis
22
+ */
23
+ import { readFileSync } from "node:fs";
24
+ import path from "node:path";
25
+ import { fileURLToPath } from "node:url";
26
+
27
+ const REPO_ROOT = path.resolve(
28
+ path.dirname(fileURLToPath(import.meta.url)),
29
+ ".."
30
+ );
31
+
32
+ const MANIFESTS = [
33
+ "all",
34
+ "typescript",
35
+ "expo",
36
+ "rails",
37
+ "nestjs",
38
+ "cdk",
39
+ "phaser",
40
+ "harper-fabric",
41
+ ];
42
+
43
+ const NEEDS_REVIEW = "needs-review";
44
+ const OWNED = "owned";
45
+ const LEGACY_PREFIX = "legacy:";
46
+
47
+ /**
48
+ * Whether one declared path carries a usable basis.
49
+ *
50
+ * Mirrors `resolveDeletionBasis` in `src/core/deletion-basis.ts`. Kept as plain
51
+ * ESM so this check runs with no build step — a gate that needs `dist/` cannot
52
+ * run in a pre-commit hook on a tree that does not compile.
53
+ * @param {object} manifest - Parsed deletions.json.
54
+ * @param {string} declaredPath - The declared path.
55
+ * @returns {boolean} True when the manifest says why the path may be removed.
56
+ */
57
+ function isClassified(manifest, declaredPath) {
58
+ const forced = manifest.force?.[declaredPath];
59
+ if (typeof forced === "string" && forced.trim() !== "") return true;
60
+ const declared = manifest.basis?.[declaredPath];
61
+ if (typeof declared !== "string") return false;
62
+ const value = declared.trim();
63
+ if (value === NEEDS_REVIEW || value === OWNED) return true;
64
+ // A `legacy` basis with no prose is unclassified in substance: the point of
65
+ // the kind is that somebody wrote down WHY.
66
+ if (value.startsWith(LEGACY_PREFIX))
67
+ return value.slice(LEGACY_PREFIX.length).trim() !== "";
68
+ return false;
69
+ }
70
+
71
+ let unclassified = 0;
72
+ let needsReview = 0;
73
+ let classified = 0;
74
+
75
+ for (const stack of MANIFESTS) {
76
+ const file = path.join(REPO_ROOT, stack, "deletions.json");
77
+ let manifest;
78
+ try {
79
+ manifest = JSON.parse(readFileSync(file, "utf8"));
80
+ } catch (error) {
81
+ if (error.code === "ENOENT") continue;
82
+ console.error(
83
+ `${stack}/deletions.json could not be read: ${error.message}`
84
+ );
85
+ process.exitCode = 1;
86
+ continue;
87
+ }
88
+ const keep = new Set(manifest.keep ?? []);
89
+ for (const declaredPath of manifest.paths ?? []) {
90
+ if (keep.has(declaredPath)) continue;
91
+ if (!isClassified(manifest, declaredPath)) {
92
+ if (unclassified === 0)
93
+ console.error(
94
+ "Declared for deletion with no basis — say why each may be removed:\n"
95
+ );
96
+ console.error(` ${stack}/deletions.json ${declaredPath}`);
97
+ unclassified++;
98
+ continue;
99
+ }
100
+ classified++;
101
+ if (manifest.basis?.[declaredPath]?.trim() === NEEDS_REVIEW) needsReview++;
102
+ }
103
+ }
104
+
105
+ if (unclassified > 0) {
106
+ console.error(
107
+ `\n${unclassified} declared path(s) carry no basis.\n\n` +
108
+ "Add one to that manifest's `basis` map:\n" +
109
+ ' "owned" Lisa installs this path today\n' +
110
+ ' "legacy: <reason>" Lisa shipped it once and no longer does\n' +
111
+ ' "needs-review" declared before the basis field; debt, but countable\n' +
112
+ "or a `force` entry when the removal is a ruling that must reach an edited copy.\n\n" +
113
+ "An unclassified path is KEPT at apply time rather than deleted, so leaving\n" +
114
+ "it unclassified does not merely fail this check — it stops the removal\n" +
115
+ "reaching consumers at all."
116
+ );
117
+ process.exitCode = 1;
118
+ } else {
119
+ console.log(
120
+ `deletion basis: ${classified} declared path(s) classified, of which ${needsReview} still carry \`${NEEDS_REVIEW}\`.`
121
+ );
122
+ if (needsReview > 0)
123
+ console.log(
124
+ ` ${needsReview} reason(s) remain unwritten. Each one replaced by \`legacy: <reason>\` is a path whose removal somebody has justified in writing.`
125
+ );
126
+ }
@@ -59,5 +59,53 @@
59
59
  ".github/workflows/reusable-auto-update-pr-branches.yml": "Removed fleet-wide (CodySwannGT/lisa#3590): it force-updated PR branches with the workflow's own github.token, and GitHub will not start runs from such a push, so required checks went ABSENT at head and pull requests silently stopped becoming mergeable. An edited copy does the same damage, so this removal overrides workflow ownership.",
60
60
  ".github/workflows/reusable-auto-update-pr-branches-dispatch.yml": "Removed fleet-wide (CodySwannGT/lisa#3590): it force-updated PR branches with the workflow's own github.token, and GitHub will not start runs from such a push, so required checks went ABSENT at head and pull requests silently stopped becoming mergeable. An edited copy does the same damage, so this removal overrides workflow ownership.",
61
61
  ".github/workflows/required-checks-drift.yml": "Removed fleet-wide (CodySwannGT/lisa#3599): it read the live ruleset over the GitHub API, which needs administration:read and therefore a personal access token held in a permanent repository secret. An edited copy still asks for that token, so this removal overrides workflow ownership."
62
+ },
63
+ "basis": {
64
+ "jest.config.js": "needs-review",
65
+ ".claude/hooks/install_pkgs.sh": "needs-review",
66
+ ".claude/hooks/format-on-edit.sh": "needs-review",
67
+ ".claude/hooks/install-pkgs.sh": "needs-review",
68
+ ".claude/hooks/lint-on-edit.sh": "needs-review",
69
+ ".claude/hooks/sg-scan-on-edit.sh": "needs-review",
70
+ ".claude/skills/jira-add-journey": "needs-review",
71
+ ".claude/skills/jira-create": "needs-review",
72
+ ".claude/skills/jira-evidence": "needs-review",
73
+ ".claude/skills/jira-journey": "needs-review",
74
+ ".claude/skills/jira-verify": "needs-review",
75
+ ".claude/skills/jsdoc-best-practices": "needs-review",
76
+ "eslint-plugin-code-organization": "needs-review",
77
+ "eslint.base.ts": "needs-review",
78
+ "eslint.typescript.ts": "needs-review",
79
+ "jest.base.ts": "needs-review",
80
+ "jest.typescript.ts": "needs-review",
81
+ "tsconfig.base.json": "needs-review",
82
+ "tsconfig.typescript.json": "needs-review",
83
+ ".github/workflows/quality.yml": "needs-review",
84
+ ".github/workflows/release.yml": "needs-review",
85
+ ".github/workflows/create-issue-on-failure.yml": "needs-review",
86
+ ".github/workflows/create-github-issue-on-failure.yml": "needs-review",
87
+ ".github/workflows/create-jira-issue-on-failure.yml": "needs-review",
88
+ ".github/workflows/create-sentry-issue-on-failure.yml": "needs-review",
89
+ ".github/workflows/reusable-claude.yml": "needs-review",
90
+ ".github/workflows/reusable-claude-ci-auto-fix.yml": "needs-review",
91
+ ".github/workflows/reusable-claude-code-review-response.yml": "needs-review",
92
+ ".github/workflows/reusable-claude-deploy-auto-fix.yml": "needs-review",
93
+ ".github/workflows/reusable-claude-nightly-code-complexity.yml": "needs-review",
94
+ ".github/workflows/reusable-claude-nightly-test-coverage.yml": "needs-review",
95
+ ".github/workflows/reusable-claude-nightly-test-improvement.yml": "needs-review",
96
+ ".github/workflows/load-test.yml": "needs-review",
97
+ ".github/workflows/claude-ci-auto-fix.yml": "needs-review",
98
+ ".github/workflows/claude-code-review-response.yml": "needs-review",
99
+ ".github/workflows/claude-deploy-auto-fix.yml": "needs-review",
100
+ ".github/workflows/claude-nightly-code-complexity.yml": "needs-review",
101
+ ".github/workflows/claude-nightly-test-coverage.yml": "needs-review",
102
+ ".github/workflows/claude-nightly-test-improvement.yml": "needs-review",
103
+ ".github/workflows/claude-sync-down-branches.yml": "needs-review",
104
+ ".github/workflows/claude.yml": "needs-review",
105
+ ".github/workflows/reusable-claude-sync-down-branches.yml": "needs-review",
106
+ ".github/workflows/reusable-claude-nightly-code-complexity-rails.yml": "needs-review",
107
+ ".github/workflows/reusable-claude-nightly-jira-triage.yml": "needs-review",
108
+ ".github/workflows/reusable-claude-nightly-test-coverage-rails.yml": "needs-review",
109
+ ".github/workflows/reusable-claude-nightly-test-improvement-rails.yml": "needs-review"
62
110
  }
63
111
  }