@qaping/cli 0.1.4 → 0.1.5

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.
Files changed (2) hide show
  1. package/bin/qaping +35 -2
  2. package/package.json +2 -1
package/bin/qaping CHANGED
@@ -22,6 +22,11 @@ const { spawnSync } = require("child_process");
22
22
 
23
23
  const QPKG = path.resolve(__dirname, "..");
24
24
 
25
+ // The name npm actually serves. The bare `qaping` is refused by the registry's
26
+ // similarity rule (petition open, QAPING_PLAN.md §8), so every global install —
27
+ // the wrapper's own and the one the kit's setup performs — must use this.
28
+ const NPM_PACKAGE = "@qaping/cli";
29
+
25
30
  // The kit is a normal npm dependency when qaping is installed, and a workspace
26
31
  // sibling in the monorepo checkout (where node_modules may not be linked yet)
27
32
  // — resolve the package, never a hardcoded install path.
@@ -55,7 +60,7 @@ function qapingWrapper() {
55
60
  brand: "qaping",
56
61
  // npm registry name ≠ bin name: the similarity rule blocks bare "qaping"
57
62
  // (petition open, QAPING_PLAN §8), so the global install pulls @qaping/cli.
58
- installPackage: "@qaping/cli",
63
+ installPackage: NPM_PACKAGE,
59
64
  appUrl: process.env.QAPING_APP_URL || undefined,
60
65
  mcpPath: "/api/mcp/qaping",
61
66
  serverKey: "qaping",
@@ -122,6 +127,32 @@ function defaultIO(kitDir) {
122
127
 
123
128
  const VALID_CLIENTS = ["claude-desktop", "claude-code", "cursor", "codex"];
124
129
 
130
+ // The kit's setup step 2 installs the global bin as `npm i -g <brand>` unless
131
+ // it is handed an installPackage — and a PUBLISHED kit older than that option
132
+ // ignores it, so it runs `npm i -g qaping`, a name npm's similarity rule
133
+ // refuses to host (404). Hit live on a fresh machine: setup configured every
134
+ // MCP client and reused the login, then reported "Setup incomplete" over that
135
+ // one 404.
136
+ //
137
+ // So the wrapper installs its OWN bin first, under the name npm serves. Once
138
+ // `qaping` is on PATH the kit's step finds it and logs "already installed
139
+ // globally", whatever kit version is underneath. npx runs from a cache dir
140
+ // that is NOT a persistent install — exactly the case that step exists for —
141
+ // so a cache/tmp path does not count as already installed.
142
+ function ensureGlobalBin(io) {
143
+ if (isSourceCheckout()) return;
144
+ const existing = io.which("qaping");
145
+ const persistent =
146
+ existing && !/[\\/](_npx|_cacache|npm-cache|Temp|tmp)[\\/]/i.test(existing);
147
+ if (persistent) return;
148
+ io.log(`Installing the qaping command (npm i -g ${NPM_PACKAGE})…`);
149
+ const r = io.run("npm", ["i", "-g", NPM_PACKAGE]);
150
+ if (!r || r.error || r.status !== 0) {
151
+ io.log(`⚠ could not install the qaping command — run it yourself: npm i -g ${NPM_PACKAGE}`);
152
+ io.log(" (setup continues; the MCP tools your agent calls do not need it, but `qaping publish-build` does)");
153
+ }
154
+ }
155
+
125
156
  async function cmdSetup(argv) {
126
157
  const kitDir = resolveKitDir();
127
158
  const { setup } = require(path.join(kitDir, "harness", "setup.js"));
@@ -129,7 +160,9 @@ async function cmdSetup(argv) {
129
160
  // accepts both the positional form (`setup cursor`) and `setup --client cursor`
130
161
  const args = argv.filter((a) => a !== "--force");
131
162
  const client = ((args[1] === "--client" ? args[2] : args[1]) || "").toLowerCase();
132
- const r = await setup(defaultIO(kitDir), {
163
+ const io = defaultIO(kitDir);
164
+ ensureGlobalBin(io);
165
+ const r = await setup(io, {
133
166
  home: os.homedir(),
134
167
  sourceCheckout: isSourceCheckout(),
135
168
  resolveToken,
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@qaping/cli",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
+ "homepage": "https://qaping.dev",
4
5
  "description": "qaping: automatic QA for your game. Your coding agent authors and maintains the QA plan, ships each patch's build to real human playtesters, and reports what broke.",
5
6
  "keywords": [
6
7
  "qaping",