@dzhechkov/harness-core 0.3.30 → 0.3.31
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/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/publish.d.ts +4 -0
- package/dist/publish.d.ts.map +1 -1
- package/dist/publish.js +56 -8
- package/dist/publish.js.map +1 -1
- package/dist/upgrade.d.ts.map +1 -1
- package/dist/upgrade.js +23 -5
- package/dist/upgrade.js.map +1 -1
- package/package.json +4 -4
- package/src/index.ts +1 -1
- package/src/publish.ts +55 -8
- package/src/upgrade.ts +25 -6
package/dist/index.d.ts
CHANGED
|
@@ -26,7 +26,7 @@ export type { PluginManifest } from './plugin.js';
|
|
|
26
26
|
export type { SetupOptions, SetupResult, SetupStep } from './setup.js';
|
|
27
27
|
export type { PretrainResult, DetectedTech } from './pretrain.js';
|
|
28
28
|
export type { RecommendationReport, SkillRecommendation } from './recommend.js';
|
|
29
|
-
export { discoverPackages, publishPackages } from './publish.js';
|
|
29
|
+
export { discoverPackages, publishPackages, bumpPatch, compareVersions } from './publish.js';
|
|
30
30
|
export { fetchAllDownloads } from './downloads.js';
|
|
31
31
|
export type { PackageDownloads, DownloadsReport } from './downloads.js';
|
|
32
32
|
export { discoverInstalled, checkUpgrades } from './upgrade.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,mFAAmF;AACnF,eAAO,MAAM,oBAAoB,EAAE,MACiD,CAAC;AAErF,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAClH,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACtH,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,SAAS,EAAE,aAAa,EAAE,qBAAqB,EAAE,eAAe,EAAE,eAAe,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC5N,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AACpK,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClE,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -20,7 +20,7 @@ export { pretrain } from './pretrain.js';
|
|
|
20
20
|
export { loadPatterns, loadSessions, computePatternBoost, readLearningConfig, BOOST_CAP, recordPattern, loadStorePatternsSync, patternToRecord, recordToPattern, consolidateSessions, recallPatterns } from './patterns.js';
|
|
21
21
|
export { runSetup } from './setup.js';
|
|
22
22
|
export { generatePlugin } from './plugin.js';
|
|
23
|
-
export { discoverPackages, publishPackages } from './publish.js';
|
|
23
|
+
export { discoverPackages, publishPackages, bumpPatch, compareVersions } from './publish.js';
|
|
24
24
|
export { fetchAllDownloads } from './downloads.js';
|
|
25
25
|
export { discoverInstalled, checkUpgrades } from './upgrade.js';
|
|
26
26
|
export { computeRiskScore } from './risk-scoring.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,mFAAmF;AACnF,MAAM,CAAC,MAAM,oBAAoB,GAC9B,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAAyB,CAAC,OAAO,CAAC;AAErF,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAElH,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,SAAS,EAAE,aAAa,EAAE,qBAAqB,EAAE,eAAe,EAAE,eAAe,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE5N,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAK7C,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,mFAAmF;AACnF,MAAM,CAAC,MAAM,oBAAoB,GAC9B,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAAyB,CAAC,OAAO,CAAC;AAErF,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAElH,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,SAAS,EAAE,aAAa,EAAE,qBAAqB,EAAE,eAAe,EAAE,eAAe,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE5N,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAK7C,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC7F,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAGhE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,EACL,YAAY,EACZ,UAAU,EACV,cAAc,EACd,SAAS,EACT,cAAc,EACd,cAAc,EACd,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAS3B,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EACL,wBAAwB,EACxB,yBAAyB,EACzB,mBAAmB,EACnB,cAAc,EACd,QAAQ,GACT,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/publish.d.ts
CHANGED
|
@@ -20,6 +20,10 @@ export interface PublishReport {
|
|
|
20
20
|
readonly errors: number;
|
|
21
21
|
readonly dryRun: boolean;
|
|
22
22
|
}
|
|
23
|
+
/** Bump patch version: 0.3.11 → 0.3.12 */
|
|
24
|
+
export declare function bumpPatch(version: string): string;
|
|
25
|
+
/** Compare two x.y.z(-pre) versions by their core triple: >0 if a>b, <0 if a<b. */
|
|
26
|
+
export declare function compareVersions(a: string, b: string): number;
|
|
23
27
|
/** Discover all publishable @dzhechkov packages. */
|
|
24
28
|
export declare function discoverPackages(monorepoRoot: string): {
|
|
25
29
|
name: string;
|
package/dist/publish.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../src/publish.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,mDAAmD;AACnD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,OAAO,CAAC;IACnD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AAED,2BAA2B;AAC3B,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;IAC5C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;
|
|
1
|
+
{"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../src/publish.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,mDAAmD;AACnD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,OAAO,CAAC;IACnD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AAED,2BAA2B;AAC3B,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;IAC5C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAED,0CAA0C;AAC1C,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAcjD;AAED,mFAAmF;AACnF,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAK5D;AAsBD,oDAAoD;AACpD,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAAE,CAavG;AAED,6DAA6D;AAC7D,wBAAgB,eAAe,CAC7B,YAAY,EAAE,MAAM,EACpB,IAAI,GAAE;IACJ,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAC9B,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC3B,GACL,aAAa,CAqEf"}
|
package/dist/publish.js
CHANGED
|
@@ -8,10 +8,46 @@ import { existsSync, readFileSync, writeFileSync, readdirSync } from 'node:fs';
|
|
|
8
8
|
import { join } from 'node:path';
|
|
9
9
|
import { execSync } from 'node:child_process';
|
|
10
10
|
/** Bump patch version: 0.3.11 → 0.3.12 */
|
|
11
|
-
function bumpPatch(version) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
export function bumpPatch(version) {
|
|
12
|
+
// Parse the core x.y.z, tolerating a 2-part "x.y" (treated as x.y.0) and a
|
|
13
|
+
// prerelease/build suffix (e.g. "1.2.3-beta.2"). A prerelease bumps to its
|
|
14
|
+
// release (x.y.z), which semver-orders ABOVE the prerelease — never below it,
|
|
15
|
+
// and never silently drops to a lower number (audit #12).
|
|
16
|
+
const core = (version.split('+')[0] ?? version).split('-');
|
|
17
|
+
const hasPrerelease = core.length > 1;
|
|
18
|
+
const nums = (core[0] ?? '').split('.');
|
|
19
|
+
const major = parseInt(nums[0] ?? '0', 10) || 0;
|
|
20
|
+
const minor = parseInt(nums[1] ?? '0', 10) || 0;
|
|
21
|
+
const patch = parseInt(nums[2] ?? '0', 10) || 0;
|
|
22
|
+
// Releasing a prerelease keeps the same x.y.z (it outranks the prerelease);
|
|
23
|
+
// a normal release bumps the patch.
|
|
24
|
+
return hasPrerelease ? `${major}.${minor}.${patch}` : `${major}.${minor}.${patch + 1}`;
|
|
25
|
+
}
|
|
26
|
+
/** Compare two x.y.z(-pre) versions by their core triple: >0 if a>b, <0 if a<b. */
|
|
27
|
+
export function compareVersions(a, b) {
|
|
28
|
+
const core = (v) => ((v.split('+')[0] ?? v).split('-')[0] ?? '').split('.').map((n) => parseInt(n, 10) || 0);
|
|
29
|
+
const [a0 = 0, a1 = 0, a2 = 0] = core(a);
|
|
30
|
+
const [b0 = 0, b1 = 0, b2 = 0] = core(b);
|
|
31
|
+
return a0 - b0 || a1 - b1 || a2 - b2;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The version already published to npm for `name`, or `undefined` if the package
|
|
35
|
+
* has never been published (or npm is unreachable). Used to bump from
|
|
36
|
+
* max(local, published) so a locally-reverted version can't collide (audit #10).
|
|
37
|
+
*/
|
|
38
|
+
function publishedVersion(name) {
|
|
39
|
+
try {
|
|
40
|
+
const out = execSync(`npm view ${name} version`, { stdio: ['ignore', 'pipe', 'ignore'], encoding: 'utf-8', timeout: 20000 }).trim();
|
|
41
|
+
return /^\d+\.\d+\.\d+/.test(out) ? out : undefined;
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return undefined; // 404 (never published) or offline → fall back to local
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/** The higher of the local version and the npm-published version (audit #10). */
|
|
48
|
+
function maxPublished(name, localVersion) {
|
|
49
|
+
const pub = publishedVersion(name);
|
|
50
|
+
return pub !== undefined && compareVersions(pub, localVersion) > 0 ? pub : localVersion;
|
|
15
51
|
}
|
|
16
52
|
/** Discover all publishable @dzhechkov packages. */
|
|
17
53
|
export function discoverPackages(monorepoRoot) {
|
|
@@ -38,16 +74,20 @@ export function publishPackages(monorepoRoot, opts = {}) {
|
|
|
38
74
|
: packages;
|
|
39
75
|
for (const pkg of filtered) {
|
|
40
76
|
const oldVersion = pkg.version;
|
|
41
|
-
|
|
77
|
+
// Bump from max(local, npm-published) so a locally-reverted version can't
|
|
78
|
+
// collide with an already-published one (audit #10). Dry-run stays offline
|
|
79
|
+
// (local only) to keep previews fast and network-free.
|
|
80
|
+
const base = opts.dryRun ? oldVersion : maxPublished(pkg.name, oldVersion);
|
|
81
|
+
const newVersion = bumpPatch(base);
|
|
42
82
|
if (opts.dryRun) {
|
|
43
83
|
results.push({ name: pkg.name, oldVersion, newVersion, status: 'skipped' });
|
|
44
84
|
continue;
|
|
45
85
|
}
|
|
86
|
+
const pkgJsonPath = join(pkg.dir, 'package.json');
|
|
87
|
+
const originalPkgJson = readFileSync(pkgJsonPath, 'utf-8');
|
|
46
88
|
try {
|
|
47
89
|
// Bump version in package.json
|
|
48
|
-
|
|
49
|
-
const pkgJson = readFileSync(pkgJsonPath, 'utf-8');
|
|
50
|
-
writeFileSync(pkgJsonPath, pkgJson.replace(`"version": "${oldVersion}"`, `"version": "${newVersion}"`));
|
|
90
|
+
writeFileSync(pkgJsonPath, originalPkgJson.replace(`"version": "${oldVersion}"`, `"version": "${newVersion}"`));
|
|
51
91
|
if (opts.bumpOnly) {
|
|
52
92
|
results.push({ name: pkg.name, oldVersion, newVersion, status: 'published' });
|
|
53
93
|
continue;
|
|
@@ -67,6 +107,14 @@ export function publishPackages(monorepoRoot, opts = {}) {
|
|
|
67
107
|
results.push({ name: pkg.name, oldVersion, newVersion, status: 'published' });
|
|
68
108
|
}
|
|
69
109
|
catch (err) {
|
|
110
|
+
// The version was written BEFORE build+publish; on any failure restore the
|
|
111
|
+
// original package.json so a failed attempt doesn't orphan/skip a version
|
|
112
|
+
// number (audit #4). pnpm rewrites workspace:* deps in-place during publish,
|
|
113
|
+
// so restore the on-disk text we captured up front.
|
|
114
|
+
try {
|
|
115
|
+
writeFileSync(pkgJsonPath, originalPkgJson);
|
|
116
|
+
}
|
|
117
|
+
catch { /* best-effort restore */ }
|
|
70
118
|
results.push({
|
|
71
119
|
name: pkg.name,
|
|
72
120
|
oldVersion,
|
package/dist/publish.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publish.js","sourceRoot":"","sources":["../src/publish.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC/E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAoB9C,0CAA0C;AAC1C,
|
|
1
|
+
{"version":3,"file":"publish.js","sourceRoot":"","sources":["../src/publish.ts"],"names":[],"mappings":"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"}
|
package/dist/upgrade.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../src/upgrade.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../src/upgrade.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAeH,qCAAqC;AACrC,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;CAClC;AAED,wCAAwC;AACxC,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC;IACnC,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3C,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,2BAA2B;AAC3B,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,CAAC;CAC1C;AAED,gEAAgE;AAChE,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,EAAE,CAgBrE;AAED,qFAAqF;AACrF,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,EAAE,GACtB,aAAa,CA6Df"}
|
package/dist/upgrade.js
CHANGED
|
@@ -5,6 +5,16 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
|
7
7
|
import { join } from 'node:path';
|
|
8
|
+
import { createHash } from 'node:crypto';
|
|
9
|
+
/** Content hash of a file, or undefined if unreadable. */
|
|
10
|
+
function hashFile(path) {
|
|
11
|
+
try {
|
|
12
|
+
return createHash('sha1').update(readFileSync(path)).digest('hex');
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
8
18
|
/** Discover installed skills in a target platform directory. */
|
|
9
19
|
export function discoverInstalled(targetDir) {
|
|
10
20
|
if (!existsSync(targetDir))
|
|
@@ -27,7 +37,7 @@ export function discoverInstalled(targetDir) {
|
|
|
27
37
|
/** Check which installed skills need updates by comparing with canonical sources. */
|
|
28
38
|
export function checkUpgrades(targetDir, canonicalDirs) {
|
|
29
39
|
const installed = discoverInstalled(targetDir);
|
|
30
|
-
// Build canonical index: skill id → { dir, size }
|
|
40
|
+
// Build canonical index: skill id → { dir, size, hash }
|
|
31
41
|
const canonical = new Map();
|
|
32
42
|
for (const cDir of canonicalDirs) {
|
|
33
43
|
if (!existsSync(cDir))
|
|
@@ -37,7 +47,7 @@ export function checkUpgrades(targetDir, canonicalDirs) {
|
|
|
37
47
|
for (const skill of skills) {
|
|
38
48
|
const skillMdPath = join(cDir, skill.name, 'SKILL.md');
|
|
39
49
|
const stat = statSync(skillMdPath);
|
|
40
|
-
canonical.set(skill.name, { dir: join(cDir, skill.name), size: stat.size });
|
|
50
|
+
canonical.set(skill.name, { dir: join(cDir, skill.name), size: stat.size, hash: hashFile(skillMdPath) });
|
|
41
51
|
}
|
|
42
52
|
}
|
|
43
53
|
const checks = [];
|
|
@@ -53,15 +63,23 @@ export function checkUpgrades(targetDir, canonicalDirs) {
|
|
|
53
63
|
});
|
|
54
64
|
continue;
|
|
55
65
|
}
|
|
56
|
-
|
|
57
|
-
|
|
66
|
+
// Compare by CONTENT HASH, not byte-size: an equal-length edit (typo fix,
|
|
67
|
+
// word swap) must still register as "needs update", and a differing size
|
|
68
|
+
// alone doesn't prove the canonical is newer (audit #11). Fall back to a
|
|
69
|
+
// size comparison only if either file is unreadable.
|
|
70
|
+
const instHash = hashFile(join(inst.path, 'SKILL.md'));
|
|
71
|
+
const needsUpdate = can.hash !== undefined && instHash !== undefined
|
|
72
|
+
? instHash !== can.hash
|
|
73
|
+
: inst.size !== can.size;
|
|
58
74
|
checks.push({
|
|
59
75
|
id: inst.id,
|
|
60
76
|
installed: inst,
|
|
61
77
|
canonicalSize: can.size,
|
|
62
78
|
needsUpdate,
|
|
63
79
|
reason: needsUpdate
|
|
64
|
-
?
|
|
80
|
+
? (can.hash !== undefined && instHash !== undefined
|
|
81
|
+
? 'content differs from canonical'
|
|
82
|
+
: `size differs (installed: ${inst.size}B, canonical: ${can.size}B)`)
|
|
65
83
|
: 'up to date',
|
|
66
84
|
});
|
|
67
85
|
}
|
package/dist/upgrade.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upgrade.js","sourceRoot":"","sources":["../src/upgrade.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC1E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"upgrade.js","sourceRoot":"","sources":["../src/upgrade.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dzhechkov/harness-core",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.31",
|
|
4
4
|
"description": "Shared harness logic - skill loading, additive apply, and the init/sync/verify/doctor operations.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
"@dzhechkov/adapter-openclaude": "^0.1.0",
|
|
31
31
|
"@dzhechkov/adapter-opencode": "^0.2.0",
|
|
32
32
|
"yaml": "^2.0.0",
|
|
33
|
-
"@dzhechkov/
|
|
34
|
-
"@dzhechkov/
|
|
35
|
-
"@dzhechkov/
|
|
33
|
+
"@dzhechkov/core": "0.2.4",
|
|
34
|
+
"@dzhechkov/memory": "0.2.5",
|
|
35
|
+
"@dzhechkov/adapter-copilot": "0.1.1"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@types/node": "^25.6.0",
|
package/src/index.ts
CHANGED
|
@@ -31,7 +31,7 @@ export type { PluginManifest } from './plugin.js';
|
|
|
31
31
|
export type { SetupOptions, SetupResult, SetupStep } from './setup.js';
|
|
32
32
|
export type { PretrainResult, DetectedTech } from './pretrain.js';
|
|
33
33
|
export type { RecommendationReport, SkillRecommendation } from './recommend.js';
|
|
34
|
-
export { discoverPackages, publishPackages } from './publish.js';
|
|
34
|
+
export { discoverPackages, publishPackages, bumpPatch, compareVersions } from './publish.js';
|
|
35
35
|
export { fetchAllDownloads } from './downloads.js';
|
|
36
36
|
export type { PackageDownloads, DownloadsReport } from './downloads.js';
|
|
37
37
|
export { discoverInstalled, checkUpgrades } from './upgrade.js';
|
package/src/publish.ts
CHANGED
|
@@ -28,10 +28,48 @@ export interface PublishReport {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
/** Bump patch version: 0.3.11 → 0.3.12 */
|
|
31
|
-
function bumpPatch(version: string): string {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
export function bumpPatch(version: string): string {
|
|
32
|
+
// Parse the core x.y.z, tolerating a 2-part "x.y" (treated as x.y.0) and a
|
|
33
|
+
// prerelease/build suffix (e.g. "1.2.3-beta.2"). A prerelease bumps to its
|
|
34
|
+
// release (x.y.z), which semver-orders ABOVE the prerelease — never below it,
|
|
35
|
+
// and never silently drops to a lower number (audit #12).
|
|
36
|
+
const core = (version.split('+')[0] ?? version).split('-');
|
|
37
|
+
const hasPrerelease = core.length > 1;
|
|
38
|
+
const nums = (core[0] ?? '').split('.');
|
|
39
|
+
const major = parseInt(nums[0] ?? '0', 10) || 0;
|
|
40
|
+
const minor = parseInt(nums[1] ?? '0', 10) || 0;
|
|
41
|
+
const patch = parseInt(nums[2] ?? '0', 10) || 0;
|
|
42
|
+
// Releasing a prerelease keeps the same x.y.z (it outranks the prerelease);
|
|
43
|
+
// a normal release bumps the patch.
|
|
44
|
+
return hasPrerelease ? `${major}.${minor}.${patch}` : `${major}.${minor}.${patch + 1}`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Compare two x.y.z(-pre) versions by their core triple: >0 if a>b, <0 if a<b. */
|
|
48
|
+
export function compareVersions(a: string, b: string): number {
|
|
49
|
+
const core = (v: string): number[] => ((v.split('+')[0] ?? v).split('-')[0] ?? '').split('.').map((n) => parseInt(n, 10) || 0);
|
|
50
|
+
const [a0 = 0, a1 = 0, a2 = 0] = core(a);
|
|
51
|
+
const [b0 = 0, b1 = 0, b2 = 0] = core(b);
|
|
52
|
+
return a0 - b0 || a1 - b1 || a2 - b2;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* The version already published to npm for `name`, or `undefined` if the package
|
|
57
|
+
* has never been published (or npm is unreachable). Used to bump from
|
|
58
|
+
* max(local, published) so a locally-reverted version can't collide (audit #10).
|
|
59
|
+
*/
|
|
60
|
+
function publishedVersion(name: string): string | undefined {
|
|
61
|
+
try {
|
|
62
|
+
const out = execSync(`npm view ${name} version`, { stdio: ['ignore', 'pipe', 'ignore'], encoding: 'utf-8', timeout: 20000 }).trim();
|
|
63
|
+
return /^\d+\.\d+\.\d+/.test(out) ? out : undefined;
|
|
64
|
+
} catch {
|
|
65
|
+
return undefined; // 404 (never published) or offline → fall back to local
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** The higher of the local version and the npm-published version (audit #10). */
|
|
70
|
+
function maxPublished(name: string, localVersion: string): string {
|
|
71
|
+
const pub = publishedVersion(name);
|
|
72
|
+
return pub !== undefined && compareVersions(pub, localVersion) > 0 ? pub : localVersion;
|
|
35
73
|
}
|
|
36
74
|
|
|
37
75
|
/** Discover all publishable @dzhechkov packages. */
|
|
@@ -67,18 +105,22 @@ export function publishPackages(
|
|
|
67
105
|
|
|
68
106
|
for (const pkg of filtered) {
|
|
69
107
|
const oldVersion = pkg.version;
|
|
70
|
-
|
|
108
|
+
// Bump from max(local, npm-published) so a locally-reverted version can't
|
|
109
|
+
// collide with an already-published one (audit #10). Dry-run stays offline
|
|
110
|
+
// (local only) to keep previews fast and network-free.
|
|
111
|
+
const base = opts.dryRun ? oldVersion : maxPublished(pkg.name, oldVersion);
|
|
112
|
+
const newVersion = bumpPatch(base);
|
|
71
113
|
|
|
72
114
|
if (opts.dryRun) {
|
|
73
115
|
results.push({ name: pkg.name, oldVersion, newVersion, status: 'skipped' });
|
|
74
116
|
continue;
|
|
75
117
|
}
|
|
76
118
|
|
|
119
|
+
const pkgJsonPath = join(pkg.dir, 'package.json');
|
|
120
|
+
const originalPkgJson = readFileSync(pkgJsonPath, 'utf-8');
|
|
77
121
|
try {
|
|
78
122
|
// Bump version in package.json
|
|
79
|
-
|
|
80
|
-
const pkgJson = readFileSync(pkgJsonPath, 'utf-8');
|
|
81
|
-
writeFileSync(pkgJsonPath, pkgJson.replace(`"version": "${oldVersion}"`, `"version": "${newVersion}"`));
|
|
123
|
+
writeFileSync(pkgJsonPath, originalPkgJson.replace(`"version": "${oldVersion}"`, `"version": "${newVersion}"`));
|
|
82
124
|
|
|
83
125
|
if (opts.bumpOnly) {
|
|
84
126
|
results.push({ name: pkg.name, oldVersion, newVersion, status: 'published' });
|
|
@@ -101,6 +143,11 @@ export function publishPackages(
|
|
|
101
143
|
|
|
102
144
|
results.push({ name: pkg.name, oldVersion, newVersion, status: 'published' });
|
|
103
145
|
} catch (err) {
|
|
146
|
+
// The version was written BEFORE build+publish; on any failure restore the
|
|
147
|
+
// original package.json so a failed attempt doesn't orphan/skip a version
|
|
148
|
+
// number (audit #4). pnpm rewrites workspace:* deps in-place during publish,
|
|
149
|
+
// so restore the on-disk text we captured up front.
|
|
150
|
+
try { writeFileSync(pkgJsonPath, originalPkgJson); } catch { /* best-effort restore */ }
|
|
104
151
|
results.push({
|
|
105
152
|
name: pkg.name,
|
|
106
153
|
oldVersion,
|
package/src/upgrade.ts
CHANGED
|
@@ -6,6 +6,16 @@
|
|
|
6
6
|
|
|
7
7
|
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
|
8
8
|
import { join } from 'node:path';
|
|
9
|
+
import { createHash } from 'node:crypto';
|
|
10
|
+
|
|
11
|
+
/** Content hash of a file, or undefined if unreadable. */
|
|
12
|
+
function hashFile(path: string): string | undefined {
|
|
13
|
+
try {
|
|
14
|
+
return createHash('sha1').update(readFileSync(path)).digest('hex');
|
|
15
|
+
} catch {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
9
19
|
|
|
10
20
|
/** Info about an installed skill. */
|
|
11
21
|
export interface InstalledSkill {
|
|
@@ -61,8 +71,8 @@ export function checkUpgrades(
|
|
|
61
71
|
): UpgradeReport {
|
|
62
72
|
const installed = discoverInstalled(targetDir);
|
|
63
73
|
|
|
64
|
-
// Build canonical index: skill id → { dir, size }
|
|
65
|
-
const canonical = new Map<string, { dir: string; size: number }>();
|
|
74
|
+
// Build canonical index: skill id → { dir, size, hash }
|
|
75
|
+
const canonical = new Map<string, { dir: string; size: number; hash: string | undefined }>();
|
|
66
76
|
for (const cDir of canonicalDirs) {
|
|
67
77
|
if (!existsSync(cDir)) continue;
|
|
68
78
|
const skills = readdirSync(cDir, { withFileTypes: true })
|
|
@@ -70,7 +80,7 @@ export function checkUpgrades(
|
|
|
70
80
|
for (const skill of skills) {
|
|
71
81
|
const skillMdPath = join(cDir, skill.name, 'SKILL.md');
|
|
72
82
|
const stat = statSync(skillMdPath);
|
|
73
|
-
canonical.set(skill.name, { dir: join(cDir, skill.name), size: stat.size });
|
|
83
|
+
canonical.set(skill.name, { dir: join(cDir, skill.name), size: stat.size, hash: hashFile(skillMdPath) });
|
|
74
84
|
}
|
|
75
85
|
}
|
|
76
86
|
|
|
@@ -89,15 +99,24 @@ export function checkUpgrades(
|
|
|
89
99
|
continue;
|
|
90
100
|
}
|
|
91
101
|
|
|
92
|
-
|
|
93
|
-
|
|
102
|
+
// Compare by CONTENT HASH, not byte-size: an equal-length edit (typo fix,
|
|
103
|
+
// word swap) must still register as "needs update", and a differing size
|
|
104
|
+
// alone doesn't prove the canonical is newer (audit #11). Fall back to a
|
|
105
|
+
// size comparison only if either file is unreadable.
|
|
106
|
+
const instHash = hashFile(join(inst.path, 'SKILL.md'));
|
|
107
|
+
const needsUpdate =
|
|
108
|
+
can.hash !== undefined && instHash !== undefined
|
|
109
|
+
? instHash !== can.hash
|
|
110
|
+
: inst.size !== can.size;
|
|
94
111
|
checks.push({
|
|
95
112
|
id: inst.id,
|
|
96
113
|
installed: inst,
|
|
97
114
|
canonicalSize: can.size,
|
|
98
115
|
needsUpdate,
|
|
99
116
|
reason: needsUpdate
|
|
100
|
-
?
|
|
117
|
+
? (can.hash !== undefined && instHash !== undefined
|
|
118
|
+
? 'content differs from canonical'
|
|
119
|
+
: `size differs (installed: ${inst.size}B, canonical: ${can.size}B)`)
|
|
101
120
|
: 'up to date',
|
|
102
121
|
});
|
|
103
122
|
}
|