@genrupt/cli 0.1.5 → 0.1.7

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/README.md CHANGED
@@ -6,20 +6,14 @@ Genrupt CLI for local-file workflows and local MCP clients.
6
6
 
7
7
  Use this when setting up Genrupt for an agent:
8
8
 
9
- Windows user-local launcher:
10
-
11
- ```powershell
12
- powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "irm https://genrupt.com/downloads/genrupt-cli/install.ps1 | iex"
13
- genrupt agent install
14
- ```
15
-
16
- Universal one-time run:
9
+ Install the CLI:
17
10
 
18
11
  ```bash
19
- npx -y @genrupt/cli@latest agent install
12
+ npm install -g @genrupt/cli@latest
13
+ genrupt agent install
20
14
  ```
21
15
 
22
- This checks auth, installs Genrupt skills for the detected agent, and writes a local runtime manifest. The user-local launcher avoids `npm install -g`; the `npx` runtime install still tries to install or update the global CLI, but global npm install failures do not block the skills/runtime setup.
16
+ This checks auth, installs Genrupt skills for the detected agent, and writes a local runtime manifest.
23
17
 
24
18
  ## Install
25
19
 
@@ -35,10 +29,10 @@ macOS/Linux:
35
29
  curl -fsSL https://genrupt.com/downloads/genrupt-cli/install.sh | sh
36
30
  ```
37
31
 
38
- Optional global npm install:
32
+ If global npm install is restricted, run without installing globally:
39
33
 
40
34
  ```bash
41
- npm install -g @genrupt/cli
35
+ npx -y @genrupt/cli@latest agent install
42
36
  ```
43
37
 
44
38
  ## Login
@@ -61,6 +55,15 @@ If Genrupt is unreachable and you only want to remove the local file, run:
61
55
  genrupt auth logout --local
62
56
  ```
63
57
 
58
+ If Claude Code or another local MCP client keeps reusing stale credentials after you remove and
59
+ re-add the connector, force a local credential reset:
60
+
61
+ ```bash
62
+ genrupt auth reset
63
+ genrupt auth login
64
+ genrupt setup claude-code --replace
65
+ ```
66
+
64
67
  ## Claude Code
65
68
 
66
69
  ```bash
@@ -85,6 +88,14 @@ genrupt doctor
85
88
 
86
89
  Checks CLI freshness, auth, remote MCP reachability, installed skills, and the local Genrupt runtime manifest.
87
90
 
91
+ If the remote MCP check fails, run:
92
+
93
+ ```bash
94
+ genrupt auth reset
95
+ genrupt auth login
96
+ genrupt doctor
97
+ ```
98
+
88
99
  ## Runtime Health
89
100
 
90
101
  The CLI sends small best-effort runtime health events for failed agent installs, stale CLI detection, doctor failures, and upload failures. Events are sanitized and do not include local paths, filenames, prompts, uploaded content, or tokens.
package/dist/auth.js CHANGED
@@ -126,12 +126,23 @@ export async function login(options = {}) {
126
126
  }
127
127
  export async function refreshAccessToken(config) {
128
128
  const endpoints = getAuthEndpoints(config.origin);
129
- const token = await postJson(endpoints.token, {
130
- grant_type: "refresh_token",
131
- client_id: config.clientId,
132
- refresh_token: config.refreshToken,
133
- resource: config.mcpServerUrl,
134
- });
129
+ let token;
130
+ try {
131
+ token = await postJson(endpoints.token, {
132
+ grant_type: "refresh_token",
133
+ client_id: config.clientId,
134
+ refresh_token: config.refreshToken,
135
+ resource: config.mcpServerUrl,
136
+ });
137
+ }
138
+ catch (error) {
139
+ if (error instanceof HttpError &&
140
+ ["invalid_grant", "invalid_client", "invalid_target"].includes(getErrorCode(error.payload) ?? "")) {
141
+ await clearConfig();
142
+ throw new Error(`Genrupt auth expired or was revoked. Cleared local credentials at ${getConfigPath()}. Run \`genrupt auth login\` to reconnect.`);
143
+ }
144
+ throw error;
145
+ }
135
146
  const nextConfig = {
136
147
  ...config,
137
148
  accessToken: token.access_token,
@@ -201,6 +212,11 @@ export async function logout(options = {}) {
201
212
  await clearConfig();
202
213
  console.log("Logged out.");
203
214
  }
215
+ export async function resetLocalAuth() {
216
+ await clearConfig();
217
+ console.log(`Cleared local Genrupt credentials at ${getConfigPath()}.`);
218
+ console.log("Run `genrupt auth login` to reconnect.");
219
+ }
204
220
  export async function assertLoggedIn() {
205
221
  await getValidAccessToken();
206
222
  }
package/dist/cli.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import { readFile } from "node:fs/promises";
3
3
  import { CLI_VERSION } from "./constants.js";
4
4
  import { installAgentRuntime } from "./agent.js";
5
- import { login, logout, printAuthStatus } from "./auth.js";
5
+ import { login, logout, printAuthStatus, resetLocalAuth } from "./auth.js";
6
6
  import { callRemoteMcpTool, assertSuccessfulToolPayload } from "./mcpClient.js";
7
7
  import { serveLocalMcp } from "./localMcpServer.js";
8
8
  import { setupClaudeCode } from "./setup.js";
@@ -76,6 +76,7 @@ Usage:
76
76
  genrupt auth login [--origin https://genrupt.com] [--no-open]
77
77
  genrupt auth status
78
78
  genrupt auth logout [--local]
79
+ genrupt auth reset
79
80
  genrupt version
80
81
 
81
82
  genrupt agent install [--agent claude|codex|cursor] [--target PATH] [--skip-auth] [--skip-global-install]
@@ -153,6 +154,10 @@ async function handleAuth(args) {
153
154
  });
154
155
  return;
155
156
  }
