@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 +31 -23
- package/dist/core.d.ts +5 -2
- package/dist/core.js +7 -6
- package/dist/index.js +11 -5
- package/package.json +1 -1
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
|
-
|
|
8
|
+
npx @salestouch/cli --help
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
|
|
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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
-
|
|
32
|
+
salestouch auth use-key st_...
|
|
25
33
|
```
|
|
26
34
|
|
|
27
35
|
## Commands
|
|
28
36
|
|
|
29
37
|
```bash
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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 `
|
|
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
|
-
|
|
56
|
+
salestouch setup --codex
|
|
49
57
|
|
|
50
58
|
# Configure Claude and Cursor explicitly in CLI mode
|
|
51
|
-
|
|
59
|
+
salestouch setup --claude --cursor --cli
|
|
52
60
|
|
|
53
61
|
# Opt into remote MCP explicitly
|
|
54
|
-
|
|
62
|
+
salestouch setup --claude --mcp --login
|
|
55
63
|
|
|
56
64
|
# Force login during setup
|
|
57
|
-
|
|
65
|
+
salestouch setup --codex --login
|
|
58
66
|
|
|
59
67
|
# Persist an API key during setup
|
|
60
|
-
|
|
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
|
-
|
|
75
|
+
salestouch mcp serve
|
|
68
76
|
|
|
69
77
|
# Override auth explicitly for the MCP process
|
|
70
|
-
|
|
71
|
-
|
|
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.
|
|
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
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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")}`);
|