Ver Fonte

fix: bump to 0.4.3, fix workspace: protocol leaking into published tarballs

Root cause: npm publish reads package.json metadata before running prepack,
so the prepack-based workspace:* replacement never takes effect.

Fix:
- Use pnpm publish for CLI (pnpm handles workspace: protocol natively)
- Add post-replacement verification in prepack script as safety net
- Standalone verify script for CI usage
- Remove broken prepublishOnly hook (runs before prepack, not after)
majx_mac há 8 meses atrás
pai
commit
f1e03b5a20

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "inkos",
-  "version": "0.4.1",
+  "version": "0.4.3",
   "private": true,
   "description": "Multi-agent novel production system",
   "license": "MIT",

+ 1 - 2
packages/cli/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@actalk/inkos",
-  "version": "0.4.1",
+  "version": "0.4.3",
   "description": "InkOS CLI — multi-agent novel production system",
   "type": "module",
   "bin": {
@@ -18,7 +18,6 @@
   },
   "scripts": {
     "prepack": "node ../../scripts/prepare-package-for-publish.mjs",
-    "prepublishOnly": "node ../../scripts/verify-no-workspace-protocol.mjs",
     "postpack": "node ../../scripts/restore-package-json.mjs",
     "build": "tsc",
     "dev": "tsc --watch",

+ 1 - 1
packages/core/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@actalk/inkos-core",
-  "version": "0.4.1",
+  "version": "0.4.3",
   "description": "InkOS core: models, agents, pipeline, LLM integration",
   "type": "module",
   "main": "dist/index.js",

+ 26 - 1
scripts/prepare-package-for-publish.mjs

@@ -7,7 +7,7 @@
  * Expects process.cwd() to be the package directory (npm/pnpm guarantee this).
  */
 
-import { readFile, writeFile, copyFile } from "node:fs/promises";
+import { readFile, writeFile, copyFile, rm } from "node:fs/promises";
 import { join, resolve } from "node:path";
 
 const packageDir = process.cwd();
@@ -99,6 +99,31 @@ async function main() {
 
   await writeFile(packageJsonPath, `${JSON.stringify(pkg, null, 2)}\n`, "utf-8");
   process.stderr.write(`[prepack] Replaced workspace:* deps in ${pkg.name}\n`);
+
+  // Verify: re-read and confirm no workspace: references remain
+  const verifyRaw = await readFile(packageJsonPath, "utf-8");
+  const verifyPkg = JSON.parse(verifyRaw);
+  const violations = [];
+  for (const field of ["dependencies", "optionalDependencies", "peerDependencies"]) {
+    const deps = verifyPkg[field];
+    if (!deps) continue;
+    for (const [name, specifier] of Object.entries(deps)) {
+      if (typeof specifier === "string" && specifier.startsWith("workspace:")) {
+        violations.push(`  ${field}.${name}: ${specifier}`);
+      }
+    }
+  }
+  if (violations.length > 0) {
+    process.stderr.write(
+      `[prepack] FATAL: workspace: references remain after replacement!\n` +
+      `${violations.join("\n")}\n`,
+    );
+    // Restore backup before aborting
+    const original = await readFile(backupPath, "utf-8");
+    await writeFile(packageJsonPath, original, "utf-8");
+    await rm(backupPath, { force: true });
+    process.exit(1);
+  }
 }
 
 await main();

+ 30 - 24
scripts/verify-no-workspace-protocol.mjs

@@ -1,40 +1,46 @@
 /**
- * prepublishOnly guard — aborts publish if package.json still contains workspace: protocol.
+ * Standalone verification: checks that no workspace: protocol remains in package.json.
  *
- * This runs AFTER prepack (which replaces workspace:* with real versions)
- * but BEFORE the actual upload. If prepack was skipped or failed silently,
- * this script catches it and prevents a broken publish.
+ * Usage:
+ *   node scripts/verify-no-workspace-protocol.mjs packages/cli packages/core
  *
- * Usage in each publishable package:
- *   "prepublishOnly": "node ../../scripts/verify-no-workspace-protocol.mjs"
+ * Used by CI and as a pre-publish sanity check. The prepack script also runs
+ * this check inline after replacement, but this script catches the case where
+ * prepack is skipped entirely.
  */
 
 import { readFile } from "node:fs/promises";
 import { join } from "node:path";
 
-const packageJsonPath = join(process.cwd(), "package.json");
-const raw = await readFile(packageJsonPath, "utf-8");
-const pkg = JSON.parse(raw);
+const dirs = process.argv.slice(2);
+if (dirs.length === 0) {
+  process.stderr.write("Usage: node verify-no-workspace-protocol.mjs <pkg-dir> [<pkg-dir>...]\n");
+  process.exit(1);
+}
+
+let failed = false;
 
-const violations = [];
+for (const dir of dirs) {
+  const packageJsonPath = join(dir, "package.json");
+  const raw = await readFile(packageJsonPath, "utf-8");
+  const pkg = JSON.parse(raw);
 
-for (const field of ["dependencies", "optionalDependencies", "peerDependencies"]) {
-  const deps = pkg[field];
-  if (!deps) continue;
-  for (const [name, specifier] of Object.entries(deps)) {
-    if (typeof specifier === "string" && specifier.startsWith("workspace:")) {
-      violations.push(`  ${field}.${name}: ${specifier}`);
+  for (const field of ["dependencies", "optionalDependencies", "peerDependencies"]) {
+    const deps = pkg[field];
+    if (!deps) continue;
+    for (const [name, specifier] of Object.entries(deps)) {
+      if (typeof specifier === "string" && specifier.startsWith("workspace:")) {
+        process.stderr.write(`FAIL: ${dir} — ${field}.${name}: ${specifier}\n`);
+        failed = true;
+      }
     }
   }
+
+  if (!failed) {
+    process.stderr.write(`OK: ${dir}\n`);
+  }
 }
 
-if (violations.length > 0) {
-  process.stderr.write(
-    `\n[ERROR] Cannot publish: package.json still contains workspace: protocol references.\n` +
-    `This means the prepack script did not run or failed silently.\n\n` +
-    `Violations:\n${violations.join("\n")}\n\n` +
-    `Fix: run "node ../../scripts/prepare-package-for-publish.mjs" manually,\n` +
-    `or check that "prepack" is configured in package.json scripts.\n\n`,
-  );
+if (failed) {
   process.exit(1);
 }