@patchgg/cli 0.3.0 → 0.3.1

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/dist/cli.js +44 -17
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -187,7 +187,7 @@ var VERSION;
187
187
  var init_version = __esm({
188
188
  "src/version.ts"() {
189
189
  "use strict";
190
- VERSION = true ? "0.3.0" : JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")).version;
190
+ VERSION = true ? "0.3.1" : JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")).version;
191
191
  }
192
192
  });
193
193
 
@@ -229,7 +229,7 @@ ${BLOCK_WORDS} Its credit goes in your recipe's \`credits\`. If nothing fits, ma
229
229
  ## 2. Start
230
230
 
231
231
  \`\`\`sh
232
- ${pch} login
232
+ ${pch} login # agents: run it yourself, in the background, and pass on its link
233
233
  ${pch} agent install # gives your coding agent Patch's tools
234
234
  ${pch} new <you>/<game> --licence MIT # a repo with a patch.json, open unless you add --visibility private
235
235
  ${pch} init # or this, in a folder you already have
@@ -253,7 +253,7 @@ That's the whole flow: it uploads, tests a browser game, a mod Patch installs or
253
253
  ${pch} publish <you>/<game>@<version> --review pass --summary "<what you saw>" --moment "1 00:04 <what you saw>" --moment "1 00:30 <what you saw>"
254
254
  \`\`\`
255
255
 
256
- That sends it to Patch's review and follows it until it's live. Running \`${pch} publish\` is your yes, so run it once the person wants it out (\`${pch} test start\` tries a build without publishing it). A passed test shows it starts and runs, not that it plays well, so play it yourself before its first public release.
256
+ That sends it to Patch's review and follows it until it's live. Run it yourself, wherever you run: in WSL, on Linux or a Mac, or on a server, the person's Patch Desktop takes the test through Patch, and pch says if they need to open it or press Start. Running \`${pch} publish\` is your yes, so run it once the person wants it out (\`${pch} test start\` tries a build without publishing it). A passed test shows it starts and runs, not that it plays well, so play it yourself before its first public release.
257
257
 
258
258
  ## 4. Its listing
259
259
 
@@ -35771,6 +35771,13 @@ if ((!process.stdout.isTTY || process.env.TERM === "dumb") && !process.env.FORCE
35771
35771
  process.env.NO_COLOR = "1";
35772
35772
  }
35773
35773
 
35774
+ // src/closed-pipes.ts
35775
+ for (const stream of [process.stdout, process.stderr]) {
35776
+ stream.on("error", (error62) => {
35777
+ if (error62.code !== "EPIPE") throw error62;
35778
+ });
35779
+ }
35780
+
35774
35781
  // node_modules/.pnpm/commander@15.0.0/node_modules/commander/lib/error.js
35775
35782
  var CommanderError = class extends Error {
35776
35783
  /**
@@ -40331,7 +40338,8 @@ async function login(ctx, options) {
40331
40338
  scopes: key.scopes,
40332
40339
  git,
40333
40340
  git_identity: gitIdentity,
40334
- look_first: LOOK_FIRST
40341
+ look_first: LOOK_FIRST,
40342
+ next: `${pchOn(target.env)} agent install`
40335
40343
  },
40336
40344
  () => {
40337
40345
  if (people) {
@@ -40353,9 +40361,7 @@ async function login(ctx, options) {
40353
40361
  if (git.helper) out.line(`Git is signed in too: Patch repos at ${git.url} just work.`);
40354
40362
  if (gitIdentity) out.line(gitIdentity);
40355
40363
  out.line(LOOK_FIRST);
40356
- out.line(
40357
- "pch agent install gives your coding agent Patch's tools, and pch guide says how to publish."
40358
- );
40364
+ out.line(agentNext(pchOn(target.env)));
40359
40365
  }
40360
40366
  );
40361
40367
  }
@@ -40393,6 +40399,7 @@ async function loginWithKey(ctx) {
40393
40399
  }
40394
40400
  );
40395
40401
  }
40402
+ var agentNext = (pch) => `Next: run ${pch} agent install now, which gives you Patch's MCP tools, one-step publish among them, then ask the person to restart you to load them. ${pch} guide says how to make and publish a game.`;
40396
40403
  var SHORT_IDENTITY = "Git doesn't know who you are on this PC yet: pch new and pch clone set that up for each repo.";
