@codyswann/lisa 4.4.8 → 4.4.9
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/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +5 -2
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/package.json +1 -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/scripts/lib/plugin-cache-resolution.mjs +325 -0
- package/scripts/plugin-parity-drift.mjs +20 -253
- package/scripts/plugin-routing-validate.mjs +32 -68
|
@@ -39,16 +39,18 @@ import process from "node:process";
|
|
|
39
39
|
import { fileURLToPath } from "node:url";
|
|
40
40
|
|
|
41
41
|
import { invokedAsScript } from "./lib/invoked-as-script.mjs";
|
|
42
|
-
import {
|
|
42
|
+
import {
|
|
43
|
+
compareSemver,
|
|
44
|
+
isDirectory,
|
|
45
|
+
isValidSemver,
|
|
46
|
+
resolveCurrentVersion,
|
|
47
|
+
} from "./lib/plugin-cache-resolution.mjs";
|
|
43
48
|
|
|
44
49
|
const REPO_ROOT = path.resolve(
|
|
45
50
|
path.dirname(fileURLToPath(import.meta.url)),
|
|
46
51
|
".."
|
|
47
52
|
);
|
|
48
53
|
|
|
49
|
-
/** A plugin name / marketplace token: `1*(ALPHA / DIGIT / "-" / "_")`. */
|
|
50
|
-
const TOKEN_RE = /^[A-Za-z0-9_-]+$/;
|
|
51
|
-
|
|
52
54
|
/** The non-Claude-native agents that every routing block must cover, exactly. */
|
|
53
55
|
const AGENTS = ["agy", "codex", "copilot", "cursor"];
|
|
54
56
|
|
|
@@ -87,78 +89,40 @@ const QUOTE_LEN = 60;
|
|
|
87
89
|
export class UsageError extends Error {}
|
|
88
90
|
|
|
89
91
|
/**
|
|
90
|
-
*
|
|
92
|
+
* The max semver across a plugin's LIVE cache version subdirs, or `null`.
|
|
91
93
|
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
return false;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Read a plugin manifest's `version` field, or `null` if unreadable / invalid.
|
|
94
|
+
* This used to walk the cache itself while importing only the semver helpers
|
|
95
|
+
* from the drift detector, which made the two scripts look like one resolver
|
|
96
|
+
* and behave like two. They disagreed about orphans: the detector was fixed to
|
|
97
|
+
* skip `.orphaned_at` directories (CodySwannGT/lisa#3085) and this walk was
|
|
98
|
+
* not, so it went on resolving a "current" version out of directories that were
|
|
99
|
+
* uninstalled ten days earlier — and the import argued the fix was already
|
|
100
|
+
* applied here (CodySwannGT/lisa#3093).
|
|
105
101
|
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
* Resolve the max semver across a plugin's cache version subdirs, mirroring the
|
|
120
|
-
* analyze-plugin Version-fallback rule: prefer each subdir's manifest `version`,
|
|
121
|
-
* else fall back to the subdir NAME when it is itself semver (some plugins ship
|
|
122
|
-
* no manifest version but a semver-named dir). Returns `null` when neither the
|
|
123
|
-
* plugin nor any semver is present.
|
|
102
|
+
* It now calls the one resolver. `dirNameFallback` is this caller's single
|
|
103
|
+
* genuine difference, and it is named rather than implied: a semver DIRECTORY
|
|
104
|
+
* NAME stands in when a live version's manifest carries no usable `version`,
|
|
105
|
+
* which the drift detector deliberately does not do.
|
|
106
|
+
*
|
|
107
|
+
* ## Why both non-`ok` statuses collapse to `null` here
|
|
108
|
+
*
|
|
109
|
+
* The resolver distinguishes `not-installed` (no live directory at all) from
|
|
110
|
+
* `unresolved` (a live directory whose manifest will not parse), and that
|
|
111
|
+
* distinction is load-bearing in the detector's report. This caller has one
|
|
112
|
+
* question — "is there a version to compare against?" — and both answers are
|
|
113
|
+
* "no". The collapse is deliberate and local; the states stay distinct in the
|
|
114
|
+
* resolver so the detector can keep telling them apart.
|
|
124
115
|
*
|
|
125
116
|
* @param {string} cacheRoot - the installed-plugin cache root.
|
|
126
117
|
* @param {string} name - plugin name.
|
|
127
118
|
* @param {string} marketplace - marketplace id.
|
|
128
|
-
* @returns {string | null} the max semver, or `null`.
|
|
119
|
+
* @returns {string | null} the max live semver, or `null`.
|
|
129
120
|
*/
|
|
130
121
|
export function cacheMaxVersion(cacheRoot, name, marketplace) {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
if (!isDirectory(dir)) {
|
|
136
|
-
return null;
|
|
137
|
-
}
|
|
138
|
-
const versions = [];
|
|
139
|
-
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
140
|
-
if (!entry.isDirectory()) {
|
|
141
|
-
continue;
|
|
142
|
-
}
|
|
143
|
-
const manifestVersion = readManifestVersion(
|
|
144
|
-
path.join(dir, entry.name, ".claude-plugin", "plugin.json")
|
|
145
|
-
);
|
|
146
|
-
if (manifestVersion !== null && isValidSemver(manifestVersion)) {
|
|
147
|
-
versions.push(manifestVersion);
|
|
148
|
-
} else if (isValidSemver(entry.name)) {
|
|
149
|
-
versions.push(entry.name);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
if (versions.length === 0) {
|
|
153
|
-
return null;
|
|
154
|
-
}
|
|
155
|
-
// `versions` is non-empty (guarded above), so seeding with the first element
|
|
156
|
-
// is exactly what the no-seed form did — and it cannot throw if that guard is
|
|
157
|
-
// ever moved.
|
|
158
|
-
return versions.reduce(
|
|
159
|
-
(acc, v) => (compareSemver(v, acc) > 0 ? v : acc),
|
|
160
|
-
versions[0]
|
|
161
|
-
);
|
|
122
|
+
const resolved = resolveCurrentVersion(cacheRoot, name, marketplace, {
|
|
123
|
+
dirNameFallback: true,
|
|
124
|
+
});
|
|
125
|
+
return resolved.status === "ok" ? resolved.version : null;
|
|
162
126
|
}
|
|
163
127
|
|
|
164
128
|
/**
|