@codyswann/lisa 4.38.8 → 4.40.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-cross-worktree-guard.mjs +276 -0
- package/all/deletions.json +136 -1
- package/cdk/deletions.json +8 -1
- package/dist/core/config.d.ts +33 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js.map +1 -1
- package/dist/core/deletion-basis.d.ts +107 -0
- package/dist/core/deletion-basis.d.ts.map +1 -0
- package/dist/core/deletion-basis.js +81 -0
- package/dist/core/deletion-basis.js.map +1 -0
- package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.js +10 -0
- package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
- package/dist/core/lisa.d.ts.map +1 -1
- package/dist/core/lisa.js +18 -0
- package/dist/core/lisa.js.map +1 -1
- package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +22 -12
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/expo/deletions.json +37 -1
- package/harper-fabric/deletions.json +6 -1
- package/nestjs/deletions.json +12 -1
- package/npm-package/create-only/.github/workflows/publish-to-npm.yml +48 -19
- package/package.json +6 -5
- package/phaser/deletions.json +6 -1
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-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/rails/deletions.json +18 -1
- package/scripts/check-deletion-basis.mjs +126 -0
- package/scripts/two-channel-couplings.json +1 -1
- package/typescript/copy-contents/.husky/pre-commit +40 -0
- package/typescript/copy-overwrite/.prettierignore +1 -0
- package/typescript/deletions.json +48 -0
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// This file is managed by Lisa and IS replaced on each `lisa` run.
|
|
3
|
+
// Do not edit directly — durable changes belong upstream in Lisa.
|
|
4
|
+
/**
|
|
5
|
+
* Refuse a commit that stages a NEW file byte-identical to uncommitted work
|
|
6
|
+
* living in a different linked worktree.
|
|
7
|
+
*
|
|
8
|
+
* WHAT THIS IS FOR. When several agents share one repository through linked
|
|
9
|
+
* worktrees, one agent's uncommitted file can be committed by another — the
|
|
10
|
+
* file is real, the branch is real, the commit succeeds, every gate passes,
|
|
11
|
+
* and the history is quietly wrong about who did what. One confirmed case:
|
|
12
|
+
* a 284-line test file staged in one worktree was committed an hour later
|
|
13
|
+
* from elsewhere, byte-identical, under a subtly different subject line.
|
|
14
|
+
*
|
|
15
|
+
* WHY IT MUST BE A HOOK AND NOT A HABIT. The failure mode is that nobody
|
|
16
|
+
* notices. A check an agent has to remember to run is a check that does not
|
|
17
|
+
* run on the commit where it mattered. This runs on every commit, needs no
|
|
18
|
+
* cooperation, and costs one `stat` per linked worktree per newly added file.
|
|
19
|
+
*
|
|
20
|
+
* WHY CONTENT AND NOT MESSAGE. The observed case had a rewritten subject
|
|
21
|
+
* line, so anything keyed on the message would have missed it. Blob identity
|
|
22
|
+
* cannot be edited away.
|
|
23
|
+
*
|
|
24
|
+
* THE LIMIT, STATED PLAINLY. This needs BOTH halves — the file being staged
|
|
25
|
+
* here and the original still present over there. Once the other worktree is
|
|
26
|
+
* removed, the comparison has nothing to match against and this guard is
|
|
27
|
+
* silent. A clean run is therefore not proof that no work was taken; it is
|
|
28
|
+
* proof that none is takeable *right now*. Deleting a worktree that holds
|
|
29
|
+
* uncommitted work permanently forecloses the only window in which its own
|
|
30
|
+
* case was detectable.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import { execFileSync } from "node:child_process";
|
|
34
|
+
import { existsSync, statSync } from "node:fs";
|
|
35
|
+
import { join } from "node:path";
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Paths that are ambient session furniture rather than authored work.
|
|
39
|
+
*
|
|
40
|
+
* Matched with `startsWith` rather than a constructed RegExp: a literal prefix
|
|
41
|
+
* needs no pattern, and building one invites escaping that the shipped fixer
|
|
42
|
+
* then rewrites, which makes this file stop being a fixed point of Lisa's own
|
|
43
|
+
* formatter (#2788).
|
|
44
|
+
*/
|
|
45
|
+
const IGNORED_PREFIXES = [".codex/"];
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Content below this many bytes is not evidence of anything. A short or empty
|
|
49
|
+
* file collides across worktrees by coincidence — an empty `__init__`, a
|
|
50
|
+
* one-line barrel re-export, a placeholder — and a guard that fires on those
|
|
51
|
+
* teaches people to bypass it, which costs more than the cases it would catch.
|
|
52
|
+
*/
|
|
53
|
+
const MIN_INTERESTING_BYTES = 64;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Run a command, returning its trimmed stdout, or `null` when it exits
|
|
57
|
+
* non-zero. Used for probes whose failure is a legitimate answer ("this path
|
|
58
|
+
* is not on main", "this path is not tracked there") rather than an error.
|
|
59
|
+
*/
|
|
60
|
+
function probe(args, cwd) {
|
|
61
|
+
try {
|
|
62
|
+
return execFileSync("git", args, {
|
|
63
|
+
cwd,
|
|
64
|
+
encoding: "utf8",
|
|
65
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
66
|
+
}).trim();
|
|
67
|
+
} catch {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function must(args, cwd) {
|
|
73
|
+
return execFileSync("git", args, {
|
|
74
|
+
cwd,
|
|
75
|
+
encoding: "utf8",
|
|
76
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
77
|
+
}).trim();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Absolute paths of every registered linked worktree, this one included. */
|
|
81
|
+
function worktrees(repo) {
|
|
82
|
+
const out = probe(["worktree", "list", "--porcelain"], repo) ?? "";
|
|
83
|
+
return out
|
|
84
|
+
.split("\n")
|
|
85
|
+
.filter(line => line.startsWith("worktree "))
|
|
86
|
+
.map(line => line.slice("worktree ".length).trim())
|
|
87
|
+
.filter(Boolean);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Paths staged as ADDED in this commit.
|
|
92
|
+
*
|
|
93
|
+
* Deliberately only `A`. A modified tracked file is frequently identical
|
|
94
|
+
* across worktrees for honest reasons — a regenerated manifest is the common
|
|
95
|
+
* one, and it is deterministic, so two agents regenerating it produce the same
|
|
96
|
+
* bytes while differing from main. Firing on that would make the guard noise
|
|
97
|
+
* on nearly every commit. A brand-new file with identical content in two
|
|
98
|
+
* worktrees has no such innocent explanation.
|
|
99
|
+
*/
|
|
100
|
+
function stagedAdditions(repo) {
|
|
101
|
+
const out = probe(
|
|
102
|
+
["diff", "--cached", "--name-only", "--diff-filter=A", "-z"],
|
|
103
|
+
repo
|
|
104
|
+
);
|
|
105
|
+
if (out === null) return [];
|
|
106
|
+
return out.split("\0").filter(Boolean);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** The blob this commit is staging for `path`, or null when unreadable. */
|
|
110
|
+
function stagedBlob(repo, path) {
|
|
111
|
+
return probe(["rev-parse", `:${path}`], repo);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Whether `blob` is simply what the integration branch already holds at
|
|
116
|
+
* `path`.
|
|
117
|
+
*
|
|
118
|
+
* THIS IS THE REJECTION CONTROL, and without it the guard is worthless rather
|
|
119
|
+
* than merely weak. Measured while designing this: a first pass without it
|
|
120
|
+
* fired on four files in one worktree that were byte-identical to `origin/main`
|
|
121
|
+
* — content every worktree carries for the ordinary reason. A guard that
|
|
122
|
+
* reports shared history as contamination fires on every worktree and is
|
|
123
|
+
* switched off within the hour.
|
|
124
|
+
*/
|
|
125
|
+
function isIntegrationContent(repo, defaultRef, path, blob) {
|
|
126
|
+
if (!defaultRef) return false;
|
|
127
|
+
return probe(["rev-parse", `${defaultRef}:${path}`], repo) === blob;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** The remote-tracking integration ref, or null when it cannot be resolved. */
|
|
131
|
+
function integrationRef(repo) {
|
|
132
|
+
const symref = probe(
|
|
133
|
+
["symbolic-ref", "--quiet", "refs/remotes/origin/HEAD"],
|
|
134
|
+
repo
|
|
135
|
+
);
|
|
136
|
+
if (symref) return symref.replace(/^refs\/remotes\//, "");
|
|
137
|
+
for (const candidate of ["origin/main", "origin/master"]) {
|
|
138
|
+
if (probe(["rev-parse", "--verify", "--quiet", candidate], repo))
|
|
139
|
+
return candidate;
|
|
140
|
+
}
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Paths the operator has explicitly cleared, as a comma-separated list.
|
|
146
|
+
*
|
|
147
|
+
* Deliberately path-scoped rather than a boolean. A blanket "off" switch on a
|
|
148
|
+
* guard like this gets set once, in frustration, and never unset — and the
|
|
149
|
+
* next real case passes silently. Naming the file keeps the override as narrow
|
|
150
|
+
* as the situation that justified it.
|
|
151
|
+
*/
|
|
152
|
+
function clearedPaths() {
|
|
153
|
+
const raw = process.env.LISA_ALLOW_CROSS_WORKTREE_BLOB;
|
|
154
|
+
if (!raw) return new Set();
|
|
155
|
+
return new Set(
|
|
156
|
+
raw
|
|
157
|
+
.split(",")
|
|
158
|
+
.map(entry => entry.trim())
|
|
159
|
+
.filter(Boolean)
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function findCollisions(repo, self) {
|
|
164
|
+
const additions = stagedAdditions(repo);
|
|
165
|
+
if (additions.length === 0) return [];
|
|
166
|
+
|
|
167
|
+
const others = worktrees(repo).filter(tree => tree !== self);
|
|
168
|
+
if (others.length === 0) return [];
|
|
169
|
+
|
|
170
|
+
const defaultRef = integrationRef(repo);
|
|
171
|
+
const cleared = clearedPaths();
|
|
172
|
+
const collisions = [];
|
|
173
|
+
|
|
174
|
+
for (const path of additions) {
|
|
175
|
+
if (cleared.has(path)) continue;
|
|
176
|
+
if (IGNORED_PREFIXES.some(prefix => path.startsWith(prefix))) continue;
|
|
177
|
+
|
|
178
|
+
const blob = stagedBlob(repo, path);
|
|
179
|
+
if (!blob) continue;
|
|
180
|
+
|
|
181
|
+
const size = Number(probe(["cat-file", "-s", blob], repo));
|
|
182
|
+
if (!Number.isFinite(size) || size < MIN_INTERESTING_BYTES) continue;
|
|
183
|
+
|
|
184
|
+
if (isIntegrationContent(repo, defaultRef, path, blob)) continue;
|
|
185
|
+
|
|
186
|
+
for (const tree of others) {
|
|
187
|
+
const candidate = join(tree, path);
|
|
188
|
+
// The stat is the cheap filter: almost every worktree lacks the path,
|
|
189
|
+
// so almost every pair costs one failed stat and nothing else.
|
|
190
|
+
if (!existsSync(candidate)) continue;
|
|
191
|
+
let stats;
|
|
192
|
+
try {
|
|
193
|
+
stats = statSync(candidate);
|
|
194
|
+
} catch {
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
if (!stats.isFile()) continue;
|
|
198
|
+
|
|
199
|
+
const theirs = probe(["hash-object", candidate], repo);
|
|
200
|
+
if (theirs !== blob) continue;
|
|
201
|
+
|
|
202
|
+
// Tracked over there means it is shared history reaching that worktree
|
|
203
|
+
// through a branch, not that agent's work in progress.
|
|
204
|
+
const tracked = probe(["-C", tree, "ls-files", "--error-unmatch", path]);
|
|
205
|
+
if (tracked !== null) continue;
|
|
206
|
+
|
|
207
|
+
collisions.push({ path, tree });
|
|
208
|
+
break;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return collisions;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function report(collisions) {
|
|
216
|
+
const lines = [
|
|
217
|
+
"",
|
|
218
|
+
"❌ Commit blocked: staged content is also uncommitted in another worktree.",
|
|
219
|
+
"",
|
|
220
|
+
];
|
|
221
|
+
for (const { path, tree } of collisions) {
|
|
222
|
+
lines.push(` ${path}`);
|
|
223
|
+
lines.push(` byte-identical to an uncommitted copy in ${tree}`);
|
|
224
|
+
}
|
|
225
|
+
lines.push("");
|
|
226
|
+
lines.push(" Each file above is being added here while the same bytes sit");
|
|
227
|
+
lines.push(
|
|
228
|
+
" uncommitted in another worktree. Either another agent authored it and"
|
|
229
|
+
);
|
|
230
|
+
lines.push(
|
|
231
|
+
" this commit would take credit for work in progress, or the same work"
|
|
232
|
+
);
|
|
233
|
+
lines.push(" is about to land twice on two branches.");
|
|
234
|
+
lines.push("");
|
|
235
|
+
lines.push(" Before retrying, establish which worktree authored it:");
|
|
236
|
+
lines.push(
|
|
237
|
+
" git log --all --oneline --find-object=$(git rev-parse :<path>)"
|
|
238
|
+
);
|
|
239
|
+
lines.push(
|
|
240
|
+
" Inspect the other branch through shared refs — git log, git show,"
|
|
241
|
+
);
|
|
242
|
+
lines.push(
|
|
243
|
+
" git cat-file all reach it from here. Do NOT enter another agent's"
|
|
244
|
+
);
|
|
245
|
+
lines.push(
|
|
246
|
+
" working tree, and do not delete it: it may hold the only copy."
|
|
247
|
+
);
|
|
248
|
+
lines.push("");
|
|
249
|
+
lines.push(" If this really is your own file, clear it by name:");
|
|
250
|
+
lines.push(
|
|
251
|
+
` LISA_ALLOW_CROSS_WORKTREE_BLOB='${collisions.map(c => c.path).join(",")}' git commit ...`
|
|
252
|
+
);
|
|
253
|
+
lines.push("");
|
|
254
|
+
return lines.join("\n");
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
function main() {
|
|
258
|
+
let repo;
|
|
259
|
+
let self;
|
|
260
|
+
try {
|
|
261
|
+
repo = must(["rev-parse", "--show-toplevel"]);
|
|
262
|
+
self = repo;
|
|
263
|
+
} catch {
|
|
264
|
+
// Not a git repository, or git is unavailable. A commit is not happening
|
|
265
|
+
// here in any case; there is nothing for this guard to say.
|
|
266
|
+
return 0;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
const collisions = findCollisions(repo, self);
|
|
270
|
+
if (collisions.length === 0) return 0;
|
|
271
|
+
|
|
272
|
+
process.stderr.write(report(collisions));
|
|
273
|
+
return 1;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
process.exit(main());
|
package/all/deletions.json
CHANGED
|
@@ -141,5 +141,140 @@
|
|
|
141
141
|
"scripts/setup-deploy-key.sh",
|
|
142
142
|
".coderabbit.yml",
|
|
143
143
|
"HUMAN.md"
|
|
144
|
-
]
|
|
144
|
+
],
|
|
145
|
+
"basis": {
|
|
146
|
+
".claude/commands/project": "needs-review",
|
|
147
|
+
".claude/skills/coding-philosophy": "needs-review",
|
|
148
|
+
".claude/skills/project-add-test-coverage": "needs-review",
|
|
149
|
+
".claude/skills/project-archive": "needs-review",
|
|
150
|
+
".claude/skills/project-bootstrap": "needs-review",
|
|
151
|
+
".claude/skills/project-debrief": "needs-review",
|
|
152
|
+
".claude/skills/project-document": "needs-review",
|
|
153
|
+
".claude/skills/project-execute": "needs-review",
|
|
154
|
+
".claude/skills/project-fix-linter-error": "needs-review",
|
|
155
|
+
".claude/skills/project-implement": "needs-review",
|
|
156
|
+
".claude/skills/project-local-code-review": "needs-review",
|
|
157
|
+
".claude/skills/project-lower-code-complexity": "needs-review",
|
|
158
|
+
".claude/skills/project-plan": "needs-review",
|
|
159
|
+
".claude/skills/project-reduce-max-lines": "needs-review",
|
|
160
|
+
".claude/skills/project-reduce-max-lines-per-function": "needs-review",
|
|
161
|
+
".claude/skills/project-research": "needs-review",
|
|
162
|
+
".claude/skills/project-review": "needs-review",
|
|
163
|
+
".claude/skills/project-setup": "needs-review",
|
|
164
|
+
".claude/skills/project-verify": "needs-review",
|
|
165
|
+
".claude/skills/prompt-complexity-scorer": "needs-review",
|
|
166
|
+
".claude/skills/git:commit": "needs-review",
|
|
167
|
+
".claude/skills/git:commit-and-submit-pr": "needs-review",
|
|
168
|
+
".claude/skills/git:prune": "needs-review",
|
|
169
|
+
".claude/skills/git:submit-pr": "needs-review",
|
|
170
|
+
".claude/skills/jira:create": "needs-review",
|
|
171
|
+
".claude/skills/jira:sync": "needs-review",
|
|
172
|
+
".claude/skills/jira:verify": "needs-review",
|
|
173
|
+
".claude/skills/lisa:review-implementation": "needs-review",
|
|
174
|
+
".claude/skills/plan:add-test-coverage": "needs-review",
|
|
175
|
+
".claude/skills/plan:create": "needs-review",
|
|
176
|
+
".claude/skills/plan:fix-linter-error": "needs-review",
|
|
177
|
+
".claude/skills/plan:implement": "needs-review",
|
|
178
|
+
".claude/skills/plan:local-code-review": "needs-review",
|
|
179
|
+
".claude/skills/plan:lower-code-complexity": "needs-review",
|
|
180
|
+
".claude/skills/plan:reduce-max-lines": "needs-review",
|
|
181
|
+
".claude/skills/plan:reduce-max-lines-per-function": "needs-review",
|
|
182
|
+
".claude/skills/pull-request:review": "needs-review",
|
|
183
|
+
".claude/skills/security:zap-scan": "needs-review",
|
|
184
|
+
".claude/skills/sonarqube:check": "needs-review",
|
|
185
|
+
".claude/skills/sonarqube:fix": "needs-review",
|
|
186
|
+
".claude/skills/tasks:load": "needs-review",
|
|
187
|
+
".claude/skills/tasks:sync": "needs-review",
|
|
188
|
+
".claude/REFERENCE.md": "needs-review",
|
|
189
|
+
".claude/commands/plan/implement.md": "needs-review",
|
|
190
|
+
".claude/rules/plan-governance.md": "needs-review",
|
|
191
|
+
".claude/rules/plan.md": "needs-review",
|
|
192
|
+
".claude/skills/plan-create": "needs-review",
|
|
193
|
+
".claude/skills/plan-implement": "needs-review",
|
|
194
|
+
".claude/agents/architecture-planner.md": "needs-review",
|
|
195
|
+
".claude/agents/codebase-analyzer.md": "needs-review",
|
|
196
|
+
".claude/agents/codebase-locator.md": "needs-review",
|
|
197
|
+
".claude/agents/codebase-pattern-finder.md": "needs-review",
|
|
198
|
+
".claude/agents/consistency-checker.md": "needs-review",
|
|
199
|
+
".claude/agents/product-planner.md": "needs-review",
|
|
200
|
+
".claude/agents/product-reviewer.md": "needs-review",
|
|
201
|
+
".claude/agents/security-planner.md": "needs-review",
|
|
202
|
+
".claude/agents/spec-analyst.md": "needs-review",
|
|
203
|
+
".claude/agents/tech-reviewer.md": "needs-review",
|
|
204
|
+
".claude/agents/test-coverage-agent.md": "needs-review",
|
|
205
|
+
".claude/agents/test-strategist.md": "needs-review",
|
|
206
|
+
".claude/agents/agent-architect.md": "needs-review",
|
|
207
|
+
".claude/agents/architecture-specialist.md": "needs-review",
|
|
208
|
+
".claude/agents/debug-specialist.md": "needs-review",
|
|
209
|
+
".claude/agents/git-history-analyzer.md": "needs-review",
|
|
210
|
+
".claude/agents/hooks-expert.md": "needs-review",
|
|
211
|
+
".claude/agents/implementer.md": "needs-review",
|
|
212
|
+
".claude/agents/learner.md": "needs-review",
|
|
213
|
+
".claude/agents/performance-specialist.md": "needs-review",
|
|
214
|
+
".claude/agents/product-specialist.md": "needs-review",
|
|
215
|
+
".claude/agents/quality-specialist.md": "needs-review",
|
|
216
|
+
".claude/agents/security-specialist.md": "needs-review",
|
|
217
|
+
".claude/agents/skill-evaluator.md": "needs-review",
|
|
218
|
+
".claude/agents/slash-command-architect.md": "needs-review",
|
|
219
|
+
".claude/agents/test-specialist.md": "needs-review",
|
|
220
|
+
".claude/agents/verification-specialist.md": "needs-review",
|
|
221
|
+
".claude/agents/web-search-researcher.md": "needs-review",
|
|
222
|
+
".claude/commands/git": "needs-review",
|
|
223
|
+
".claude/commands/jira": "needs-review",
|
|
224
|
+
".claude/commands/lisa": "needs-review",
|
|
225
|
+
".claude/commands/plan": "needs-review",
|
|
226
|
+
".claude/commands/plans": "needs-review",
|
|
227
|
+
".claude/commands/pull-request": "needs-review",
|
|
228
|
+
".claude/commands/security": "needs-review",
|
|
229
|
+
".claude/commands/sonarqube": "needs-review",
|
|
230
|
+
".claude/commands/tasks": "needs-review",
|
|
231
|
+
".claude/skills/agent-design-best-practices": "needs-review",
|
|
232
|
+
".claude/skills/git-commit": "needs-review",
|
|
233
|
+
".claude/skills/git-commit-and-submit-pr": "needs-review",
|
|
234
|
+
".claude/skills/git-commit-submit-pr-and-verify": "needs-review",
|
|
235
|
+
".claude/skills/git-commit-submit-pr-deploy-and-verify": "needs-review",
|
|
236
|
+
".claude/skills/git-prune": "needs-review",
|
|
237
|
+
".claude/skills/git-submit-pr": "needs-review",
|
|
238
|
+
".claude/skills/jira-add-journey": "needs-review",
|
|
239
|
+
".claude/skills/jira-create": "needs-review",
|
|
240
|
+
".claude/skills/jira-evidence": "needs-review",
|
|
241
|
+
".claude/skills/jira-fix": "needs-review",
|
|
242
|
+
".claude/skills/jira-implement": "needs-review",
|
|
243
|
+
".claude/skills/jira-journey": "needs-review",
|
|
244
|
+
".claude/skills/jira-sync": "needs-review",
|
|
245
|
+
".claude/skills/jira-verify": "needs-review",
|
|
246
|
+
".claude/skills/lisa-review-implementation": "needs-review",
|
|
247
|
+
".claude/skills/plan-add-test-coverage": "needs-review",
|
|
248
|
+
".claude/skills/plan-execute": "needs-review",
|
|
249
|
+
".claude/skills/plan-fix-linter-error": "needs-review",
|
|
250
|
+
".claude/skills/plan-local-code-review": "needs-review",
|
|
251
|
+
".claude/skills/plan-lower-code-complexity": "needs-review",
|
|
252
|
+
".claude/skills/plan-reduce-max-lines": "needs-review",
|
|
253
|
+
".claude/skills/plan-reduce-max-lines-per-function": "needs-review",
|
|
254
|
+
".claude/skills/pull-request-review": "needs-review",
|
|
255
|
+
".claude/skills/security-zap-scan": "needs-review",
|
|
256
|
+
".claude/skills/skill-creator": "needs-review",
|
|
257
|
+
".claude/skills/sonarqube-check": "needs-review",
|
|
258
|
+
".claude/skills/sonarqube-fix": "needs-review",
|
|
259
|
+
".claude/skills/tasks-load": "needs-review",
|
|
260
|
+
".claude/skills/tasks-sync": "needs-review",
|
|
261
|
+
".claude/hooks/check-tired-boss.sh": "needs-review",
|
|
262
|
+
".claude/hooks/debug-hook.sh": "needs-review",
|
|
263
|
+
".claude/hooks/enforce-plan-rules.sh": "needs-review",
|
|
264
|
+
".claude/hooks/notify-ntfy.sh": "needs-review",
|
|
265
|
+
".claude/hooks/setup-jira-cli.sh": "needs-review",
|
|
266
|
+
".claude/hooks/sync-tasks.sh": "needs-review",
|
|
267
|
+
".claude/hooks/ticket-sync-reminder.sh": "needs-review",
|
|
268
|
+
".claude/hooks/track-plan-sessions.sh": "needs-review",
|
|
269
|
+
".claude/hooks/verify-completion.sh": "needs-review",
|
|
270
|
+
".claude/hooks/README.md": "needs-review",
|
|
271
|
+
".claude/rules/verfication.md": "needs-review",
|
|
272
|
+
".claude/rules/lisa.md": "needs-review",
|
|
273
|
+
".claude/rules/base-rules.md": "needs-review",
|
|
274
|
+
".claude/rules/coding-philosophy.md": "needs-review",
|
|
275
|
+
".claude/rules/intent-routing.md": "needs-review",
|
|
276
|
+
".claude/rules/security-audit-handling.md": "needs-review",
|
|
277
|
+
".claude/rules/verification.md": "needs-review",
|
|
278
|
+
".lisa-manifest": "needs-review"
|
|
279
|
+
}
|
|
145
280
|
}
|
package/cdk/deletions.json
CHANGED
|
@@ -5,5 +5,12 @@
|
|
|
5
5
|
"jest.cdk.ts",
|
|
6
6
|
"jest.base.ts",
|
|
7
7
|
"jest.thresholds.json"
|
|
8
|
-
]
|
|
8
|
+
],
|
|
9
|
+
"basis": {
|
|
10
|
+
"jest.config.ts": "needs-review",
|
|
11
|
+
"jest.config.local.ts": "needs-review",
|
|
12
|
+
"jest.cdk.ts": "needs-review",
|
|
13
|
+
"jest.base.ts": "needs-review",
|
|
14
|
+
"jest.thresholds.json": "needs-review"
|
|
15
|
+
}
|
|
9
16
|
}
|
package/dist/core/config.d.ts
CHANGED
|
@@ -272,6 +272,39 @@ export interface DeletionsConfig {
|
|
|
272
272
|
* to any other path is recorded and unused.
|
|
273
273
|
*/
|
|
274
274
|
readonly force?: Readonly<Record<string, string>>;
|
|
275
|
+
/**
|
|
276
|
+
* Why each declared path may be removed, keyed by that path.
|
|
277
|
+
*
|
|
278
|
+
* `deletions.json` authorises a removal by the path being LISTED, and nothing
|
|
279
|
+
* else — the manifest cannot see whether Lisa put that file in a given
|
|
280
|
+
* consumer's repository, because ownership is a per-consumer fact and this is
|
|
281
|
+
* a repo-side artifact. CodySwannGT/lisa#3656 closed the gap for
|
|
282
|
+
* `.github/workflows/` by reading each workflow's own ownership header, which
|
|
283
|
+
* covers 42 of 255 declared paths.
|
|
284
|
+
*
|
|
285
|
+
* The obvious rule for the other 213 — delete only what Lisa still ships —
|
|
286
|
+
* was measured and fails on 95% of them: 11 are attributable to a lane Lisa
|
|
287
|
+
* ships today and 202 are not, because the 202 ARE the point. They are skill
|
|
288
|
+
* trees Lisa renamed, and stranding them leaves every consumer carrying dead
|
|
289
|
+
* directories forever. So ownership stops being inferred and starts being
|
|
290
|
+
* declared, one of:
|
|
291
|
+
*
|
|
292
|
+
* - `owned` — Lisa installs this path today.
|
|
293
|
+
* - `legacy: <reason>` — Lisa shipped it once and no longer does; the reason
|
|
294
|
+
* names the version or ticket.
|
|
295
|
+
* - `needs-review` — declared before this field existed. Authorises removal
|
|
296
|
+
* exactly as before, so no consumer sees a behaviour change, while staying
|
|
297
|
+
* countable as debt rather than passing as classified.
|
|
298
|
+
*
|
|
299
|
+
* An ABSENT basis means "I cannot tell", which is deliberately distinct from
|
|
300
|
+
* "not owned": the uncertain case keeps the file and says so. A path wrongly
|
|
301
|
+
* kept is visible and fixable; a path wrongly deleted is gone from someone
|
|
302
|
+
* else's repository with no undo.
|
|
303
|
+
*
|
|
304
|
+
* A `force` entry is itself a basis and outranks this map.
|
|
305
|
+
* @see core/deletion-basis
|
|
306
|
+
*/
|
|
307
|
+
readonly basis?: Readonly<Record<string, string>>;
|
|
275
308
|
}
|
|
276
309
|
/**
|
|
277
310
|
* Result of a Lisa operation
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"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"}
|
package/dist/core/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAwBA;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAE/B;IACF,IAAI,EAAE,YAAY;IAClB,MAAM,EAAE,YAAY;IACpB,GAAG,EAAE,YAAY;IACjB,eAAe,EAAE,YAAY;IAC7B,MAAM,EAAE,YAAY;IACpB,aAAa,EAAE,YAAY;IAC3B,UAAU,EAAE,SAAS;IACrB,KAAK,EAAE,SAAS;CACR,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAA2B;IACxD,YAAY;IACZ,aAAa;IACb,eAAe;IACf,QAAQ;IACR,MAAM;IACN,QAAQ;IACR,KAAK;IACL,OAAO;CACC,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAA4B;IACtD,gBAAgB;IAChB,eAAe;IACf,aAAa;IACb,OAAO;IACP,cAAc;IACd,cAAc;CACN,CAAC;AAyBX;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAuB;IAChD,QAAQ;IACR,OAAO;IACP,QAAQ;IACR,KAAK;IACL,SAAS;IACT,UAAU;IACV,OAAO;CACC,CAAC;AAEX;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAsC;IAChE,GAAG,EAAE,OAAO;CACb,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAsB;IACxD,GAAG,cAAc;IACjB,GAAG,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC;CAChC,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAsC;IACvE,IAAI,EAAE,OAAO;CACd,CAAC;AASF;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,oBAAoB,CAClC,OAAgB,EAChB,KAAgB;IAEhB,IAAI,OAAO,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC;IACrC,OAAO,OAAO,KAAK,KAAK,CAAC;AAC3B,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAY,QAAQ,CAAC;AAoFjD;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAChC,YAAoB,EACpB,OAAqC;IAErC,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACxC,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IACxC,8EAA8E;IAC9E,0CAA0C;IAC1C,MAAM,MAAM,GAAG,YAAY,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAClD,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;QAC9B,MAAM,KAAK,GAAG,oBAAoB,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;QAC9D,OAAO,KAAK,KAAK,MAAM,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,oBAAoB,CAAC,KAAa;IACzC,OAAO,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAChF,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Why a declared path may be removed from a consumer's repository.
|
|
3
|
+
*
|
|
4
|
+
* `deletions.json` removes host files BY DESTINATION PATH ONLY. The path being
|
|
5
|
+
* listed is the entire authorisation: nothing between the manifest and
|
|
6
|
+
* `fse.remove` looks at the file's contents, its origin, or whether Lisa ever
|
|
7
|
+
* installed it. CodySwannGT/lisa#3656 closed that for `.github/workflows/` by
|
|
8
|
+
* reading each workflow's own ownership header, which covers 42 of 255 declared
|
|
9
|
+
* paths. This module is about the other 213.
|
|
10
|
+
*
|
|
11
|
+
* ## Why the obvious gate is not the fix
|
|
12
|
+
*
|
|
13
|
+
* The natural rule — "only delete what Lisa currently ships" — was measured
|
|
14
|
+
* against `main` and fails on 95% of the manifest: of the 213 non-workflow
|
|
15
|
+
* paths, 11 are attributable to a lane Lisa still ships and 202 are not. The
|
|
16
|
+
* 202 are not marginal. They are `.claude/skills/project-*`,
|
|
17
|
+
* `.claude/skills/git:*`, `.claude/skills/jira:*` and friends — skill trees Lisa
|
|
18
|
+
* renamed. Stranding them leaves every consumer carrying dead directories
|
|
19
|
+
* forever, which is the harm the manifest exists to prevent. A gate that causes
|
|
20
|
+
* the harm it was written to stop is the wrong gate.
|
|
21
|
+
*
|
|
22
|
+
* The reason it fails is structural rather than incidental: ownership is a
|
|
23
|
+
* per-consumer fact and the manifest is a repo-side artifact. Lisa cannot see,
|
|
24
|
+
* from its own tree, whether it put a given file in someone else's repository.
|
|
25
|
+
* No amount of matching logic closes that gap, so this module stops trying to
|
|
26
|
+
* infer ownership and requires it to be DECLARED.
|
|
27
|
+
*
|
|
28
|
+
* ## The grammar
|
|
29
|
+
*
|
|
30
|
+
* Every declared path carries a basis, and `force` counts as one:
|
|
31
|
+
*
|
|
32
|
+
* - `owned` — Lisa installs this path today; the lane is the evidence.
|
|
33
|
+
* - `legacy: <reason>` — Lisa shipped it in an older version and no longer
|
|
34
|
+
* does. The reason names the version or ticket. The honest home for the 202.
|
|
35
|
+
* - `needs-review` — declared before this field existed. Deletes exactly as it
|
|
36
|
+
* did before, so nothing changes for an existing consumer, but it is
|
|
37
|
+
* countable: debt kept visible rather than laundered as classified.
|
|
38
|
+
* - a `force` entry — a ruling that overrides even the workflow ownership gate.
|
|
39
|
+
* Unchanged by this module; its five existing entries keep working verbatim.
|
|
40
|
+
*
|
|
41
|
+
* ## What an ABSENT basis means, and why it keeps
|
|
42
|
+
*
|
|
43
|
+
* Unclassified is not "not owned" — it is "I cannot tell", and the two must be
|
|
44
|
+
* distinguishable or the uncertain case gets silently resolved as one of them.
|
|
45
|
+
* The cheap error is to keep the file: a path wrongly kept is visible and
|
|
46
|
+
* fixable, a path wrongly deleted is gone from someone else's repository with
|
|
47
|
+
* no undo. So an unclassified path is kept and announced.
|
|
48
|
+
*
|
|
49
|
+
* Two rules this deliberately does NOT implement, both learned in #3656:
|
|
50
|
+
*
|
|
51
|
+
* 1. Ownership is never inferred from a filename. A probe of the form "does
|
|
52
|
+
* Lisa ship a file with this name anywhere?" marks the highest-risk paths
|
|
53
|
+
* SAFE precisely because Lisa knows those names.
|
|
54
|
+
* 2. Ownership never keys on "was it modified". "The host has local work here"
|
|
55
|
+
* and "the host has re-armed the hazard" are the same observation on disk;
|
|
56
|
+
* only a declared reason separates them.
|
|
57
|
+
* @module core/deletion-basis
|
|
58
|
+
*/
|
|
59
|
+
import type { DeletionsConfig } from "./config.js";
|
|
60
|
+
/** How a declared deletion path is authorised. */
|
|
61
|
+
export type DeletionBasisKind = "owned" | "legacy" | "needs-review" | "force" | "unclassified";
|
|
62
|
+
/** The resolved basis for one declared path. */
|
|
63
|
+
export interface DeletionBasis {
|
|
64
|
+
readonly kind: DeletionBasisKind;
|
|
65
|
+
/** Prose accompanying a `legacy` or `force` basis; empty otherwise. */
|
|
66
|
+
readonly reason: string;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Resolve why one declared path may be removed.
|
|
70
|
+
*
|
|
71
|
+
* `force` is checked first and wins: it is the strongest declaration in the
|
|
72
|
+
* manifest, and a path carrying one is authorised whatever else says.
|
|
73
|
+
* @param config - The parsed manifest.
|
|
74
|
+
* @param relativePath - Declared path, spelled as the manifest spells it.
|
|
75
|
+
* @returns The basis, or `unclassified` when the manifest does not say.
|
|
76
|
+
*/
|
|
77
|
+
export declare function resolveDeletionBasis(config: DeletionsConfig, relativePath: string): DeletionBasis;
|
|
78
|
+
/**
|
|
79
|
+
* Whether a resolved basis authorises removal.
|
|
80
|
+
*
|
|
81
|
+
* `needs-review` authorises: this field lands with every existing path already
|
|
82
|
+
* marked, so an existing consumer sees byte-identical behaviour. The gate binds
|
|
83
|
+
* on paths added AFTER it, which is the whole point of shipping the mechanism
|
|
84
|
+
* before the prose.
|
|
85
|
+
* @param basis - A resolved basis.
|
|
86
|
+
* @returns True when the path may be removed.
|
|
87
|
+
*/
|
|
88
|
+
export declare function basisAuthorisesDeletion(basis: DeletionBasis): boolean;
|
|
89
|
+
/**
|
|
90
|
+
* Every declared path in one manifest that carries no basis.
|
|
91
|
+
*
|
|
92
|
+
* This is what the authoring gate refuses on. It is deliberately separate from
|
|
93
|
+
* the runtime keep-decision above: the runtime rule is the fail-safe that
|
|
94
|
+
* protects consumers whatever manifest they have, and this is the check that
|
|
95
|
+
* stops an unclassified path being authored in the first place. A single
|
|
96
|
+
* mechanism doing both would have to choose which to be.
|
|
97
|
+
* @param config - The parsed manifest.
|
|
98
|
+
* @returns Unclassified paths, in declaration order.
|
|
99
|
+
*/
|
|
100
|
+
export declare function unclassifiedDeletionPaths(config: DeletionsConfig): readonly string[];
|
|
101
|
+
/**
|
|
102
|
+
* Count declared paths by basis kind, for reporting the outstanding debt.
|
|
103
|
+
* @param config - The parsed manifest.
|
|
104
|
+
* @returns A count per kind, including zeroes.
|
|
105
|
+
*/
|
|
106
|
+
export declare function countDeletionBases(config: DeletionsConfig): Readonly<Record<DeletionBasisKind, number>>;
|
|
107
|
+
//# sourceMappingURL=deletion-basis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deletion-basis.d.ts","sourceRoot":"","sources":["../../src/core/deletion-basis.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,kDAAkD;AAClD,MAAM,MAAM,iBAAiB,GACzB,OAAO,GACP,QAAQ,GACR,cAAc,GACd,OAAO,GACP,cAAc,CAAC;AAEnB,gDAAgD;AAChD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,uEAAuE;IACvE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAMD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,eAAe,EACvB,YAAY,EAAE,MAAM,GACnB,aAAa,CAqBf;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAErE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,eAAe,GACtB,SAAS,MAAM,EAAE,CAMnB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,eAAe,GACtB,QAAQ,CAAC,MAAM,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC,CAc7C"}
|