@tokenoftrust/cli 1.2.0 → 1.2.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/package.json +1 -1
- package/src/auth.mjs +5 -1
- package/src/commands/whoami.mjs +6 -1
- package/src/mcp.mjs +20 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tokenoftrust/cli",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "Token of Trust developer CLI — check out a tenant store, run it locally with save→reload, and submit it for preview. Installs the `tot` command.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Token of Trust",
|
package/src/auth.mjs
CHANGED
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
defaultCredentialsPath, readCredentials, writeCredentials, isExpired,
|
|
28
28
|
} from "./token-store.mjs";
|
|
29
29
|
import { refreshAccessToken, credentialsFromToken } from "./oauth.mjs";
|
|
30
|
+
import { recordServerPolicy } from "./update-check.mjs";
|
|
30
31
|
|
|
31
32
|
/** Thrown when no provider can authenticate — carries actionable guidance. */
|
|
32
33
|
export class AuthUnavailableError extends Error {
|
|
@@ -60,11 +61,14 @@ export async function resolveSession(client, opts = {}) {
|
|
|
60
61
|
{ hint: "source apps/storefront/lib/resolve-tot-credentials.sh (from a storefront checkout), or unset --identity to use developer sign-in." },
|
|
61
62
|
);
|
|
62
63
|
}
|
|
63
|
-
await client.callTool("credential_validate", {
|
|
64
|
+
const validated = await client.callTool("credential_validate", {
|
|
64
65
|
totApiKey: env.TOT_API_KEY,
|
|
65
66
|
totSecretKey: env.TOT_SECRET_KEY,
|
|
66
67
|
appDomain: env.TOT_APP_DOMAIN,
|
|
67
68
|
});
|
|
69
|
+
// Update-awareness Layer 2: the MCP may attach a version-support policy to the
|
|
70
|
+
// authed response (wire contract: `cliPolicy`). Safe no-op when absent.
|
|
71
|
+
recordServerPolicy(validated?.cliPolicy, env);
|
|
68
72
|
return { identity: "operator", appDomain: env.TOT_APP_DOMAIN };
|
|
69
73
|
}
|
|
70
74
|
|
package/src/commands/whoami.mjs
CHANGED
|
@@ -13,6 +13,7 @@ import { defaultCredentialsPath, readCredentials, isExpired } from "../token-sto
|
|
|
13
13
|
import { hasOperatorCreds, resolveDeveloperSession } from "../auth.mjs";
|
|
14
14
|
import { createMcpClient } from "../mcp.mjs";
|
|
15
15
|
import { normalizeStores } from "./checkout.mjs";
|
|
16
|
+
import { recordServerPolicy } from "../update-check.mjs";
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
19
|
* Pure summary of the cached session — no network. Returned for both display and
|
|
@@ -56,7 +57,11 @@ export async function run(argv, _ctx) {
|
|
|
56
57
|
const client = createMcpClient(status.mcpUrl || env.MCP_BASE_URL || env.TOT_MCP_URL || "https://mcp.tokenoftrust.com");
|
|
57
58
|
await client.initialize();
|
|
58
59
|
await resolveDeveloperSession(client, env);
|
|
59
|
-
const
|
|
60
|
+
const listResp = await client.callTool("client_list", {});
|
|
61
|
+
// Update-awareness Layer 2: an authed response may carry a version-support
|
|
62
|
+
// policy (wire contract: `cliPolicy`). Safe no-op when absent.
|
|
63
|
+
recordServerPolicy(listResp?.cliPolicy, env);
|
|
64
|
+
const stores = normalizeStores(listResp);
|
|
60
65
|
if (stores.length) {
|
|
61
66
|
console.log(` stores you can build on: ${stores.map((s) => s.id).join(", ")}`);
|
|
62
67
|
} else {
|
package/src/mcp.mjs
CHANGED
|
@@ -7,10 +7,26 @@
|
|
|
7
7
|
* answer as JSON or as an SSE stream, with the session id carried in the
|
|
8
8
|
* `Mcp-Session-Id` header across calls. Dependency-free (global fetch, Node 20+).
|
|
9
9
|
*/
|
|
10
|
+
import { readFileSync } from "node:fs";
|
|
11
|
+
|
|
12
|
+
// The CLI's REAL version for the MCP handshake — the transmission channel the
|
|
13
|
+
// server-side support policy (update-awareness Layer 2) decides against. Read from
|
|
14
|
+
// our own package.json (same pattern as bin/tot.mjs); best-effort, never throws.
|
|
15
|
+
export const CLI_VERSION = (() => {
|
|
16
|
+
try {
|
|
17
|
+
return (
|
|
18
|
+
JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")).version ||
|
|
19
|
+
"0.0.0"
|
|
20
|
+
);
|
|
21
|
+
} catch {
|
|
22
|
+
return "0.0.0";
|
|
23
|
+
}
|
|
24
|
+
})();
|
|
10
25
|
|
|
11
26
|
/**
|
|
12
27
|
* @param {string} baseUrl - MCP base URL; `/mcp` is appended if absent.
|
|
13
|
-
* @param {{ token?: string }} [opts] - optional developer OAuth
|
|
28
|
+
* @param {{ token?: string, clientVersion?: string }} [opts] - optional developer OAuth
|
|
29
|
+
* bearer to attach; `clientVersion` overrides the handshake version (tests).
|
|
14
30
|
* @returns a small client: { mcpUrl, initialize, callRaw, callTool, sessionId(), setToken }
|
|
15
31
|
*/
|
|
16
32
|
export function createMcpClient(baseUrl, opts = {}) {
|
|
@@ -86,7 +102,9 @@ export function createMcpClient(baseUrl, opts = {}) {
|
|
|
86
102
|
}
|
|
87
103
|
|
|
88
104
|
/** Complete the MCP handshake. Call once before any tool call. */
|
|
89
|
-
async function initialize(
|
|
105
|
+
async function initialize(
|
|
106
|
+
clientInfo = { name: "tot-cli", version: opts.clientVersion || CLI_VERSION },
|
|
107
|
+
) {
|
|
90
108
|
await callRaw("initialize", {
|
|
91
109
|
protocolVersion: "2025-06-18",
|
|
92
110
|
capabilities: {},
|