40397
40404
  function signedIn(ctx, headline, { git, notes }) {
40398
40405
  const { out, target } = ctx;
@@ -40457,14 +40464,14 @@ ${drawn.map((line) => ` ${line}`).join("\n")}
40457
40464
  block.write(` Opening ${page} in your browser: check the code matches, then approve.`);
40458
40465
  block.write(import_picocolors3.default.dim(` Didn't open? Go to ${device.verification_uri} and enter the code.`));
40459
40466
  } else {
40460
- block.write(` Go to ${import_picocolors3.default.bold(device.verification_uri)} and enter the code.`);
40467
+ block.write(` Go to ${import_picocolors3.default.bold(device.verification_uri_complete)} and approve the code.`);
40461
40468
  }
40462
40469
  block.write();
40463
40470
  } else {
40464
40471
  process.stderr.write(
40465
40472
  `This waits for a person to approve it in a browser, which can take a few minutes. The code only works while this keeps running, so don't put a short timeout on it.
40466
40473
 
40467
- To sign in, open ${import_picocolors3.default.bold(device.verification_uri)} and enter ${import_picocolors3.default.bold(code)}
40474
+ To sign in, the person opens this link, which has the code in it, checks the code is ${import_picocolors3.default.bold(code)} and approves it: ${import_picocolors3.default.bold(device.verification_uri_complete)}
40468
40475
 
40469
40476
  `
40470
40477
  );
@@ -41694,7 +41701,12 @@ var recipeSchema = external_exports.object({
41694
41701
  ).max(4).default([]).describe("Config files and the values to set in them."),
41695
41702
  test: external_exports.object({
41696
41703
  args: external_exports.array(shortLine(400)).max(16).optional(),
41697
- checks: external_exports.array(external_exports.string().regex(checkName, "must be lowercase letters, digits and dashes")).max(12).optional().describe(
41704
+ checks: external_exports.array(
41705
+ external_exports.string().regex(
41706
+ checkName,
41707
+ "must be lowercase letters, digits and dashes, such as player-moves"
41708
+ )
41709
+ ).max(12).optional().describe(
41698
41710
  `Checks the release reports itself while it's tested: a browser game opened with ?patch-test=1 logs "pass <name>" or "fail <name>: why".`
41699
41711
  ),
41700
41712
  minutes: external_exports.number().int().min(1).max(15).optional(),
@@ -43049,13 +43061,15 @@ function mcpServer({ target }, options = {}, found = {}) {
43049
43061
  ];
43050
43062
  const name = target.env === "production" ? "patch" : `patch-${target.env}`;
43051
43063
  const platform = found.platform ?? process.platform;
43052
- if (found.hasPch ?? onPath("pch")) {
43053
- return platform === "win32" ? { name, command: "cmd", args: ["/c", "pch", ...flags] } : { name, command: "pch", args: flags };
43064
+ if (found.executable ?? isExecutable) return { name, command: process.execPath, args: flags };
43065
+ const pch = found.pchPath === void 0 ? whereOnPath("pch") : found.pchPath;
43066
+ if (pch) {
43067
+ return platform === "win32" ? { name, command: "cmd", args: ["/c", "pch", ...flags] } : { name, command: pch, args: flags };
43054
43068
  }
43055
43069
  return {
43056
43070
  name,
43057
43071
  command: process.execPath,
43058
- args: isExecutable ? flags : [...process.execArgv, resolve5(process.argv[1]), ...flags]
43072
+ args: [...process.execArgv, resolve5(process.argv[1]), ...flags]
43059
43073
  };
43060
43074
  }
43061
43075
  function commandLine(server) {
@@ -43084,8 +43098,18 @@ function codexHas(server) {
43084
43098
  return { status: listed.stdout?.includes(server.name) ? 0 : 1 };
43085
43099
  }
43086
43100
  function onPath(bin) {
43101
+ return whereOnPath(bin) !== null;
43102
+ }
43103
+ function whereOnPath(bin) {
43087
43104
  const names = process.platform === "win32" ? [`${bin}.cmd`, `${bin}.exe`, `${bin}.bat`, bin] : [bin];
43088
- return (process.env.PATH ?? "").split(delimiter).some((folder) => folder && names.some((name) => existsSync2(join6(folder, name))));
43105
+ for (const folder of (process.env.PATH ?? "").split(delimiter)) {
43106
+ if (!folder) continue;
43107
+ for (const name of names) {
43108
+ const path2 = resolve5(folder, name);
43109
+ if (existsSync2(path2)) return path2;
43110
+ }
43111
+ }
43112
+ return null;
43089
43113
  }
43090
43114
  function run(bin, args2) {
43091
43115
  const shell = process.platform === "win32";
@@ -48736,6 +48760,7 @@ async function followRelease(ctx, ref, options = {}) {
48736
48760
  ...review ? { review } : {},
48737
48761
  ...options.testAgain ? { test_again: true } : {}
48738
48762
  };
48763
+ const people = forAPerson(out.json, runningIn());
48739
48764
  let said2 = "";
48740
48765
  let asked = "";
48741
48766
  let step;
@@ -48754,7 +48779,9 @@ async function followRelease(ctx, ref, options = {}) {
48754
48779
  said2 = line;
48755
48780
  if (step.needs_person && step.needs_person.ask !== asked) {
48756
48781
  asked = step.needs_person.ask;
48757
- out.step(step.needs_person.ask);
48782
+ out.step(
48783
+ people ? step.needs_person.ask : `${step.needs_person.why} Ask the person: "${step.needs_person.ask}" This carries on by itself once they have, so keep it running, or run it again.`
48784
+ );
48758
48785
  }
48759
48786
  if (stops || Date.now() >= deadline) break;
48760
48787
  if (step.needs_person) await sleep10(PERSON_EVERY_MS);
@@ -49652,7 +49679,7 @@ function topLevel(command) {
49652
49679
  }
49653
49680
  var collect = (value, previous = []) => [...previous, value];
49654
49681
  program2.command("login").description(
49655
- "Sign in through the browser (device code), and sign git in with it. It waits for a person, which can take a few minutes, so don't run it under a short timeout"
49682
+ "Sign in through the browser (device code), and sign git in with it. It waits for a person, which can take a few minutes, so don't run it under a short timeout. Agents: run it yourself, in the background, and give the person the link it prints, which has the code in it"
49656
49683
  ).option("--scope <scope>", "API key scope: read, publish, admin (repeatable)", collect).option("--no-browser", "print the link instead of opening a browser").action(action((ctx, options) => login(ctx, options)));
49657
49684
  program2.command("logout").description("Revoke and forget the active login, and sign git out").action(action((ctx) => logout(ctx)));
49658
49685
  program2.command("whoami").description("Who you're signed in as, and where").action(action((ctx) => whoami(ctx)));
@@ -49864,7 +49891,7 @@ program2.command("check [dir]").description(
49864
49891
  )
49865
49892
  );
49866
49893
  program2.command("publish [target]").description(
49867
- "Publish from upload to live: uploads what Patch doesn't have, tests it on your PC, saves the footage for your review, then follows Patch's review until it's live. Running it is your yes. Give owner/slug@version instead of a folder to carry a release on, with --review once you've looked at its footage"
49894
+ "Publish from upload to live: uploads what Patch doesn't have, tests it on your PC, saves the footage for your review, then follows Patch's review until it's live. Running it is your yes. Give owner/slug@version instead of a folder to carry a release on, with --review once you've looked at its footage. Agents: run it yourself, wherever you run (WSL, Linux, a Mac or a server). The person's Patch Desktop takes the test through Patch, and pch says if they need to open it or press Start"
49868
49895
  ).addOption(
49869
49896
  new Option("--channel <channel>", `overrides patch.json. ${NOT_LOCKED_HELP}`).choices([
49870
49897
  "private",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patchgg/cli",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "pch: the Patch command-line tool for creators and their agents",
5
5
  "license": "MIT",
6
6
  "homepage": "https://patch.gg",