@salestouch/cli 0.1.0 → 0.1.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.
package/README.md CHANGED
@@ -5,70 +5,78 @@ Public CLI for SalesTouch commands, resources, agent setup, and MCP workflows.
5
5
  ## Install
6
6
 
7
7
  ```bash
8
- pnpm salestouch --help
8
+ npx @salestouch/cli --help
9
9
  ```
10
10
 
11
- The npm package is not published yet. Run the CLI from the repository root with `pnpm salestouch ...`.
11
+ Global install:
12
+
13
+ ```bash
14
+ npm install -g @salestouch/cli
15
+ salestouch --help
16
+ ```
17
+
18
+ If you only want a one-off execution, use `npx @salestouch/cli ...`.
19
+ The public setup guide is also available at `https://www.salestouch.io/setup.md`.
12
20
 
13
21
  ## Authenticate
14
22
 
15
23
  ```bash
16
- pnpm salestouch auth login
17
- pnpm salestouch auth whoami
18
- pnpm salestouch auth logout
24
+ salestouch auth login
25
+ salestouch auth whoami
26
+ salestouch auth logout
19
27
  ```
20
28
 
21
29
  API key authentication is also supported:
22
30
 
23
31
  ```bash
24
- pnpm salestouch auth use-key st_...
32
+ salestouch auth use-key st_...
25
33
  ```
26
34
 
27
35
  ## Commands
28
36
 
29
37
  ```bash
30
- pnpm salestouch doctor
31
- pnpm salestouch commands list
32
- pnpm salestouch commands schema mission.get
33
- pnpm salestouch commands run mission.get --input-json '{"mission_id":"mission_123"}'
34
- pnpm salestouch resources list
35
- pnpm salestouch resources read salestouch://status
36
- pnpm salestouch setup --codex
37
- pnpm salestouch mcp serve
38
+ salestouch doctor
39
+ salestouch commands list
40
+ salestouch commands schema mission.get
41
+ salestouch commands run mission.get --input-json '{"mission_id":"mission_123"}'
42
+ salestouch resources list
43
+ salestouch resources read salestouch://status
44
+ salestouch setup --codex
45
+ salestouch mcp serve
38
46
  ```
39
47
 
40
48
  The CLI can authenticate with either a stored SalesTouch login session or an API key. `salestouch setup` persists the selected auth method to the CLI config so local MCP clients can reuse it.
41
49
  By default, `salestouch setup` installs `CLI + skills`. Add `--mcp` when you want MCP instead.
42
- If you run `pnpm salestouch setup` with no setup flags in an interactive terminal, the CLI starts a small guided setup wizard.
50
+ If you run `salestouch setup` with no setup flags in an interactive terminal, the CLI starts a small guided setup wizard.
43
51
 
44
52
  ## Setup
45
53
 
46
54
  ```bash
47
55
  # Project-local CLI + skills setup for Codex
48
- pnpm salestouch setup --codex
56
+ salestouch setup --codex
49
57
 
50
58
  # Configure Claude and Cursor explicitly in CLI mode
51
- pnpm salestouch setup --claude --cursor --cli
59
+ salestouch setup --claude --cursor --cli
52
60
 
53
61
  # Opt into remote MCP explicitly
54
- pnpm salestouch setup --claude --mcp --login
62
+ salestouch setup --claude --mcp --login
55
63
 
56
64
  # Force login during setup
57
- pnpm salestouch setup --codex --login
65
+ salestouch setup --codex --login
58
66
 
59
67
  # Persist an API key during setup
60
- pnpm salestouch setup --codex --api-key st_...
68
+ salestouch setup --codex --api-key st_...
61
69
  ```
62
70
 
63
71
  ## MCP
64
72
 
65
73
  ```bash
66
74
  # Start the local stdio MCP server
67
- pnpm salestouch mcp serve
75
+ salestouch mcp serve
68
76
 
69
77
  # Override auth explicitly for the MCP process
70
- pnpm salestouch mcp serve --api-key st_...
71
- pnpm salestouch mcp serve --access-token <token>
78
+ salestouch mcp serve --api-key st_...
79
+ salestouch mcp serve --access-token <token>
72
80
  ```