157
+ if (subcommand === "reset") {
158
+ await resetLocalAuth();
159
+ return;
160
+ }
156
161
  throw new Error("Unknown auth command. Run `genrupt --help`.");
157
162
  }
158
163
  async function handleSetup(args) {
@@ -360,5 +365,5 @@ main().catch(async (error) => {
360
365
  ? await buildUnknownCommandUpdateHint()
361
366
  : "";
362
367
  console.error(`${message}${updateHint}`);
363
- process.exit(1);
368
+ process.exitCode = 1;
364
369
  });
package/dist/constants.js CHANGED
@@ -3,5 +3,5 @@ export const DEFAULT_MCP_SERVER_URL = `${DEFAULT_ORIGIN}/api/agent/mcp`;
3
3
  export const OAUTH_DEVICE_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:device_code";
4
4
  export const OAUTH_SCOPE = "mcp";
5
5
  export const CLI_CLIENT_NAME = "Genrupt CLI";
6
- export const CLI_VERSION = "0.1.5";
6
+ export const CLI_VERSION = "0.1.7";
7
7
  export const ACCESS_TOKEN_REFRESH_SKEW_MS = 60_000;
package/dist/doctor.js CHANGED
@@ -234,7 +234,7 @@ export async function runDoctor(options = {}) {
234
234
  label: "Remote MCP",
235
235
  status: "fail",
236
236
  detail: message,
237
- remediation: "Run: genrupt auth login, then retry genrupt doctor",
237
+ remediation: "Run: genrupt auth reset, then genrupt auth login, then retry genrupt doctor",
238
238
  });
239
239
  }
240
240
  }
package/dist/globalCli.js CHANGED
@@ -180,10 +180,11 @@ export function buildGlobalCliDiagnosticsLines(diagnostics) {
180
180
  }
181
181
  export function buildNoGlobalInstallRemediation() {
182
182
  return [
183
- "Install the user-local launcher without npm global writes:",
184
- ` powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "irm https://genrupt.com/downloads/genrupt-cli/install.ps1 | iex"`,
183
+ `Update the global CLI:`,
184
+ ` npm install -g ${CLI_PACKAGE_NAME}@latest`,
185
185
  "Or keep using npx:",
186
186
  ` npx -y ${CLI_PACKAGE_NAME}@latest doctor`,
187
- "If you want the global npm command, check that npm's global prefix is writable or run the install from an elevated terminal.",
187
+ "If global npm install is restricted, install the user-local launcher:",
188
+ ` powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "irm https://genrupt.com/downloads/genrupt-cli/install.ps1 | iex"`,
188
189
  ];
189
190
  }
@@ -2,6 +2,7 @@ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
3
  import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
4
4
  import { CLI_VERSION } from "./constants.js";
5
+ import { getConfigPath, readConfig } from "./config.js";
5
6
  import { listRemoteMcpTools, callRemoteMcpTool } from "./mcpClient.js";
6
7
  import { uploadProductReferenceImages, uploadReferenceMedia, } from "./upload.js";
7
8
  import { classifyCliError, emitRuntimeTelemetry } from "./telemetry.js";
@@ -43,6 +44,16 @@ const LOCAL_UPLOAD_TOOL = {
43
44
  additionalProperties: false,
44
45
  },
45
46
  };
