@retasc/cli 1.28.0 → 1.29.0

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
@@ -6,6 +6,17 @@ release commits and the issues they reference.
6
6
 
7
7
  Dates are the npm publish date. Each entry names the RTSC issue behind it.
8
8
 
9
+ ## 1.29.0 (2026-08-19)
10
+
11
+ - **RTSC-672** — every command we hand out now says `npx @retasc/cli@latest`. npx caches
12
+ by spec, so a bare `npx @retasc/cli` can keep serving whatever version you first ran —
13
+ which meant the people most likely to re-run a command, the ones who hit a bug and were
14
+ told it was fixed, were exactly the ones liable to be served the broken build again.
15
+ `@latest` is a tag, not a pin: it re-resolves every time and can never go stale, where a
16
+ version number written into docs absolutely can.
17
+ - **RTSC-672** — a first-run failure names the build that produced it, so "it still
18
+ doesn't work" and "you're running last week's CLI" stop looking identical.
19
+
9
20
  ## 1.28.0 (2026-08-19)
10
21
 
11
22
  - **RTSC-676** — signing in opens your browser. It used to print a URL and an
@@ -5,7 +5,7 @@ import { loadConfig, patchConfig } from "../config.js";
5
5
  import { installMarker, printMarkerBlock } from "./mcp.js";
6
6
  import { readLocalBinding, resolveBinding } from "../lib/binding.js";
7
7
  import { getBinding, setBinding, newWorkspaceId } from "../lib/keystore.js";
8
- import { resolveLauncher, launcherNote, runsOk, selfCommand } from "../lib/launcher.js";
8
+ import { resolveLauncher, launcherNote, runsOk, selfCommand, versionStamp } from "../lib/launcher.js";
9
9
  import { ask, confirm, isInteractive } from "../lib/prompt.js";
10
10
  import { clean } from "../lib/text.js";
11
11
  import { card, DOT } from "../lib/card.js";
@@ -563,7 +563,11 @@ export async function ensureSignedIn() {
563
563
  if (loadConfig().token)
564
564
  return;
565
565
  if (!isInteractive()) {
566
- throw new Error(`Not signed in. Run \`${selfCommand(VERSION)} login\` first (no TTY here for the device flow).`);
566
+ // RTSC-672 the stamp rides in the HINT, not the message. `formatError` keeps only
567
+ // the first line of a message (deliberately, to strip stack noise), so a second line
568
+ // here would be silently dropped — which is how a diagnostic aimed at silent failures
569
+ // would itself fail silently.
570
+ cliError("UNAUTHENTICATED", `Not signed in. Run \`${selfCommand(VERSION)} login\` first (no TTY here for the device flow).`, versionStamp(VERSION).trim());
567
571
  }
568
572
  // RTSC-508: don't name a provider here. `deviceLogin` asks which door, and
569
573
  // announcing "GitHub" before the question would be wrong for the invited
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { Command } from "commander";
3
3
  import { VERSION } from "./version.js";
4
- import { selfCommand } from "./lib/launcher.js";
4
+ import { selfCommand, versionStamp } from "./lib/launcher.js";
5
5
  import { loadConfig, patchConfig, saveConfig, configPath, isLoggedIn } from "./config.js";
6
6
  import { installMcp, normalizeScope } from "./commands/mcp.js";
7
7
  import { installGate, resolveGatePrefix } from "./commands/gate.js";
@@ -27,9 +27,13 @@ program
27
27
  function requireLogin() {
28
28
  if (!isLoggedIn()) {
29
29
  // RTSC-671 — `selfCommand` renders the form they actually used. The docs send a
30
- // new owner through `npx @retasc/cli`, which never puts `retasc` on PATH, so naming
30
+ // new owner through `npx @retasc/cli@latest`, which never puts `retasc` on PATH, so naming
31
31
  // it here answers a failure with a second `command not found`.
32
32
  console.error(`Not signed in. Run \`${selfCommand(VERSION)} login\` first.`);
33
+ // RTSC-672 — say which build spoke. A stale CLI and a broken one produce the same
34
+ // sentence otherwise, and the people most likely to re-run this are the ones who
35
+ // were just told a fix shipped.
36
+ console.error(versionStamp(VERSION));
33
37
  process.exit(1);
34
38
  }
35
39
  }
@@ -403,7 +407,7 @@ members
403
407
  // them in, binds the folder and wires their agent, so this must not tell them to run
404
408
  // `retasc login` first — nor name a `retasc` binary they don't have yet.
405
409
  console.log(` Share it. In the folder their agent works in, they run:`);
406
- console.log(` npx @retasc/cli join ${res.code}`);
410
+ console.log(` npx @retasc/cli@latest join ${res.code}`);
407
411
  }
408
412
  catch (e) {
409
413
  fail(e);
@@ -96,6 +96,25 @@ export function portableLauncher(r, version) {
96
96
  export function selfCommand(version, argv1 = process.argv[1] ?? "") {
97
97
  return /[\\/]_npx[\\/]/.test(argv1) ? `npx -y ${PKG}@${version}` : "retasc";
98
98
  }
99
+ /**
100
+ * A one-line stamp of which build just spoke (RTSC-672).
101
+ *
102
+ * A failure report is only diagnosable if it says what produced it. After 1.26.0 fixed
103
+ * sign-in, a container kept printing the 1.25.0 message and the only way to learn why was
104
+ * a round trip asking someone to run `--version` — because nothing in the output said.
105
+ * Worse, the population most likely to re-run a command is the population that hit a bug
106
+ * and was told it is fixed, which is exactly the population liable to be holding a stale
107
+ * build. "It still doesn't work" and "you are running last week's CLI" look identical
108
+ * without this.
109
+ *
110
+ * The EXACT version, not `@latest`: this names the code that emitted the message, which
111
+ * is a different question from how to fetch the current one. `npx` in the prefix when
112
+ * that is how they started, so the line doubles as a runnable command.
113
+ */
114
+ export function versionStamp(version, argv1 = process.argv[1] ?? "") {
115
+ const how = /[\\/]_npx[\\/]/.test(argv1) ? `npx ${PKG}@${version}` : `${PKG} ${version}`;
116
+ return ` (${how})`;
117
+ }
99
118
  /** Install (or upgrade to) an exact version globally. Returns null on success. */
100
119
  function installGlobal(version) {
101
120
  // A cold global install takes seconds with no output of its own. Silence here reads as
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@retasc/cli",
3
- "version": "1.28.0",
3
+ "version": "1.29.0",
4
4
  "description": "Retasc CLI \u2014 the issue tracker AI agents pull work from. Sign in with GitHub or Google, create projects, mint agent API keys, and wire your agent to the Retasc MCP server in one command.",
5
5
  "type": "module",
6
6
  "bin": {