@rosthq/cli 0.5.10 → 0.5.12
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/dist/auth.d.ts +2 -0
- package/dist/auth.d.ts.map +1 -1
- package/dist/device-auth.d.ts.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +129 -17
- package/dist/index.js.map +2 -2
- package/dist/operations.d.ts +5 -1
- package/dist/operations.d.ts.map +1 -1
- package/dist/token-store.d.ts +1 -0
- package/dist/token-store.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/auth.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { CliConfig } from "./config.js";
|
|
2
2
|
import type { CliSession } from "./token-store.js";
|
|
3
3
|
export declare function loginWithBrowser(config: CliConfig): Promise<CliSession>;
|
|
4
|
+
export declare function shouldRefreshSession(session: CliSession, now?: number): boolean;
|
|
5
|
+
export declare function refreshCliSessionIfNeeded(config: CliConfig, session: CliSession, now?: number): Promise<CliSession>;
|
|
4
6
|
/**
|
|
5
7
|
* Best-effort attempt to open a URL in the default browser. Returns true when a
|
|
6
8
|
* launcher was invoked, false when no launcher is available for the platform.
|
package/dist/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAUnD,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CA2C7E;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,SAAa,GAAG,OAAO,CAKnF;AAED,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,UAAU,EACnB,GAAG,SAAa,GACf,OAAO,CAAC,UAAU,CAAC,CA4BrB;AASD;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAqBlE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"device-auth.d.ts","sourceRoot":"","sources":["../src/device-auth.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAQnD,KAAK,KAAK,GAAG;IACX,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC1C,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;CAC3C,CAAC;AAGF,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAGhD,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IACnG,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB,CAAC;AAwBF,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,OAAO,EAAE,MAAM;CAI5B;
|
|
1
|
+
{"version":3,"file":"device-auth.d.ts","sourceRoot":"","sources":["../src/device-auth.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAQnD,KAAK,KAAK,GAAG;IACX,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC1C,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;CAC3C,CAAC;AAGF,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAGhD,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IACnG,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB,CAAC;AAwBF,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,OAAO,EAAE,MAAM;CAI5B;AAiCD,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,SAAS,EACjB,EAAE,EAAE,KAAK,EACT,IAAI,GAAE,eAAoB,GACzB,OAAO,CAAC,UAAU,CAAC,CAuFrB"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { loginWithBrowser } from "./auth.js";
|
|
2
|
+
import { loginWithBrowser, refreshCliSessionIfNeeded } from "./auth.js";
|
|
3
3
|
import { loginWithDeviceCode } from "./device-auth.js";
|
|
4
4
|
import { type TokenStore } from "./token-store.js";
|
|
5
5
|
type CliIo = {
|
|
@@ -12,6 +12,7 @@ type MainOptions = {
|
|
|
12
12
|
io?: CliIo;
|
|
13
13
|
login?: typeof loginWithBrowser;
|
|
14
14
|
deviceLogin?: typeof loginWithDeviceCode;
|
|
15
|
+
refreshSession?: typeof refreshCliSessionIfNeeded;
|
|
15
16
|
};
|
|
16
17
|
export declare function main(argv?: string[], options?: MainOptions): Promise<number>;
|
|
17
18
|
export declare function isCliEntrypoint(moduleUrl: string, argvPath: string | undefined): boolean;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAMA,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAMA,OAAO,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,MAAM,WAAW,CAAC;AACxE,OAAO,EAAoB,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACzE,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAYrE,KAAK,KAAK,GAAG;IACX,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC1C,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAK1C,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,EAAE,CAAC,EAAE,KAAK,CAAC;IACX,KAAK,CAAC,EAAE,OAAO,gBAAgB,CAAC;IAChC,WAAW,CAAC,EAAE,OAAO,mBAAmB,CAAC;IACzC,cAAc,CAAC,EAAE,OAAO,yBAAyB,CAAC;CACnD,CAAC;AAEF,wBAAsB,IAAI,CAAC,IAAI,WAAwB,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CA+LnG;AAwXD,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAUxF"}
|
package/dist/index.js
CHANGED
|
@@ -36984,6 +36984,7 @@ var run = promisify(execFile);
|
|
|
36984
36984
|
var oauthCallbackSchema = external_exports.object({
|
|
36985
36985
|
code: external_exports.string().min(1)
|
|
36986
36986
|
}).strict();
|
|
36987
|
+
var REFRESH_SKEW_MS = 5 * 60 * 1e3;
|
|
36987
36988
|
async function loginWithBrowser(config2) {
|
|
36988
36989
|
const callback = await waitForOAuthCallback();
|
|
36989
36990
|
const supabase = createClient(config2.supabaseUrl, config2.supabaseAnonKey, {
|
|
@@ -37021,9 +37022,43 @@ async function loginWithBrowser(config2) {
|
|
|
37021
37022
|
}
|
|
37022
37023
|
return {
|
|
37023
37024
|
accessToken,
|
|
37025
|
+
...sessionData.session.refresh_token ? { refreshToken: sessionData.session.refresh_token } : {},
|
|
37024
37026
|
...sessionData.session.expires_at ? { expiresAt: new Date(sessionData.session.expires_at * 1e3).toISOString() } : {}
|
|
37025
37027
|
};
|
|
37026
37028
|
}
|
|
37029
|
+
function shouldRefreshSession(session, now = Date.now()) {
|
|
37030
|
+
if (!session.refreshToken || !session.expiresAt) {
|
|
37031
|
+
return false;
|
|
37032
|
+
}
|
|
37033
|
+
return new Date(session.expiresAt).getTime() <= now + REFRESH_SKEW_MS;
|
|
37034
|
+
}
|
|
37035
|
+
async function refreshCliSessionIfNeeded(config2, session, now = Date.now()) {
|
|
37036
|
+
const refreshToken = session.refreshToken;
|
|
37037
|
+
if (!refreshToken || !shouldRefreshSession(session, now)) {
|
|
37038
|
+
return session;
|
|
37039
|
+
}
|
|
37040
|
+
const supabase = createClient(config2.supabaseUrl, config2.supabaseAnonKey, {
|
|
37041
|
+
auth: {
|
|
37042
|
+
autoRefreshToken: false,
|
|
37043
|
+
detectSessionInUrl: false,
|
|
37044
|
+
persistSession: false
|
|
37045
|
+
}
|
|
37046
|
+
});
|
|
37047
|
+
const { data, error: error51 } = await supabase.auth.refreshSession({ refresh_token: refreshToken });
|
|
37048
|
+
if (error51) {
|
|
37049
|
+
throw error51;
|
|
37050
|
+
}
|
|
37051
|
+
const refreshed = data.session;
|
|
37052
|
+
const accessToken = refreshed?.access_token;
|
|
37053
|
+
if (!accessToken) {
|
|
37054
|
+
throw new Error("Supabase did not return a refreshed access token.");
|
|
37055
|
+
}
|
|
37056
|
+
return {
|
|
37057
|
+
accessToken,
|
|
37058
|
+
refreshToken: refreshed.refresh_token ?? refreshToken,
|
|
37059
|
+
...refreshed.expires_at ? { expiresAt: new Date(refreshed.expires_at * 1e3).toISOString() } : {}
|
|
37060
|
+
};
|
|
37061
|
+
}
|
|
37027
37062
|
async function openBrowser(url2) {
|
|
37028
37063
|
const opened = await tryOpenBrowser(url2);
|
|
37029
37064
|
if (!opened) {
|
|
@@ -37131,6 +37166,7 @@ async function defaultVerifyOtp(config2, input) {
|
|
|
37131
37166
|
}
|
|
37132
37167
|
return {
|
|
37133
37168
|
accessToken,
|
|
37169
|
+
...data.session?.refresh_token ? { refreshToken: data.session.refresh_token } : {},
|
|
37134
37170
|
...data.session?.expires_at ? { expiresAt: new Date(data.session.expires_at * 1e3).toISOString() } : {}
|
|
37135
37171
|
};
|
|
37136
37172
|
}
|
|
@@ -37241,6 +37277,7 @@ import { promisify as promisify2 } from "node:util";
|
|
|
37241
37277
|
var execFile2 = promisify2(execFileCallback);
|
|
37242
37278
|
var sessionSchema = external_exports.object({
|
|
37243
37279
|
accessToken: external_exports.string().min(1),
|
|
37280
|
+
refreshToken: external_exports.string().min(1).optional(),
|
|
37244
37281
|
expiresAt: external_exports.string().datetime({ offset: true }).optional()
|
|
37245
37282
|
}).strict();
|
|
37246
37283
|
var serviceName = `${cliBrand.binName}-cli`;
|
|
@@ -37332,7 +37369,7 @@ function createTokenStore(options = {}) {
|
|
|
37332
37369
|
if (env[allowFileStoreKey] === "1") {
|
|
37333
37370
|
const warning = [
|
|
37334
37371
|
"WARNING: using the development-only plain-file CLI token store.",
|
|
37335
|
-
"It stores only
|
|
37372
|
+
"It stores only CLI session tokens, never tenant secrets, API keys, or vault refs."
|
|
37336
37373
|
].join(" ");
|
|
37337
37374
|
(options.stderr ?? process.stderr).write(`${warning}
|
|
37338
37375
|
`);
|
|
@@ -37346,7 +37383,7 @@ function createTokenStore(options = {}) {
|
|
|
37346
37383
|
[
|
|
37347
37384
|
"No OS credential store is available (the CLI uses the macOS Keychain by default; there is no Windows or Linux keychain integration).",
|
|
37348
37385
|
`For headless Linux, CI runners, or any no-keychain host, export ${allowFileStoreKey}=1 (set it for every invocation) to opt into the development-only plain-file token store.`,
|
|
37349
|
-
"It is not encrypted: it writes an owner-only file (directory 0700, file 0600) holding only
|
|
37386
|
+
"It is not encrypted: it writes an owner-only file (directory 0700, file 0600) holding only CLI session tokens \u2014 never tenant secrets, API keys, or vault refs."
|
|
37350
37387
|
].join(" ")
|
|
37351
37388
|
);
|
|
37352
37389
|
}
|
|
@@ -42180,7 +42217,7 @@ Review the first dry runs, fleet overview, tool-call audit rows, escalations, an
|
|
|
42180
42217
|
order: 46,
|
|
42181
42218
|
title: "Tool access and vault",
|
|
42182
42219
|
summary: "How to give agents access to tools without exposing raw credentials or expanding authority by accident.",
|
|
42183
|
-
version: "2026-06-20.
|
|
42220
|
+
version: "2026-06-20.2",
|
|
42184
42221
|
public: true,
|
|
42185
42222
|
audiences: ["human", "cli", "mcp", "in_app_agent"],
|
|
42186
42223
|
stages: ["staffing"],
|
|
@@ -42222,7 +42259,7 @@ Connecting a tool is a human-controlled step. The agent can recommend a tool, ex
|
|
|
42222
42259
|
|
|
42223
42260
|
## Generic REST connector
|
|
42224
42261
|
|
|
42225
|
-
For an API with no dedicated connector, the generic REST tool lets a seat call an HTTP endpoint with a credential you paste through the vault \u2014 no {{brand}}-owned app. It is escalate-by-default: the agent may only call a host a steward has signed onto the allowlist; any other host is refused and escalated, with no request made. The connector sets the Authorization header from the vaulted credential itself \u2014 the agent never sees the token, and the secret is redacted from the response before it reaches the agent, the audit row, or the logs. The token is only ever sent over HTTPS, only to the signed host, and a redirect is never followed \u2014 so an allowlisted endpoint cannot bounce the call (and the token) to another host. A sandbox dry run of a REST tool makes no real request.
|
|
42262
|
+
For an API with no dedicated connector, the generic REST tool lets a seat call an HTTP endpoint with a credential you paste through the vault \u2014 no {{brand}}-owned app. It is escalate-by-default: the agent may only call a host, method, and explicit path prefix a steward has signed onto the allowlist; any other host, method, or path is refused and escalated, with no request made. A path prefix of \`/\` means the steward intentionally approved every path. The connector sets the Authorization header from the vaulted credential itself \u2014 the agent never sees the token, and the secret is redacted from the response before it reaches the agent, the audit row, or the logs. The token is only ever sent over HTTPS, only to the signed host and scoped path, and a redirect is never followed \u2014 so an allowlisted endpoint cannot bounce the call (and the token) to another host. A sandbox dry run of a REST tool makes no real request.
|
|
42226
42263
|
|
|
42227
42264
|
## Slack post connector
|
|
42228
42265
|
|
|
@@ -42256,7 +42293,7 @@ There is exactly one way to give a connected tool its credential, and it is the
|
|
|
42256
42293
|
order: 47,
|
|
42257
42294
|
title: "Available tools guide",
|
|
42258
42295
|
summary: "How to think about tool categories available to seats and what each category should be used for.",
|
|
42259
|
-
version: "2026-06-20.
|
|
42296
|
+
version: "2026-06-20.2",
|
|
42260
42297
|
public: true,
|
|
42261
42298
|
audiences: ["human", "cli", "mcp", "in_app_agent"],
|
|
42262
42299
|
stages: ["staffing"],
|
|
@@ -42298,14 +42335,14 @@ Agents should explain the job, the required tool category, the minimum permissio
|
|
|
42298
42335
|
|
|
42299
42336
|
Every tool call passes the server-side guard first: the guard checks the call against the seat's signed permission manifest and records a tool-call audit row for **every** call \u2014 allowed, denied, or escalated. Tool selection is never authorization. Only an allowed call reaches its handler. A connected credential is bound into the handler for the duration of the call only; the secret never appears in the result, the audit summary, logs, or the model's context.
|
|
42300
42337
|
|
|
42301
|
-
External connectors are being rolled out provider by provider, conservatively (read and draft before send; write behind approval). A selected tool is only a permission until a live handler exists and the seat has the required credential or binding. Today the built-in execution path supports internal status reporting, the generic REST connector when a signed allowlist and credential exist, and \`slack.post_message\` for a bound Slack channel. Other provider entries remain configuration-only until their connector ships, so nothing runs silently.`
|
|
42338
|
+
External connectors are being rolled out provider by provider, conservatively (read and draft before send; write behind approval). A selected tool is only a permission until a live handler exists and the seat has the required credential or binding. Today the built-in execution path supports internal status reporting, the generic REST connector when a signed host/method/path allowlist and credential exist, and \`slack.post_message\` for a bound Slack channel. Other provider entries remain configuration-only until their connector ships, so nothing runs silently.`
|
|
42302
42339
|
},
|
|
42303
42340
|
{
|
|
42304
42341
|
slug: "mcp-and-cli-guide",
|
|
42305
42342
|
order: 48,
|
|
42306
42343
|
title: "CLI and MCP installation guide",
|
|
42307
42344
|
summary: "Install the public CLI, register remote token-backed MCP clients, and find the full command and tool catalog.",
|
|
42308
|
-
version: "2026-06-20.
|
|
42345
|
+
version: "2026-06-20.4",
|
|
42309
42346
|
public: true,
|
|
42310
42347
|
audiences: ["human", "cli", "mcp", "in_app_agent"],
|
|
42311
42348
|
stages: ["company_setup", "staffing"],
|
|
@@ -42453,7 +42490,7 @@ Notes:
|
|
|
42453
42490
|
|
|
42454
42491
|
By default the CLI stores the session in the **macOS Keychain** (on darwin). There is no built-in Windows or Linux keychain integration today \u2014 on any non-macOS host, or any machine without a keychain, the CLI errors with "No OS credential store is available" unless you opt into the file store.
|
|
42455
42492
|
|
|
42456
|
-
For headless Linux, CI runners, or any no-keychain environment, set \`{{envPrefix}}_CLI_ALLOW_FILE_TOKEN_STORE=1\` to opt into the **development-only plain-file token store**. It is **not encrypted** \u2014 it writes the file with owner-only permissions (directory \`0700\`, file \`0600\`) and prints a stderr warning. It stores **only
|
|
42493
|
+
For headless Linux, CI runners, or any no-keychain environment, set \`{{envPrefix}}_CLI_ALLOW_FILE_TOKEN_STORE=1\` to opt into the **development-only plain-file token store**. It is **not encrypted** \u2014 it writes the file with owner-only permissions (directory \`0700\`, file \`0600\`) and prints a stderr warning. It stores **only CLI session tokens** (access + refresh token), never tenant secrets, API keys, or vault refs. Treat that file as a credential: do not bake it into a shared image and do not commit it.
|
|
42457
42494
|
|
|
42458
42495
|
The CLI checks this flag on **every** invocation, not just \`login\`. Export it for the whole shell or CI job (so \`{{cli}} whoami\`, \`{{cli}} onboard status\`, and the rest also find the file store), not only on the login line:
|
|
42459
42496
|
|
|
@@ -42462,7 +42499,7 @@ export {{envPrefix}}_CLI_ALLOW_FILE_TOKEN_STORE=1
|
|
|
42462
42499
|
{{cli}} login --device
|
|
42463
42500
|
\`\`\`
|
|
42464
42501
|
|
|
42465
|
-
For CI, do not run an interactive device login on every job (a device code still needs a human approver, which CI does not have).
|
|
42502
|
+
For CI, do not run an interactive device login on every job (a device code still needs a human approver, which CI does not have). The CLI stores the Supabase refresh token from \`login\` / \`login --device\` and refreshes the access token before command execution when it is close to expiry, so normal local agent sessions survive the short access-token window without repeated browser approvals. The refresh token is still a user credential; if refresh fails or is revoked, run \`{{cli}} login --device\` again. For ongoing unattended automation, prefer a **seat-scoped MCP token** used directly by your MCP client, and treat that client config as a secret. Such a token now defaults to a **90-day** expiry, so for automation that must outlive that window, mint it with an explicit \`--expires-in <days>\` (up to 365) or, accepting the long-lived-credential tradeoff, \`--no-expiry\` \u2014 e.g. \`mcp install --scope seat --seat-id <id> --expires-in 365\`. Rotate it before it lapses (\`--rotate <old-token-id>\`), and revoke and re-mint if a runner image is rebuilt or shared.
|
|
42466
42503
|
|
|
42467
42504
|
## First-run path
|
|
42468
42505
|
|
|
@@ -42721,6 +42758,7 @@ These ergonomic wrappers (including the \`{{cli}} agent\` group) require **{{cli
|
|
|
42721
42758
|
| \`{{cli}} member invite|update|remove\` | \`member.invite\`, \`member.update\`, \`member.remove\` | Manage tenant members. | Tenant | \`{{cli}} member invite --email ops@example.com --role member\` |
|
|
42722
42759
|
| \`{{cli}} agent templates|create|setup|tools|dry-run|go-live|status|run-now|get-run|show\` | \`agent_template.list\`, \`agent.create_from_template\`, \`agent.create_custom\`, \`agent_setup.get\`, \`agent_setup.update\`, \`agent.configure_tools\`, \`agent.run_dry_run\`, \`agent.go_live\`, \`agent.status\`, \`agent.run_now\`, \`agent.get_run\`, \`agent.show_markdown\` | Run the full agent setup and operation flow: list templates, create a draft from a template or guided custom answers (with \`--model\` and \`--effort\`), read or answer setup state, connect or decline tools, dry-run, go live, run on demand, read one run's transcript/error diagnostics, and show a markdown readout. Create and go-live stop at human gates; the dry-run is ungated by human approval but requires a signed manifest first. | Tenant and seat | \`{{cli}} agent get-run --seat-id <seat-id> --run-id <run-id> --json\` |
|
|
42723
42760
|
| \`{{cli}} tools list\` | \`tool.catalog\` | List the discoverable tool catalog the builder reads (id, scope tiers, credential requirement, access policy, and execution-boundary guidance). | Tenant | \`{{cli}} tools list --json\` |
|
|
42761
|
+
| \`{{cli}} model list\` | \`model.catalog\` | List guided model tiers with recommendations, token prices, cost bands, best-fit work, and model ids for \`--model\`. | Tenant | \`{{cli}} model list --json\` |
|
|
42724
42762
|
| \`{{cli}} compass show\` | \`compass.show_markdown\` | Render the current Compass as a clean markdown card for review. | Tenant | \`{{cli}} compass show --markdown\` |
|
|
42725
42763
|
| \`{{cli}} charter show\` | \`charter.show_markdown\` | Render a seat's Charter as a clean markdown card for review. | Tenant | \`{{cli}} charter show --seat-id <id> --markdown\` |
|
|
42726
42764
|
|
|
@@ -42743,7 +42781,8 @@ This catalog is the canonical machine surface \u2014 the \`rost_*\` tools your M
|
|
|
42743
42781
|
|
|
42744
42782
|
1. **The MCP tools below** \u2014 the \`rost_*\` surface your client actually calls to read and act.
|
|
42745
42783
|
2. **\`{{cli}} tools list\` / \`tool.catalog\`** (MCP \`rost_list_tool_catalog\`) \u2014 the agent-configuration catalog the builder reads when staffing an agent. It is selectable per agent, but selecting a tool is not itself a call; live handlers execute later only behind the signed manifest, guard, credentials, and bindings.
|
|
42746
|
-
3.
|
|
42784
|
+
3. **\`{{cli}} model list\` / \`model.catalog\`** (MCP \`rost_list_model_catalog\`) \u2014 the guided model-tier catalog the builder reads for recommendations, effort, token prices, cost bands, and model id selection.
|
|
42785
|
+
4. **The "Available tools guide"** (in the sidebar) \u2014 covers tool *categories* and governance, not a callable surface. See the available-tools-guide.
|
|
42747
42786
|
|
|
42748
42787
|
Sections below: Command discovery (2) \xB7 Public reference (3) \xB7 Tenant-admin tools (grouped by domain) \xB7 Seat-scoped operating tools (9) \xB7 MCP operation resources (9).
|
|
42749
42788
|
|
|
@@ -42879,6 +42918,7 @@ Several rows here are seat-operating commands (\`task.create\`, the \`signal.*\`
|
|
|
42879
42918
|
| \`rost_show_charter_as_markdown\` | \`charter.show_markdown\` | Render a seat's active or latest Charter as a clean markdown card for review. | Tenant | Call with \`{"seat_id":"<seat-id>"}\`. |
|
|
42880
42919
|
| \`rost_show_agent_setup_as_markdown\` | \`agent.show_markdown\` | Render a seat's agent setup, model, steward, tools, and Charter as a clean markdown card for review. | Tenant | Call with \`{"seat_id":"<seat-id>"}\`. |
|
|
42881
42920
|
| \`rost_list_tool_catalog\` | \`tool.catalog\` | List the discoverable tool catalog the agent builder reads \u2014 id, prescriptive description, scope tiers, credential requirement, access policy, and execution-boundary guidance. | Tenant | Call with \`{}\` or \`{"provider":"google"}\`. |
|
|
42921
|
+
| \`rost_list_model_catalog\` | \`model.catalog\` | List guided model tiers \u2014 recommendations, token prices, cost bands, best-fit work, and model ids for \`--model\`. | Tenant | Call with \`{}\`. |
|
|
42882
42922
|
|
|
42883
42923
|
### Seat-scoped operating tools
|
|
42884
42924
|
|
|
@@ -42936,7 +42976,7 @@ These rows are quick, at-a-glance triage. For deeper auth, tenant, scope, confir
|
|
|
42936
42976
|
order: 49,
|
|
42937
42977
|
title: "Agent reference map",
|
|
42938
42978
|
summary: "Where CLI sessions, MCP clients, and in-app agents should retrieve {{brand}} guidance before recommending setup changes.",
|
|
42939
|
-
version: "2026-06-20.
|
|
42979
|
+
version: "2026-06-20.2",
|
|
42940
42980
|
public: true,
|
|
42941
42981
|
audiences: ["cli", "mcp", "in_app_agent"],
|
|
42942
42982
|
stages: ["company_setup", "graph_design", "charter_design", "staffing", "operating_rhythm"],
|
|
@@ -42987,6 +43027,7 @@ Never guess a command's JSON shape. Before calling a command that changes state,
|
|
|
42987
43027
|
- List every callable command: {{cli}} command list (CLI) or rost_list_commands (MCP)
|
|
42988
43028
|
- Read one command's exact input/output schema, help pointer, and a worked example: {{cli}} command schema <id> (CLI) or rost_describe_command with {"command_id":"<id>"} (MCP)
|
|
42989
43029
|
- List the tool catalog the agent builder reads (id, scope tiers, credential requirement, access policy, and execution-boundary guidance): {{cli}} tools list (CLI) or rost_list_tool_catalog (MCP)
|
|
43030
|
+
- List guided model tiers before choosing --model (recommended default, effort, token prices, cost bands, best-fit work, model id): {{cli}} model list (CLI) or rost_list_model_catalog (MCP)
|
|
42990
43031
|
- Show a Compass, Charter, or agent setup as a markdown card to review with your human: {{cli}} compass show --markdown, {{cli}} charter show --seat-id <id> --markdown, {{cli}} agent show --seat-id <id> --markdown
|
|
42991
43032
|
|
|
42992
43033
|
When a command fails, the error returns a machine-readable code, a message, and a help field naming the exact command to run next. Read the help field and run the command it points at \u2014 do not retry the same call blindly. A failed precondition (for example a manifest not yet signed, a dry run that has not passed, or the inference budget hard cap reached) returns COMMAND_PRECONDITION_FAILED with a help pointer, not an opaque internal error.
|
|
@@ -43029,7 +43070,7 @@ Read the listed guide before recommending or running each workflow. Every workfl
|
|
|
43029
43070
|
- Add an agent through the app (graph or sidebar, visual journey): add-agents-guide.
|
|
43030
43071
|
- Create an agent from a template: stock-agents-guide, then how-agents-work.
|
|
43031
43072
|
- Create a custom agent (operational answers, Charter Builder, configure tools, dry run, go live): custom-agents-guide, then agent-staffing-playbook and tool-access-and-vault.
|
|
43032
|
-
- Build a controlled agent worker directly on the CLI/MCP path (seat, steward, job, boundaries, tools, credentials, model, schedule, dry-run, go-live): agent-builder-guide \u2014 it shows the full setup sequence, the structured model config, the access tiers, how to discover tools (tool.catalog), which connector entries have live execution boundaries, and how to show your human a markdown readout (agent.show_markdown).
|
|
43073
|
+
- Build a controlled agent worker directly on the CLI/MCP path (seat, steward, job, boundaries, tools, credentials, model, schedule, dry-run, go-live): agent-builder-guide \u2014 it shows the full setup sequence, the structured model config, the model catalog (model.catalog), the access tiers, how to discover tools (tool.catalog), which connector entries have live execution boundaries, and how to show your human a markdown readout (agent.show_markdown).
|
|
43033
43074
|
- Connect an existing or local agent to a seat: stock-agents-guide (connect section), then mcp-and-cli-guide and runner-guide.
|
|
43034
43075
|
- Run the operating loop as a seat (context, tasks, status, escalate): how-agents-work.
|
|
43035
43076
|
- Track goals: cascade-guide. Track measurables: signal-guide. File and resolve issues, tasks, escalations: friction-guide.
|
|
@@ -43735,7 +43776,7 @@ Name the failing surface, collect evidence, recommend the smallest correction, a
|
|
|
43735
43776
|
order: 78,
|
|
43736
43777
|
title: "Security model guide",
|
|
43737
43778
|
summary: "How {{brand}} protects tenant data, credentials, tool calls, and human decisions across web, MCP, CLI, and agents.",
|
|
43738
|
-
version: "2026-06-
|
|
43779
|
+
version: "2026-06-20.1",
|
|
43739
43780
|
public: true,
|
|
43740
43781
|
audiences: ["human", "cli", "mcp", "in_app_agent"],
|
|
43741
43782
|
stages: ["company_setup", "staffing", "operating_rhythm"],
|
|
@@ -43766,6 +43807,8 @@ Name the failing surface, collect evidence, recommend the smallest correction, a
|
|
|
43766
43807
|
- Agents recommend and draft; humans approve durable decisions.
|
|
43767
43808
|
- Accepted knowledge changes by supersession, not silent mutation.
|
|
43768
43809
|
|
|
43810
|
+
The public Privacy Policy and Terms of Service are available at \`/privacy\` and \`/terms\` before sign-in and from the authenticated app chrome.
|
|
43811
|
+
|
|
43769
43812
|
## Agent guidance
|
|
43770
43813
|
|
|
43771
43814
|
Never infer permission from the user's wording or a locally available tool. Check the Charter, manifest, and server response. When in doubt, escalate with the evidence and the narrow question a human must decide.`
|
|
@@ -44067,7 +44110,7 @@ This worked document **omits** \`unanswered_boundaries\` and \`seat_type_recomme
|
|
|
44067
44110
|
order: 43,
|
|
44068
44111
|
title: "Agent builder guide",
|
|
44069
44112
|
summary: "The full agent setup sequence on the CLI/MCP path \u2014 seat, steward, job, boundaries, tools, credentials, model, schedule, dry-run, go-live \u2014 with the structured model config and access tiers.",
|
|
44070
|
-
version: "2026-06-20.
|
|
44113
|
+
version: "2026-06-20.2",
|
|
44071
44114
|
public: true,
|
|
44072
44115
|
audiences: ["cli", "mcp", "in_app_agent"],
|
|
44073
44116
|
stages: ["staffing"],
|
|
@@ -44078,6 +44121,7 @@ This worked document **omits** \`unanswered_boundaries\` and \`seat_type_recomme
|
|
|
44078
44121
|
"agent_setup.update",
|
|
44079
44122
|
"agent.configure_tools",
|
|
44080
44123
|
"tool.catalog",
|
|
44124
|
+
"model.catalog",
|
|
44081
44125
|
"agent.run_dry_run",
|
|
44082
44126
|
"agent.go_live",
|
|
44083
44127
|
"agent.show_markdown",
|
|
@@ -44116,7 +44160,7 @@ Building teams of controlled agent workers is the product's core differentiator.
|
|
|
44116
44160
|
5. **Tools** \u2014 pick from the discoverable catalog (\`{{cli}} tools list\`); each tool has a default scope tier and access policy. Connect or decline via \`agent.configure_tools\`. Selecting a tool records permission; live handlers execute later only behind the signed manifest, server guard, required credential or binding, and connector-specific approval boundary.
|
|
44117
44161
|
6. **Credentials** \u2014 a tool that needs access declares a credential-ingress request (provider, scope, secret name). The secret itself flows through the vault-backed ingress command as a vault ref \u2014 never paste a secret into a builder command.
|
|
44118
44162
|
7. **Operating instructions** \u2014 the runtime composes the agent's context from its Charter; you do not write a system prompt.
|
|
44119
|
-
8. **Model** \u2014 select the structured model config (see below).
|
|
44163
|
+
8. **Model** \u2014 select the structured model config (see below). Read \`{{cli}} model list\` / \`model.catalog\` first when you are unsure; it returns the recommended default, effort, token price estimates, cost band, and best-fit work for each tier. If \`agent.create_custom\` omits \`model_config\`, {{brand}} recommends a tier from the supplied responsibility answers.
|
|
44120
44164
|
9. **Heartbeat** \u2014 set the schedule (\`schedule_cron\`) for a recurring agent; a live scheduled agent must keep a steward chain.
|
|
44121
44165
|
10. **Dry-run** \u2014 \`agent.run_dry_run\` rehearses in sandbox after the manifest is signed; it is ungated by human approval but requires a signed manifest.
|
|
44122
44166
|
11. **Go-live** \u2014 \`agent.go_live\` is \`human_required\`. Prepare everything and surface the go-live to a human; never go live on a human's behalf.
|
|
@@ -44133,6 +44177,8 @@ The agent's model is a structured object, not a bare string:
|
|
|
44133
44177
|
- \`model\` is a model id. Pick by the work the seat does \u2014 a triage tier for cheap, high-volume classification; a balanced tier for most seats; a complex tier for judgment-heavy reasoning; the hardest tier for long-horizon agentic work. The builder offers tier shortcuts (\`triage\`, \`balanced\`, \`complex\`, \`hardest\`) that map to a current Claude id, so you never hardcode a stale one.
|
|
44134
44178
|
- \`effort\` (\`low\` \u2192 \`max\`) trades thoroughness for cost/latency. Low for triage; high or xhigh for the hardest agentic seats.
|
|
44135
44179
|
|
|
44180
|
+
Run \`{{cli}} model list\` (MCP \`rost_list_model_catalog\`) before choosing when cost or reasoning depth is unclear. Balanced is the recommended default. Token prices are catalog estimates per million tokens, and cost bands are planning guidance for relative spend; the billing-grade number is still each run's recorded token usage and \`cost_usd\`. Custom agent creation recommends a tier from responsibility answers when \`model_config\` is omitted.
|
|
44181
|
+
|
|
44136
44182
|
On the CLI, \`{{cli}} agent create --custom --seat-id <id> --model balanced --effort medium \u2026\`, or set it later with \`{{cli}} agent setup answer --seat-id <id> --model complex\`. The model cannot change after the agent is live.
|
|
44137
44183
|
|
|
44138
44184
|
## Access tiers
|
|
@@ -45088,7 +45134,7 @@ function markdownLine(output) {
|
|
|
45088
45134
|
const markdown = asRecord(output).markdown;
|
|
45089
45135
|
return typeof markdown === "string" ? markdown : JSON.stringify(output, null, 2);
|
|
45090
45136
|
}
|
|
45091
|
-
var
|
|
45137
|
+
var CLI_MODEL_TIER_MAP = {
|
|
45092
45138
|
triage: { model: "claude-haiku-4-5", effort: "low" },
|
|
45093
45139
|
balanced: { model: "claude-sonnet-4-6", effort: "medium" },
|
|
45094
45140
|
complex: { model: "claude-opus-4-8", effort: "high" },
|
|
@@ -45098,7 +45144,7 @@ function resolveModelConfig(model, effort) {
|
|
|
45098
45144
|
if (model === void 0) {
|
|
45099
45145
|
return void 0;
|
|
45100
45146
|
}
|
|
45101
|
-
const tier =
|
|
45147
|
+
const tier = CLI_MODEL_TIER_MAP[model];
|
|
45102
45148
|
const resolvedModel = tier ? tier.model : model;
|
|
45103
45149
|
const resolvedEffort = effort ?? tier?.effort;
|
|
45104
45150
|
return {
|
|
@@ -45945,6 +45991,44 @@ function toolsUsage(bin) {
|
|
|
45945
45991
|
return `Usage: ${bin} tools list [--provider <name>] [--json]
|
|
45946
45992
|
${bin} tools list \u2014 the discoverable tool catalog the builder reads; live handlers execute only behind signed manifests, guards, credentials, and bindings.`;
|
|
45947
45993
|
}
|
|
45994
|
+
var modelWrapper = (context, args) => dispatch(context, "model", args, {
|
|
45995
|
+
list: (ctx, rest) => {
|
|
45996
|
+
const parsed = parseFlags(rest);
|
|
45997
|
+
return execute(ctx, parsed, "model.catalog", {}, (output) => {
|
|
45998
|
+
const record2 = asRecord(output);
|
|
45999
|
+
const tiers = asArray(record2.tiers);
|
|
46000
|
+
const header = `# Model tiers
|
|
46001
|
+
|
|
46002
|
+
${field(record2, "note")}
|
|
46003
|
+
`;
|
|
46004
|
+
if (tiers.length === 0) {
|
|
46005
|
+
return `${header}
|
|
46006
|
+
No model tiers are configured.`;
|
|
46007
|
+
}
|
|
46008
|
+
const defaultTier = field(record2, "default_tier");
|
|
46009
|
+
const lines = tiers.map((entry) => {
|
|
46010
|
+
const r = asRecord(entry);
|
|
46011
|
+
const tier = field(r, "tier");
|
|
46012
|
+
const recommended = r.recommended === true || tier === defaultTier ? " recommended" : "";
|
|
46013
|
+
const bestFor = asArray(r.best_for).map(String).join(", ");
|
|
46014
|
+
return [
|
|
46015
|
+
`- \`${tier}\` [${field(r, "provider")}/${field(r, "model")} \xB7 effort ${field(r, "effort")} \xB7 cost ${field(r, "cost_band")}${recommended}]`,
|
|
46016
|
+
` ${field(r, "description")}`,
|
|
46017
|
+
` Best for: ${bestFor}`,
|
|
46018
|
+
` Price: $${field(r, "input_usd_per_million_tokens")}/1M input \xB7 $${field(r, "output_usd_per_million_tokens")}/1M output`,
|
|
46019
|
+
` Cost: ${field(r, "cost_note")}`,
|
|
46020
|
+
` Avoid for: ${field(r, "avoid_for")}`
|
|
46021
|
+
].join("\n");
|
|
46022
|
+
});
|
|
46023
|
+
return `${header}
|
|
46024
|
+
${lines.join("\n")}`;
|
|
46025
|
+
});
|
|
46026
|
+
}
|
|
46027
|
+
}, modelUsage(context.binName));
|
|
46028
|
+
function modelUsage(bin) {
|
|
46029
|
+
return `Usage: ${bin} model list [--json]
|
|
46030
|
+
${bin} model list \u2014 guided model tiers with recommendations, token prices, cost bands, and model ids for --model.`;
|
|
46031
|
+
}
|
|
45948
46032
|
var compassWrapper = (context, args) => dispatch(context, "compass", args, {
|
|
45949
46033
|
show: (ctx, rest) => {
|
|
45950
46034
|
const parsed = parseFlags(rest, /* @__PURE__ */ new Set(["markdown"]));
|
|
@@ -45980,6 +46064,7 @@ var OPERATION_GROUPS = [
|
|
|
45980
46064
|
"member",
|
|
45981
46065
|
"agent",
|
|
45982
46066
|
"tools",
|
|
46067
|
+
"model",
|
|
45983
46068
|
"compass",
|
|
45984
46069
|
"charter"
|
|
45985
46070
|
];
|
|
@@ -45997,6 +46082,7 @@ var wrappers = {
|
|
|
45997
46082
|
member: memberWrapper,
|
|
45998
46083
|
agent: agentWrapper,
|
|
45999
46084
|
tools: toolsWrapper,
|
|
46085
|
+
model: modelWrapper,
|
|
46000
46086
|
compass: compassWrapper,
|
|
46001
46087
|
charter: charterWrapper
|
|
46002
46088
|
};
|
|
@@ -46017,6 +46103,7 @@ var groupUsageBuilders = {
|
|
|
46017
46103
|
member: memberUsage,
|
|
46018
46104
|
agent: agentUsage,
|
|
46019
46105
|
tools: toolsUsage,
|
|
46106
|
+
model: modelUsage,
|
|
46020
46107
|
compass: compassUsage,
|
|
46021
46108
|
charter: charterUsage
|
|
46022
46109
|
};
|
|
@@ -46046,6 +46133,7 @@ function operationUsageLines(bin) {
|
|
|
46046
46133
|
`${bin} member invite|update|remove`,
|
|
46047
46134
|
`${bin} agent templates|create|setup|tools|dry-run|go-live|status|run-now|get-run|show`,
|
|
46048
46135
|
`${bin} tools list`,
|
|
46136
|
+
`${bin} model list`,
|
|
46049
46137
|
`${bin} compass show`,
|
|
46050
46138
|
`${bin} charter show`
|
|
46051
46139
|
];
|
|
@@ -46130,6 +46218,7 @@ async function main(argv = process.argv.slice(2), options = {}) {
|
|
|
46130
46218
|
};
|
|
46131
46219
|
const login = options.login ?? loginWithBrowser;
|
|
46132
46220
|
const deviceLogin = options.deviceLogin ?? loginWithDeviceCode;
|
|
46221
|
+
const refreshSession = options.refreshSession ?? refreshCliSessionIfNeeded;
|
|
46133
46222
|
const [rawCommand, ...args] = argv;
|
|
46134
46223
|
const command = rawCommand === "--help" || rawCommand === "-h" ? "help" : rawCommand;
|
|
46135
46224
|
if (!isCommand(command) && !isOperationGroup(command)) {
|
|
@@ -46230,6 +46319,29 @@ async function main(argv = process.argv.slice(2), options = {}) {
|
|
|
46230
46319
|
return 1;
|
|
46231
46320
|
}
|
|
46232
46321
|
const config2 = loadConfig();
|
|
46322
|
+
let refreshed;
|
|
46323
|
+
try {
|
|
46324
|
+
refreshed = await refreshSession(config2, session);
|
|
46325
|
+
} catch (error51) {
|
|
46326
|
+
io.stderr.write(
|
|
46327
|
+
`${redactForLog(error51 instanceof Error ? error51.message : String(error51))}
|
|
46328
|
+
Session refresh failed. Run ${cliBrand.binName} login --device again.
|
|
46329
|
+
`
|
|
46330
|
+
);
|
|
46331
|
+
return 1;
|
|
46332
|
+
}
|
|
46333
|
+
if (refreshed !== session) {
|
|
46334
|
+
session = refreshed;
|
|
46335
|
+
try {
|
|
46336
|
+
await store.write(session);
|
|
46337
|
+
} catch (error51) {
|
|
46338
|
+
io.stderr.write(
|
|
46339
|
+
`Session refreshed, but storing it failed: ${redactForLog(error51 instanceof Error ? error51.message : String(error51))}
|
|
46340
|
+
Run ${cliBrand.binName} login --device again if the next command asks you to authenticate.
|
|
46341
|
+
`
|
|
46342
|
+
);
|
|
46343
|
+
}
|
|
46344
|
+
}
|
|
46233
46345
|
const client = new CommandClient({
|
|
46234
46346
|
appUrl: config2.appUrl,
|
|
46235
46347
|
token: session.accessToken
|