73
81
 
74
82
  ## Environment
package/dist/core.d.ts CHANGED
@@ -20,7 +20,7 @@ export type ResolvedSessionAuth = ResolvedBaseUrl & {
20
20
  };
21
21
  export type ResolvedAuth = ResolvedApiKeyAuth | ResolvedSessionAuth;
22
22
  export type JsonRecord = Record<string, unknown>;
23
- export declare const CLI_VERSION = "0.3.0";
23
+ export declare const CLI_VERSION = "0.1.1";
24
24
  export declare const DEFAULT_BASE_URL = "https://www.salestouch.io";
25
25
  export declare const CLI_DEVICE_CLIENT_ID = "salestouch-cli";
26
26
  export declare function readFlagString(flags: Record<string, FlagValue>, name: string): string | null;
@@ -30,7 +30,10 @@ export declare function getConfigDirectory(): string;
30
30
  export declare function getConfigPath(): string;
31
31
  export declare function loadConfig(): Promise<CliConfig>;
32
32
  export declare function saveConfig(config: CliConfig): Promise<void>;
33
- export declare function resolveBaseUrl(overrideBaseUrl?: string | null): Promise<ResolvedBaseUrl>;
33
+ export declare function resolveBaseUrl(overrideBaseUrl?: string | null, options?: {
34
+ includeConfig?: boolean;
35
+ includeWorkspace?: boolean;
36
+ }): Promise<ResolvedBaseUrl>;
34
37
  export declare function getRemoteMcpUrl(baseUrl: string): string;
