@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 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';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
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;AACjE,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"}
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;
@@ -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;AASD,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,CA4Df"}
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
- const parts = version.split('.');
13
- const patch = parseInt(parts[2] ?? '0', 10);
14
- return `${parts[0]}.${parts[1]}.${patch + 1}`;
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
- const newVersion = bumpPatch(oldVersion);
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
- const pkgJsonPath = join(pkg.dir, 'package.json');
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,
@@ -1 +1 @@
1
- {"version":3,"file":"publish.js","sourceRoot":"","sources":["../src/publish.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"publish.js","sourceRoot":"","sources":["../src/publish.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../src/upgrade.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,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,CAoDf"}
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
- const sizeDiff = Math.abs(inst.size - can.size);
57
- const needsUpdate = sizeDiff > 0;
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
- ? `size differs (installed: ${inst.size}B, canonical: ${can.size}B, delta: ${sizeDiff}B)`
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
  }
@@ -1 +1 @@
1
- {"version":3,"file":"upgrade.js","sourceRoot":"","sources":["../src/upgrade.ts"],"names":[],"mappings":"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"}
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.30",
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/adapter-copilot": "0.1.1",
34
- "@dzhechkov/core": "0.2.3",
35
- "@dzhechkov/memory": "0.2.5"
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
- const parts = version.split('.');
33
- const patch = parseInt(parts[2] ?? '0', 10);
34
- return `${parts[0]}.${parts[1]}.${patch + 1}`;
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
- const newVersion = bumpPatch(oldVersion);
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
- const pkgJsonPath = join(pkg.dir, 'package.json');
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
- const sizeDiff = Math.abs(inst.size - can.size);
93
- const needsUpdate = sizeDiff > 0;
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
- ? `size differs (installed: ${inst.size}B, canonical: ${can.size}B, delta: ${sizeDiff}B)`
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
  }