teamix-evo 0.14.0 → 0.14.1
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/index.d.ts +19 -2
- package/dist/core/index.js +118 -30
- package/dist/core/index.js.map +1 -1
- package/dist/index.js +196 -44
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/core/index.d.ts
CHANGED
|
@@ -314,8 +314,14 @@ interface RunUiAddResult {
|
|
|
314
314
|
packageName: string;
|
|
315
315
|
/** Registered ids in install order (deps + requested). */
|
|
316
316
|
orderedIds: string[];
|
|
317
|
-
/** Number of files written. */
|
|
317
|
+
/** Number of files written (= created + overwritten). */
|
|
318
318
|
written: number;
|
|
319
|
+
/** Number of files newly created. */
|
|
320
|
+
created: number;
|
|
321
|
+
/** Number of existing files overwritten. */
|
|
322
|
+
overwritten: number;
|
|
323
|
+
/** Number of overwritten files that had local modifications. */
|
|
324
|
+
userModified: number;
|
|
319
325
|
/** Number of files skipped due to frozen + exists. */
|
|
320
326
|
skipped: number;
|
|
321
327
|
/** Aggregate npm dependencies of the installed entries. */
|
|
@@ -390,6 +396,9 @@ interface RunVariantUiAddResult {
|
|
|
390
396
|
variant: string;
|
|
391
397
|
orderedIds: string[];
|
|
392
398
|
written: number;
|
|
399
|
+
created: number;
|
|
400
|
+
overwritten: number;
|
|
401
|
+
userModified: number;
|
|
393
402
|
skipped: number;
|
|
394
403
|
npmDependencies: Record<string, string>;
|
|
395
404
|
resources: InstalledResource[];
|
|
@@ -883,6 +892,8 @@ interface UiInstallOptions {
|
|
|
883
892
|
skipExisting?: boolean;
|
|
884
893
|
/** When false, preserve directory structure in import paths (skip flattenRestPath). Defaults to true. */
|
|
885
894
|
flatten?: boolean;
|
|
895
|
+
/** Prior manifest resources for the same package — used to detect user-modified files before overwrite. */
|
|
896
|
+
priorResources?: InstalledResource[];
|
|
886
897
|
}
|
|
887
898
|
interface UiInstallResult {
|
|
888
899
|
/** Ordered list of entry ids that were processed (deps + requested) */
|
|
@@ -891,8 +902,14 @@ interface UiInstallResult {
|
|
|
891
902
|
resources: InstalledResource[];
|
|
892
903
|
/** Aggregate npm dependencies across the installed entries */
|
|
893
904
|
npmDependencies: Record<string, string>;
|
|
894
|
-
/** Number of files written */
|
|
905
|
+
/** Number of files written (= created + overwritten, kept for backwards compat) */
|
|
895
906
|
written: number;
|
|
907
|
+
/** Number of files newly created (target did not exist) */
|
|
908
|
+
created: number;
|
|
909
|
+
/** Number of existing files overwritten */
|
|
910
|
+
overwritten: number;
|
|
911
|
+
/** Number of overwritten files that had local modifications vs manifest hash */
|
|
912
|
+
userModified: number;
|
|
896
913
|
/** Number of files skipped because they already exist (frozen) */
|
|
897
914
|
skipped: number;
|
|
898
915
|
}
|
package/dist/core/index.js
CHANGED
|
@@ -165,12 +165,40 @@ async function readInstalledManifest(projectRoot) {
|
|
|
165
165
|
);
|
|
166
166
|
}
|
|
167
167
|
const result = validateInstalled(data);
|
|
168
|
-
if (
|
|
169
|
-
|
|
170
|
-
|
|
168
|
+
if (result.success) {
|
|
169
|
+
return result.data;
|
|
170
|
+
}
|
|
171
|
+
const migrated = migrateManifest(data);
|
|
172
|
+
const retryResult = validateInstalled(migrated);
|
|
173
|
+
if (retryResult.success) {
|
|
174
|
+
logger.warn(
|
|
175
|
+
"Migrated legacy manifest.json \u2014 will be overwritten on next install."
|
|
171
176
|
);
|
|
177
|
+
return retryResult.data;
|
|
172
178
|
}
|
|
173
|
-
|
|
179
|
+
throw new Error(
|
|
180
|
+
`Invalid manifest.json schema: ${result.error}. Fix the file manually or remove it to start fresh.`
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
function migrateManifest(data) {
|
|
184
|
+
if (typeof data !== "object" || data === null) return data;
|
|
185
|
+
const obj = data;
|
|
186
|
+
if (!("schemaVersion" in obj)) obj.schemaVersion = 1;
|
|
187
|
+
if (!Array.isArray(obj.installed)) obj.installed = [];
|
|
188
|
+
for (const pkg of obj.installed) {
|
|
189
|
+
if (typeof pkg !== "object" || pkg === null) continue;
|
|
190
|
+
if (!pkg.variant) pkg.variant = "_flat";
|
|
191
|
+
if (!pkg.installedAt) pkg.installedAt = "";
|
|
192
|
+
if (!pkg.version) pkg.version = "0.0.0";
|
|
193
|
+
if (Array.isArray(pkg.resources)) {
|
|
194
|
+
for (const res of pkg.resources) {
|
|
195
|
+
if (typeof res !== "object" || res === null) continue;
|
|
196
|
+
if (!res.hash) res.hash = "sha256:legacy-unknown";
|
|
197
|
+
if (!res.strategy) res.strategy = "frozen";
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return obj;
|
|
174
202
|
}
|
|
175
203
|
async function writeInstalledManifest(projectRoot, manifest) {
|
|
176
204
|
const manifestPath = path2.join(projectRoot, TEAMIX_DIR, MANIFEST_FILE);
|
|
@@ -948,9 +976,15 @@ function partitionByVersion(ids, manifest, existing) {
|
|
|
948
976
|
onlyIds.push(name);
|
|
949
977
|
continue;
|
|
950
978
|
}
|
|
951
|
-
const installedVer = existing.lock?.skills?.[name]?.version;
|
|
979
|
+
const installedVer = existing.lock?.skills?.[name]?.version ?? existing.pkg?.version;
|
|
952
980
|
const latestVer = manifestById.get(name)?.version;
|
|
953
|
-
if (installedVer
|
|
981
|
+
if (!installedVer || !latestVer) {
|
|
982
|
+
if (latestVer) {
|
|
983
|
+
outdatedSkills.push({ id: name, installed: "0.0.0", latest: latestVer });
|
|
984
|
+
} else {
|
|
985
|
+
skippedSkillIds.push(name);
|
|
986
|
+
}
|
|
987
|
+
} else if (compareSemver(installedVer, latestVer) < 0) {
|
|
954
988
|
outdatedSkills.push({
|
|
955
989
|
id: name,
|
|
956
990
|
installed: installedVer,
|
|
@@ -1669,13 +1703,34 @@ async function runSkillsUpdate(options) {
|
|
|
1669
1703
|
}
|
|
1670
1704
|
const ides = skillsCfg.ides ?? ["qoder", "claude"];
|
|
1671
1705
|
const scope = skillsCfg.scope ?? "project";
|
|
1672
|
-
|
|
1706
|
+
let existingLock = await readSkillsLock(projectRoot);
|
|
1673
1707
|
if (!existingLock || Object.keys(existingLock.skills).length === 0) {
|
|
1674
|
-
|
|
1708
|
+
const installedManifest2 = await readInstalledManifest(projectRoot);
|
|
1709
|
+
const pkg = installedManifest2?.installed.find(
|
|
1710
|
+
(p) => p.package === packageName
|
|
1711
|
+
);
|
|
1712
|
+
if (!pkg || pkg.resources.length === 0) {
|
|
1713
|
+
return { status: "no-skills" };
|
|
1714
|
+
}
|
|
1715
|
+
const derivedSkills = {};
|
|
1716
|
+
for (const r of pkg.resources) {
|
|
1717
|
+
const skillId = r.id.split(":")[0] ?? r.id;
|
|
1718
|
+
if (!derivedSkills[skillId]) {
|
|
1719
|
+
derivedSkills[skillId] = {
|
|
1720
|
+
version: pkg.version,
|
|
1721
|
+
from: packageName,
|
|
1722
|
+
installedAt: "",
|
|
1723
|
+
scope,
|
|
1724
|
+
mirroredTo: []
|
|
1725
|
+
};
|
|
1726
|
+
}
|
|
1727
|
+
}
|
|
1728
|
+
existingLock = { schemaVersion: 1, skills: derivedSkills };
|
|
1675
1729
|
}
|
|
1730
|
+
const activeLock = existingLock;
|
|
1676
1731
|
const { manifest, data, packageRoot } = await loadSkillsData(packageName);
|
|
1677
1732
|
const manifestById = new Map(manifest.skills.map((s) => [s.id, s]));
|
|
1678
|
-
const lockIds = Object.keys(
|
|
1733
|
+
const lockIds = Object.keys(activeLock.skills);
|
|
1679
1734
|
const requestedSet = requestedNames ? new Set(requestedNames) : null;
|
|
1680
1735
|
if (requestedSet) {
|
|
1681
1736
|
const unknown = requestedNames.filter(
|
|
@@ -1712,7 +1767,7 @@ async function runSkillsUpdate(options) {
|
|
|
1712
1767
|
targetIds.push(id);
|
|
1713
1768
|
}
|
|
1714
1769
|
const allSame = targetIds.every((id) => {
|
|
1715
|
-
const lockVer =
|
|
1770
|
+
const lockVer = activeLock.skills[id].version;
|
|
1716
1771
|
const manVer = manifestById.get(id).version;
|
|
1717
1772
|
return lockVer === manVer;
|
|
1718
1773
|
});
|
|
@@ -1726,7 +1781,7 @@ async function runSkillsUpdate(options) {
|
|
|
1726
1781
|
}
|
|
1727
1782
|
if (dryRun) {
|
|
1728
1783
|
const plan = targetIds.map((id) => {
|
|
1729
|
-
const lockVer =
|
|
1784
|
+
const lockVer = activeLock.skills[id].version;
|
|
1730
1785
|
const entry2 = manifestById.get(id);
|
|
1731
1786
|
const sameVersion = lockVer === entry2.version;
|
|
1732
1787
|
return {
|
|
@@ -1798,7 +1853,7 @@ async function runSkillsUpdate(options) {
|
|
|
1798
1853
|
await writeInstalledManifest(projectRoot, installedManifest);
|
|
1799
1854
|
const lock = {
|
|
1800
1855
|
schemaVersion: 1,
|
|
1801
|
-
skills: { ...
|
|
1856
|
+
skills: { ...activeLock.skills }
|
|
1802
1857
|
};
|
|
1803
1858
|
for (const id of targetIds) {
|
|
1804
1859
|
const skillDef = manifestById.get(id);
|
|
@@ -1984,8 +2039,14 @@ async function installUiEntries(options) {
|
|
|
1984
2039
|
const idToEntry = new Map(manifest.entries.map((e) => [e.id, e]));
|
|
1985
2040
|
const resources = [];
|
|
1986
2041
|
const npmDeps = {};
|
|
1987
|
-
let
|
|
2042
|
+
let created = 0;
|
|
2043
|
+
let overwritten = 0;
|
|
2044
|
+
let userModified = 0;
|
|
1988
2045
|
let skipped = 0;
|
|
2046
|
+
const { priorResources } = options;
|
|
2047
|
+
const priorByTarget = new Map(
|
|
2048
|
+
(priorResources ?? []).map((r) => [r.target, r])
|
|
2049
|
+
);
|
|
1989
2050
|
for (const id of orderedIds) {
|
|
1990
2051
|
const entry = idToEntry.get(id);
|
|
1991
2052
|
if (!entry) continue;
|
|
@@ -2019,11 +2080,25 @@ async function installUiEntries(options) {
|
|
|
2019
2080
|
});
|
|
2020
2081
|
continue;
|
|
2021
2082
|
}
|
|
2083
|
+
const relPath = path11.relative(projectRoot, targetAbs);
|
|
2084
|
+
const prior = priorByTarget.get(relPath);
|
|
2085
|
+
if (prior && prior.hash !== "sha256:legacy-unknown") {
|
|
2086
|
+
const onDiskHash = computeHash(current);
|
|
2087
|
+
if (onDiskHash !== prior.hash) {
|
|
2088
|
+
logger.warn(
|
|
2089
|
+
` \u26A0 ${relPath} has local modifications (backed up)`
|
|
2090
|
+
);
|
|
2091
|
+
userModified++;
|
|
2092
|
+
}
|
|
2093
|
+
}
|
|
2022
2094
|
await backupFile(targetAbs, projectRoot);
|
|
2095
|
+
overwritten++;
|
|
2096
|
+
logger.info(` overwrite: ${rel(projectRoot, targetAbs)}`);
|
|
2097
|
+
} else {
|
|
2098
|
+
created++;
|
|
2099
|
+
logger.info(` create: ${rel(projectRoot, targetAbs)}`);
|
|
2023
2100
|
}
|
|
2024
2101
|
await writeFileSafe(targetAbs, transformed);
|
|
2025
|
-
written++;
|
|
2026
|
-
logger.info(` write: ${rel(projectRoot, targetAbs)}`);
|
|
2027
2102
|
resources.push({
|
|
2028
2103
|
id: `${entry.id}:${file.targetName}`,
|
|
2029
2104
|
target: path11.relative(projectRoot, targetAbs),
|
|
@@ -2036,7 +2111,10 @@ async function installUiEntries(options) {
|
|
|
2036
2111
|
orderedIds,
|
|
2037
2112
|
resources,
|
|
2038
2113
|
npmDependencies: npmDeps,
|
|
2039
|
-
written,
|
|
2114
|
+
written: created + overwritten,
|
|
2115
|
+
created,
|
|
2116
|
+
overwritten,
|
|
2117
|
+
userModified,
|
|
2040
2118
|
skipped
|
|
2041
2119
|
};
|
|
2042
2120
|
}
|
|
@@ -2115,17 +2193,22 @@ async function runUiAdd(options) {
|
|
|
2115
2193
|
`Unknown entry id(s): ${unknown.map((s) => `"${s}"`).join(", ")}. Run \`teamix-evo ui list\` to see options.`
|
|
2116
2194
|
);
|
|
2117
2195
|
}
|
|
2196
|
+
const existingManifest = await readInstalledManifest(
|
|
2197
|
+
projectRoot
|
|
2198
|
+
) ?? { schemaVersion: 1, installed: [] };
|
|
2199
|
+
const priorPkg = existingManifest.installed.find(
|
|
2200
|
+
(p) => p.package === packageName
|
|
2201
|
+
);
|
|
2118
2202
|
const result = await installUiEntries({
|
|
2119
2203
|
projectRoot,
|
|
2120
2204
|
manifest: effectiveManifest,
|
|
2121
2205
|
packageRoot,
|
|
2122
2206
|
aliases: uiCfg.aliases,
|
|
2123
2207
|
requested: ids,
|
|
2124
|
-
skipExisting: !overwrite
|
|
2208
|
+
skipExisting: !overwrite,
|
|
2209
|
+
priorResources: priorPkg?.resources
|
|
2125
2210
|
});
|
|
2126
|
-
const installed =
|
|
2127
|
-
projectRoot
|
|
2128
|
-
) ?? { schemaVersion: 1, installed: [] };
|
|
2211
|
+
const installed = existingManifest;
|
|
2129
2212
|
const idx = installed.installed.findIndex((p) => p.package === packageName);
|
|
2130
2213
|
const prior = idx >= 0 ? installed.installed[idx] : null;
|
|
2131
2214
|
const mergedResources = mergeResources(
|
|
@@ -2150,6 +2233,9 @@ async function runUiAdd(options) {
|
|
|
2150
2233
|
packageName,
|
|
2151
2234
|
orderedIds: result.orderedIds,
|
|
2152
2235
|
written: result.written,
|
|
2236
|
+
created: result.created,
|
|
2237
|
+
overwritten: result.overwritten,
|
|
2238
|
+
userModified: result.userModified,
|
|
2153
2239
|
skipped: result.skipped,
|
|
2154
2240
|
npmDependencies: result.npmDependencies,
|
|
2155
2241
|
resources: result.resources
|
|
@@ -2260,24 +2346,23 @@ async function runVariantUiAdd(packageName, options) {
|
|
|
2260
2346
|
engines: variantManifest.engines,
|
|
2261
2347
|
entries: mergedEntries
|
|
2262
2348
|
};
|
|
2349
|
+
const installed = await readInstalledManifest(
|
|
2350
|
+
projectRoot
|
|
2351
|
+
) ?? { schemaVersion: 1, installed: [] };
|
|
2352
|
+
const idx = installed.installed.findIndex(
|
|
2353
|
+
(p) => p.package === fullPackageName && p.variant === variant
|
|
2354
|
+
);
|
|
2355
|
+
const prior = idx >= 0 ? installed.installed[idx] : null;
|
|
2263
2356
|
const result = await installUiEntries({
|
|
2264
2357
|
projectRoot,
|
|
2265
2358
|
manifest: adaptedManifest,
|
|
2266
2359
|
packageRoot: variantDir,
|
|
2267
|
-
// default for variant entries
|
|
2268
2360
|
entryPackageRoot,
|
|
2269
|
-
// ui entries resolve from uiPackageRoot
|
|
2270
2361
|
aliases: uiCfg.aliases,
|
|
2271
2362
|
requested: ids,
|
|
2272
|
-
skipExisting: !overwrite
|
|
2363
|
+
skipExisting: !overwrite,
|
|
2364
|
+
priorResources: prior?.resources
|
|
2273
2365
|
});
|
|
2274
|
-
const installed = await readInstalledManifest(
|
|
2275
|
-
projectRoot
|
|
2276
|
-
) ?? { schemaVersion: 1, installed: [] };
|
|
2277
|
-
const idx = installed.installed.findIndex(
|
|
2278
|
-
(p) => p.package === fullPackageName && p.variant === variant
|
|
2279
|
-
);
|
|
2280
|
-
const prior = idx >= 0 ? installed.installed[idx] : null;
|
|
2281
2366
|
const mergedResources = mergeResources2(
|
|
2282
2367
|
prior?.resources ?? [],
|
|
2283
2368
|
result.resources
|
|
@@ -2297,6 +2382,9 @@ async function runVariantUiAdd(packageName, options) {
|
|
|
2297
2382
|
variant,
|
|
2298
2383
|
orderedIds: result.orderedIds,
|
|
2299
2384
|
written: result.written,
|
|
2385
|
+
created: result.created,
|
|
2386
|
+
overwritten: result.overwritten,
|
|
2387
|
+
userModified: result.userModified,
|
|
2300
2388
|
skipped: result.skipped,
|
|
2301
2389
|
npmDependencies: result.npmDependencies,
|
|
2302
2390
|
resources: result.resources
|