47
+ const LOCAL_AUTH_STATUS_TOOL = {
48
+ name: "get_genrupt_cli_auth_status",
49
+ title: "Get Genrupt CLI auth status",
50
+ description: "Use when Genrupt MCP tools are missing, failing to connect, or asking for auth repair. This local diagnostic tool checks whether this machine has cached Genrupt CLI credentials and returns the credential file path plus exact repair commands. It does not validate credentials with the server or expose tokens.",
51
+ inputSchema: {
52
+ type: "object",
53
+ properties: {},
54
+ additionalProperties: false,
55
+ },
56
+ };
46
57
  const LOCAL_REFERENCE_MEDIA_UPLOAD_TOOL = {
47
58
  name: "upload_reference_media",
48
59
  title: "Upload local reference media",
@@ -144,6 +155,26 @@ async function handleLocalReferenceMediaUploadTool(args) {
144
155
  });
145
156
  return buildToolResult(payload);
146
157
  }
158
+ async function handleLocalAuthStatusTool() {
159
+ const config = await readConfig();
160
+ return buildToolResult({
161
+ hasLocalCredentials: Boolean(config),
162
+ configPath: getConfigPath(),
163
+ origin: config?.origin ?? null,
164
+ mcpServerUrl: config?.mcpServerUrl ?? null,
165
+ accessTokenExpiresAt: config?.accessTokenExpiresAt ?? null,
166
+ scope: config?.scope ?? null,
167
+ nextActions: config
168
+ ? [
169
+ "Run `genrupt doctor` to validate the remote MCP connection.",
170
+ "If Claude Code still fails, run `genrupt auth reset`, then `genrupt auth login`, then restart Claude Code.",
171
+ ]
172
+ : [
173
+ "Run `genrupt auth login` to connect this machine.",
174
+ "Run `genrupt setup claude-code --replace` after login if Claude Code does not show Genrupt.",
175
+ ],
176
+ });
177
+ }
147
178
  export async function serveLocalMcp() {
148
179
  const server = new Server({
149
180
  name: "genrupt-cli",
@@ -159,6 +190,7 @@ export async function serveLocalMcp() {
159
190
  const remote = await listRemoteMcpTools();
160
191
  return {
161
192
  tools: [
193
+ LOCAL_AUTH_STATUS_TOOL,
162
194
  LOCAL_UPLOAD_TOOL,
163
195
  LOCAL_REFERENCE_MEDIA_UPLOAD_TOOL,
164
196
  ...remote.tools.filter((tool) => tool.name !== LOCAL_UPLOAD_TOOL.name &&
@@ -169,7 +201,7 @@ export async function serveLocalMcp() {
169
201
  catch (error) {
170
202
  console.error(`[genrupt] Failed to list remote MCP tools: ${error instanceof Error ? error.message : String(error)}`);
171
203
  return {
172
- tools: [LOCAL_UPLOAD_TOOL, LOCAL_REFERENCE_MEDIA_UPLOAD_TOOL],
204
+ tools: [LOCAL_AUTH_STATUS_TOOL],
173
205
  };
174
206
  }
175
207
  });
@@ -184,6 +216,9 @@ export async function serveLocalMcp() {
184
216
  if (request.params.name === LOCAL_REFERENCE_MEDIA_UPLOAD_TOOL.name) {
185
217
  return await handleLocalReferenceMediaUploadTool(args);
186
218
  }
219
+ if (request.params.name === LOCAL_AUTH_STATUS_TOOL.name) {
220
+ return await handleLocalAuthStatusTool();
221
+ }
187
222
  return await callRemoteMcpTool(request.params.name, args);
188
223
  }
189
224
  catch (error) {
package/dist/mcpClient.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { getValidAccessToken, getValidConfig, refreshAccessToken } from "./auth.js";
2
+ import { clearConfig, getConfigPath } from "./config.js";
2
3
  import { HttpError, getErrorDescription } from "./http.js";
3
4
  let nextJsonRpcId = 1;
4
5
  function parseEventStreamPayload(text) {
@@ -53,7 +54,16 @@ async function withAuthRetry(call) {
53
54
  throw error;
54
55
  }
55
56
  const refreshed = await refreshAccessToken(config);
56
- return call(refreshed.accessToken, refreshed.mcpServerUrl);
57
+ try {
58
+ return await call(refreshed.accessToken, refreshed.mcpServerUrl);
59
+ }
60
+ catch (retryError) {
61
+ if (retryError instanceof HttpError && retryError.status === 401) {
62
+ await clearConfig();
63
+ throw new Error(`Genrupt auth is no longer valid. Cleared local credentials at ${getConfigPath()}. Run \`genrupt auth login\` to reconnect.`);
64
+ }
65
+ throw retryError;
66
+ }
57
67
  }
58
68
  }
59
69
  export async function listRemoteMcpTools() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@genrupt/cli",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "Genrupt CLI for OAuth login, local file uploads, and local MCP bridge setup.",
5
5
  "license": "MIT",
6
6
  "repository": {