35
38
  export declare function resolveAuth(options?: {
36
39
  apiKey?: string | null;
package/dist/core.js CHANGED
@@ -5,11 +5,12 @@ import path from "node:path";
5
5
  import process from "node:process";
6
6
  import { setTimeout as sleep } from "node:timers/promises";
7
7
  import { parse as parseDotenv } from "dotenv";
8
- export const CLI_VERSION = "0.3.0";
8
+ export const CLI_VERSION = "0.1.1";
9
9
  export const DEFAULT_BASE_URL = "https://www.salestouch.io";
10
10
  export const CLI_DEVICE_CLIENT_ID = "salestouch-cli";
11
11
  const DEVICE_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:device_code";
12
12
  const WORKSPACE_BASE_URL_FILES = [".env.local", ".env"];
13
+ const WORKSPACE_BASE_URL_KEYS = ["SALESTOUCH_API_BASE_URL"];
13
14
  export function readFlagString(flags, name) {
14
15
  const value = flags[name];
15
16
  return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
@@ -74,7 +75,7 @@ async function readWorkspaceBaseUrlFromFile(filePath) {
74
75
  try {
75
76
  const raw = await readFile(filePath, "utf8");
76
77
  const parsed = parseDotenv(raw);
77
- for (const key of ["SALESTOUCH_API_BASE_URL", "NEXT_PUBLIC_APP_URL", "BETTER_AUTH_URL"]) {
78
+ for (const key of WORKSPACE_BASE_URL_KEYS) {
78
79
  const value = parsed[key]?.trim();
79
80
  if (value) {
80
81
  return value;
@@ -103,10 +104,10 @@ async function findWorkspaceBaseUrl(startDir) {
103
104
  currentDir = parentDir;
104
105
  }
105
106
  }
106
- export async function resolveBaseUrl(overrideBaseUrl) {
107
- const config = await loadConfig();
108
- const workspaceBaseUrl = await findWorkspaceBaseUrl(process.cwd());
109
- return resolveBaseUrlFromSources(overrideBaseUrl ?? null, readEnvString("SALESTOUCH_API_BASE_URL"), config.baseUrl?.trim() || null, workspaceBaseUrl);
107
+ export async function resolveBaseUrl(overrideBaseUrl, options) {
108
+ const config = options?.includeConfig === false ? null : await loadConfig();
109
+ const workspaceBaseUrl = options?.includeWorkspace === false ? null : await findWorkspaceBaseUrl(process.cwd());
110
+ return resolveBaseUrlFromSources(overrideBaseUrl ?? null, readEnvString("SALESTOUCH_API_BASE_URL"), config?.baseUrl?.trim() || null, workspaceBaseUrl);
110
111
  }
111
112
  export function getRemoteMcpUrl(baseUrl) {
112
113
  return `${baseUrl.replace(/\/$/, "")}/api/mcp`;
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import process from "node:process";
4
4
  import { readFile } from "node:fs/promises";
5
5
  import { log, note, outro, spinner } from "@clack/prompts";
6
6
  import pc from "picocolors";
7
- import { CLI_VERSION, apiRequest, clearStoredAuth, describeAuthMethod, getRemoteMcpUrl, getConfigPath, loadConfig, loginWithDeviceFlow, outputJson, persistAuth, printResourceStatus, printTable, readFlagBoolean, readFlagString, resolveAuth, } from "./core.js";
7
+ import { CLI_VERSION, apiRequest, clearStoredAuth, describeAuthMethod, getRemoteMcpUrl, getConfigPath, loadConfig, loginWithDeviceFlow, outputJson, persistAuth, printResourceStatus, printTable, readFlagBoolean, readFlagString, resolveAuth, resolveBaseUrl, } from "./core.js";
8
8
  import { detectCliLocale } from "./locale.js";
9
9
  import { startMcpServer } from "./mcp-server.js";
10
10
  import { applySetupWizardSelections, runInteractiveSetupWizard, shouldRunSetupWizard, } from "./setup-wizard.js";
@@ -272,18 +272,24 @@ async function ensureSetupAuth(parsed) {
272
272
  const baseUrl = readFlagString(parsed.flags, "base-url");
273
273
  const forceLogin = readFlagBoolean(parsed.flags, "login");
274
274
  if (apiKey) {
275
- const { auth, resource } = await readStatusResource({ apiKey, baseUrl });
275
+ const freshBaseUrl = await resolveBaseUrl(baseUrl, { includeConfig: false });
276
+ const { auth, resource } = await readStatusResource({ apiKey, baseUrl: freshBaseUrl.baseUrl });
276
277
  await persistAuth(auth);
277
278
  return { auth, resource };
278
279
  }
279
280
  if (accessToken) {
280
- const { auth, resource } = await readStatusResource({ accessToken, baseUrl });
281
+ const freshBaseUrl = await resolveBaseUrl(baseUrl, { includeConfig: false });
282
+ const { auth, resource } = await readStatusResource({
283
+ accessToken,
284
+ baseUrl: freshBaseUrl.baseUrl,
285
+ });
281
286
  await persistAuth(auth);
282
287
  return { auth, resource };
283
288
  }
284
289
  if (forceLogin) {
290
+ const freshBaseUrl = await resolveBaseUrl(baseUrl, { includeConfig: false });
285
291
  const login = await loginWithDeviceFlow({
286
- baseUrl,
292
+ baseUrl: freshBaseUrl.baseUrl,
287
293
  quiet: readFlagBoolean(parsed.flags, "json"),
288
294
  });
289
295
  const payload = await apiRequest(login.auth, `/api/v1/resources/read?uri=${encodeURIComponent("salestouch://status")}`);
@@ -313,7 +319,7 @@ async function ensureSetupAuth(parsed) {
313
319
  }
314
320
  }
315
321
  const login = await loginWithDeviceFlow({
316
- baseUrl,
322
+ baseUrl: (await resolveBaseUrl(baseUrl, { includeConfig: false })).baseUrl,
317
323
  quiet: readFlagBoolean(parsed.flags, "json"),
318
324
  });
319
325
  const payload = await apiRequest(login.auth, `/api/v1/resources/read?uri=${encodeURIComponent("salestouch://status")}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salestouch/cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Public SalesTouch CLI for commands, resources, and developer workflows.",
5
5
  "type": "module",
6
6
  "bin": {