pm-ops 2026.9.23 → 2026.9.26

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/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## 2026.9.26 - 2026-09-26
4
+
5
+ ### Fixed
6
+
7
+ - A publish that npm accepts late is reported as failed and the GitHub Release is skipped on bun mirror lag ([ops-ssnr](https://github.com/unbraind/pm-ops/blob/main/.agents/pm/issues/ops-ssnr.toon))
8
+ - The guarded launcher template reads a pm-ops directory without package.json as an omit-dev install and skips the merge drivers ([ops-eyi8](https://github.com/unbraind/pm-ops/blob/main/.agents/pm/issues/ops-eyi8.toon))
9
+
10
+ ### Other
11
+
12
+ - Certify pm CLI 2026.9.23 and adopt the guarded pm-ops merge-driver launcher ([ops-me3v](https://github.com/unbraind/pm-ops/blob/main/.agents/pm/chores/ops-me3v.toon))
13
+
3
14
  ## 2026.9.18 - 2026-09-18
4
15
 
5
16
  ### Added
package/README.md CHANGED
@@ -306,6 +306,7 @@ Dynamic `import()` is forbidden by the fleet lint gate. Instead the template res
306
306
 
307
307
  - **pm-ops not installed** (`--omit=dev`): exits `0` after exactly one notice line
308
308
  - **pm-ops too old to export the entry, or its entry file missing**: fails the install loudly, and never skips
309
+ - **a broken install** (`node_modules/pm-ops` left as a directory without its `package.json`, or as a dangling link): fails the install loudly; resolution fails there with the same `MODULE_NOT_FOUND` an omit-dev install produces, so the template also looks for that entry before skipping
309
310
  - **pm-ops installed**: runs `runPrepareMergeDriver` (below) and propagates its exit status
310
311
 
311
312
  Fixture tests in `test/merge-driver-launcher.test.ts` execute the shipped template against each of
package/dist/index.js CHANGED
@@ -2082,7 +2082,7 @@ function renderDocstringsMarkdown(result) {
2082
2082
  const defineExtension = (module) => module;
2083
2083
  export default defineExtension({
2084
2084
  name: "pm-ops",
2085
- version: "2026.9.23",
2085
+ version: "2026.9.26",
2086
2086
  activate(api) {
2087
2087
  if (typeof api.registerRenderer === "function") {
2088
2088
  // Derived from OPS_COMMAND_PATHS rather than restated. A literal copy is
package/manifest.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pm-ops",
3
- "version": "2026.9.23",
3
+ "version": "2026.9.26",
4
4
  "description": "Multi-repo fleet operations for pm-cli",
5
5
  "author": "@unbraind",
6
6
  "entry": "./dist/index.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pm-ops",
3
- "version": "2026.9.23",
3
+ "version": "2026.9.26",
4
4
  "description": "Multi-repo fleet operations for pm-cli",
5
5
  "repository": {
6
6
  "type": "git",
@@ -121,13 +121,13 @@
121
121
  "@babel/eslint-parser": "^8.0.5",
122
122
  "@babel/plugin-syntax-typescript": "^8.0.3",
123
123
  "@types/node": "^26.2.0",
124
- "@unbrained/pm-cli": "2026.9.21",
124
+ "@unbrained/pm-cli": "2026.9.23",
125
125
  "c8": "^12.0.0",
126
126
  "eslint": "^10.10.0",
127
127
  "fast-glob": "^3.3.3",
128
128
  "jscpd": "^5.2.1",
129
129
  "jscpd4": "npm:jscpd@4.3.0",
130
- "pm-changelog": "2026.9.18"
130
+ "pm-changelog": "2026.9.23"
131
131
  },
132
132
  "keywords": [
133
133
  "pm-cli",
@@ -7,13 +7,15 @@
7
7
  * therefore imports nothing from pm-ops: it resolves the installer entry from
8
8
  * the package root and runs it in a child process. Only a missing pm-ops package skips, with one
9
9
  * notice; any other resolution failure (for example a pm-ops too old to export
10
- * the entry) and any installer failure fail the install.
10
+ * the entry, or a `pm-ops` directory whose package.json is gone) and any
11
+ * installer failure fail the install.
11
12
  *
12
13
  * Canonical copy: `pm-ops/templates/prepare-merge-driver.ts`. Copy it
13
14
  * unchanged to `scripts/prepare-merge-driver.ts`.
14
15
  */
15
16
 
16
17
  import { spawnSync } from "node:child_process";
18
+ import { lstatSync } from "node:fs";
17
19
  import { createRequire } from "node:module";
18
20
  import { join } from "node:path";
19
21
 
@@ -26,12 +28,17 @@ try {
26
28
  // Only an absent pm-ops package may skip. Probing its package.json tells that
27
29
  // apart from an installed pm-ops that cannot serve the entry (exports without
28
30
  // it, no exports map, a missing file): those resolve or fail differently, and
29
- // the original error is rethrown.
31
+ // the original error is rethrown. A probe that finds no package.json is not
32
+ // yet proof of absence: a broken install can leave `node_modules/pm-ops` (a
33
+ // directory or a dangling link) with no package.json, which fails the probe
34
+ // the same way, so an entry there also counts as present.
30
35
  let packagePresent = true;
31
36
  try {
32
37
  resolver.resolve("pm-ops/package.json");
33
38
  } catch (probe) {
34
- packagePresent = !(probe instanceof Error && "code" in probe && probe.code === "MODULE_NOT_FOUND");
39
+ packagePresent =
40
+ !(probe instanceof Error && "code" in probe && probe.code === "MODULE_NOT_FOUND") ||
41
+ lstatSync(join(process.cwd(), "node_modules", "pm-ops"), { throwIfNoEntry: false }) !== undefined;
35
42
  }
36
43
  if (packagePresent) throw error;
37
44
  }