@rosthq/cli 0.5.18 → 0.5.20
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/index.d.ts.map +1 -1
- package/dist/index.js +1176 -118
- package/dist/index.js.map +4 -4
- package/dist/operations.d.ts.map +1 -1
- package/dist/skills.d.ts +19 -0
- package/dist/skills.d.ts.map +1 -0
- package/package.json +1 -1
- package/prompts/how-tos/human-confirmations.md +2 -0
package/dist/index.js
CHANGED
|
@@ -472,13 +472,13 @@ function __disposeResources(env) {
|
|
|
472
472
|
}
|
|
473
473
|
return next();
|
|
474
474
|
}
|
|
475
|
-
function __rewriteRelativeImportExtension(
|
|
476
|
-
if (typeof
|
|
477
|
-
return
|
|
475
|
+
function __rewriteRelativeImportExtension(path3, preserveJsx) {
|
|
476
|
+
if (typeof path3 === "string" && /^\.\.?\//.test(path3)) {
|
|
477
|
+
return path3.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function(m, tsx, d, ext, cm) {
|
|
478
478
|
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : d + ext + "." + cm.toLowerCase() + "js";
|
|
479
479
|
});
|
|
480
480
|
}
|
|
481
|
-
return
|
|
481
|
+
return path3;
|
|
482
482
|
}
|
|
483
483
|
var extendStatics, __assign, __createBinding, __setModuleDefault, ownKeys, _SuppressedError, tslib_es6_default;
|
|
484
484
|
var init_tslib_es6 = __esm({
|
|
@@ -14026,10 +14026,10 @@ function mergeDefs(...defs) {
|
|
|
14026
14026
|
function cloneDef(schema) {
|
|
14027
14027
|
return mergeDefs(schema._zod.def);
|
|
14028
14028
|
}
|
|
14029
|
-
function getElementAtPath(obj,
|
|
14030
|
-
if (!
|
|
14029
|
+
function getElementAtPath(obj, path3) {
|
|
14030
|
+
if (!path3)
|
|
14031
14031
|
return obj;
|
|
14032
|
-
return
|
|
14032
|
+
return path3.reduce((acc, key) => acc?.[key], obj);
|
|
14033
14033
|
}
|
|
14034
14034
|
function promiseAllObject(promisesObj) {
|
|
14035
14035
|
const keys = Object.keys(promisesObj);
|
|
@@ -14438,11 +14438,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
14438
14438
|
}
|
|
14439
14439
|
return false;
|
|
14440
14440
|
}
|
|
14441
|
-
function prefixIssues(
|
|
14441
|
+
function prefixIssues(path3, issues) {
|
|
14442
14442
|
return issues.map((iss) => {
|
|
14443
14443
|
var _a3;
|
|
14444
14444
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
14445
|
-
iss.path.unshift(
|
|
14445
|
+
iss.path.unshift(path3);
|
|
14446
14446
|
return iss;
|
|
14447
14447
|
});
|
|
14448
14448
|
}
|
|
@@ -14589,16 +14589,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
|
|
|
14589
14589
|
}
|
|
14590
14590
|
function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
14591
14591
|
const fieldErrors = { _errors: [] };
|
|
14592
|
-
const processError = (error52,
|
|
14592
|
+
const processError = (error52, path3 = []) => {
|
|
14593
14593
|
for (const issue2 of error52.issues) {
|
|
14594
14594
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
14595
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
14595
|
+
issue2.errors.map((issues) => processError({ issues }, [...path3, ...issue2.path]));
|
|
14596
14596
|
} else if (issue2.code === "invalid_key") {
|
|
14597
|
-
processError({ issues: issue2.issues }, [...
|
|
14597
|
+
processError({ issues: issue2.issues }, [...path3, ...issue2.path]);
|
|
14598
14598
|
} else if (issue2.code === "invalid_element") {
|
|
14599
|
-
processError({ issues: issue2.issues }, [...
|
|
14599
|
+
processError({ issues: issue2.issues }, [...path3, ...issue2.path]);
|
|
14600
14600
|
} else {
|
|
14601
|
-
const fullpath = [...
|
|
14601
|
+
const fullpath = [...path3, ...issue2.path];
|
|
14602
14602
|
if (fullpath.length === 0) {
|
|
14603
14603
|
fieldErrors._errors.push(mapper(issue2));
|
|
14604
14604
|
} else {
|
|
@@ -14625,17 +14625,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
|
14625
14625
|
}
|
|
14626
14626
|
function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
14627
14627
|
const result = { errors: [] };
|
|
14628
|
-
const processError = (error52,
|
|
14628
|
+
const processError = (error52, path3 = []) => {
|
|
14629
14629
|
var _a3, _b;
|
|
14630
14630
|
for (const issue2 of error52.issues) {
|
|
14631
14631
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
14632
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
14632
|
+
issue2.errors.map((issues) => processError({ issues }, [...path3, ...issue2.path]));
|
|
14633
14633
|
} else if (issue2.code === "invalid_key") {
|
|
14634
|
-
processError({ issues: issue2.issues }, [...
|
|
14634
|
+
processError({ issues: issue2.issues }, [...path3, ...issue2.path]);
|
|
14635
14635
|
} else if (issue2.code === "invalid_element") {
|
|
14636
|
-
processError({ issues: issue2.issues }, [...
|
|
14636
|
+
processError({ issues: issue2.issues }, [...path3, ...issue2.path]);
|
|
14637
14637
|
} else {
|
|
14638
|
-
const fullpath = [...
|
|
14638
|
+
const fullpath = [...path3, ...issue2.path];
|
|
14639
14639
|
if (fullpath.length === 0) {
|
|
14640
14640
|
result.errors.push(mapper(issue2));
|
|
14641
14641
|
continue;
|
|
@@ -14667,8 +14667,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
|
14667
14667
|
}
|
|
14668
14668
|
function toDotPath(_path) {
|
|
14669
14669
|
const segs = [];
|
|
14670
|
-
const
|
|
14671
|
-
for (const seg of
|
|
14670
|
+
const path3 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
14671
|
+
for (const seg of path3) {
|
|
14672
14672
|
if (typeof seg === "number")
|
|
14673
14673
|
segs.push(`[${seg}]`);
|
|
14674
14674
|
else if (typeof seg === "symbol")
|
|
@@ -27360,13 +27360,13 @@ function resolveRef(ref, ctx) {
|
|
|
27360
27360
|
if (!ref.startsWith("#")) {
|
|
27361
27361
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
27362
27362
|
}
|
|
27363
|
-
const
|
|
27364
|
-
if (
|
|
27363
|
+
const path3 = ref.slice(1).split("/").filter(Boolean);
|
|
27364
|
+
if (path3.length === 0) {
|
|
27365
27365
|
return ctx.rootSchema;
|
|
27366
27366
|
}
|
|
27367
27367
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
27368
|
-
if (
|
|
27369
|
-
const key =
|
|
27368
|
+
if (path3[0] === defsKey) {
|
|
27369
|
+
const key = path3[1];
|
|
27370
27370
|
if (!key || !ctx.defs[key]) {
|
|
27371
27371
|
throw new Error(`Reference not found: ${ref}`);
|
|
27372
27372
|
}
|
|
@@ -27828,7 +27828,7 @@ var CommandClient = class {
|
|
|
27828
27828
|
this.fetchImpl = options.fetchImpl ?? fetch;
|
|
27829
27829
|
}
|
|
27830
27830
|
async execute(commandId, body = {}, options = {}) {
|
|
27831
|
-
const
|
|
27831
|
+
const path3 = `/api/commands/${encodeURIComponent(commandId)}`;
|
|
27832
27832
|
const headers = {
|
|
27833
27833
|
authorization: `Bearer ${this.token}`,
|
|
27834
27834
|
"content-type": "application/json"
|
|
@@ -27836,7 +27836,7 @@ var CommandClient = class {
|
|
|
27836
27836
|
if (options.targetSeatId !== void 0 && options.targetSeatId.length > 0) {
|
|
27837
27837
|
headers["x-rost-seat"] = options.targetSeatId;
|
|
27838
27838
|
}
|
|
27839
|
-
const response = await this.fetchImpl(`${this.appUrl}${
|
|
27839
|
+
const response = await this.fetchImpl(`${this.appUrl}${path3}`, {
|
|
27840
27840
|
method: "POST",
|
|
27841
27841
|
headers,
|
|
27842
27842
|
body: JSON.stringify(body)
|
|
@@ -27849,7 +27849,7 @@ var CommandClient = class {
|
|
|
27849
27849
|
const snippet = redactSecrets(text.replace(/\s+/g, " ").trim()).slice(0, 200);
|
|
27850
27850
|
throw new CommandClientError(
|
|
27851
27851
|
response.status,
|
|
27852
|
-
`server returned HTTP ${response.status} (non-JSON) from ${
|
|
27852
|
+
`server returned HTTP ${response.status} (non-JSON) from ${path3}` + (snippet ? ` \u2014 ${snippet}` : "") + " \u2014 the deployment may be unhealthy"
|
|
27853
27853
|
);
|
|
27854
27854
|
}
|
|
27855
27855
|
const parsed = commandResponseSchema.parse(raw);
|
|
@@ -33056,8 +33056,8 @@ var IcebergError = class extends Error {
|
|
|
33056
33056
|
return this.status === 419;
|
|
33057
33057
|
}
|
|
33058
33058
|
};
|
|
33059
|
-
function buildUrl(baseUrl,
|
|
33060
|
-
const url2 = new URL(
|
|
33059
|
+
function buildUrl(baseUrl, path3, query) {
|
|
33060
|
+
const url2 = new URL(path3, baseUrl);
|
|
33061
33061
|
if (query) {
|
|
33062
33062
|
for (const [key, value] of Object.entries(query)) {
|
|
33063
33063
|
if (value !== void 0) {
|
|
@@ -33087,12 +33087,12 @@ function createFetchClient(options) {
|
|
|
33087
33087
|
return {
|
|
33088
33088
|
async request({
|
|
33089
33089
|
method,
|
|
33090
|
-
path:
|
|
33090
|
+
path: path3,
|
|
33091
33091
|
query,
|
|
33092
33092
|
body,
|
|
33093
33093
|
headers
|
|
33094
33094
|
}) {
|
|
33095
|
-
const url2 = buildUrl(options.baseUrl,
|
|
33095
|
+
const url2 = buildUrl(options.baseUrl, path3, query);
|
|
33096
33096
|
const authHeaders = await buildAuthHeaders(options.auth);
|
|
33097
33097
|
const res = await fetchFn(url2, {
|
|
33098
33098
|
method,
|
|
@@ -33954,7 +33954,7 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
33954
33954
|
* @param path The relative file path. Should be of the format `folder/subfolder/filename.png`. The bucket must already exist before attempting to upload.
|
|
33955
33955
|
* @param fileBody The body of the file to be stored in the bucket.
|
|
33956
33956
|
*/
|
|
33957
|
-
async uploadOrUpdate(method,
|
|
33957
|
+
async uploadOrUpdate(method, path3, fileBody, fileOptions) {
|
|
33958
33958
|
var _this = this;
|
|
33959
33959
|
return _this.handleOperation(async () => {
|
|
33960
33960
|
let body;
|
|
@@ -33978,7 +33978,7 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
33978
33978
|
if ((typeof ReadableStream !== "undefined" && body instanceof ReadableStream || body && typeof body === "object" && "pipe" in body && typeof body.pipe === "function") && !options.duplex) options.duplex = "half";
|
|
33979
33979
|
}
|
|
33980
33980
|
if (fileOptions === null || fileOptions === void 0 ? void 0 : fileOptions.headers) for (const [key, value] of Object.entries(fileOptions.headers)) headers = setHeader(headers, key, value);
|
|
33981
|
-
const cleanPath = _this._removeEmptyFolders(
|
|
33981
|
+
const cleanPath = _this._removeEmptyFolders(path3);
|
|
33982
33982
|
const _path = _this._getFinalPath(cleanPath);
|
|
33983
33983
|
const data = await (method == "PUT" ? put : post)(_this.fetch, `${_this.url}/object/${_path}`, body, _objectSpread22({ headers }, (options === null || options === void 0 ? void 0 : options.duplex) ? { duplex: options.duplex } : {}));
|
|
33984
33984
|
return {
|
|
@@ -34055,8 +34055,8 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
34055
34055
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
34056
34056
|
* - For React Native, using either `Blob`, `File` or `FormData` does not work as intended. Upload file using `ArrayBuffer` from base64 file data instead, see example below.
|
|
34057
34057
|
*/
|
|
34058
|
-
async upload(
|
|
34059
|
-
return this.uploadOrUpdate("POST",
|
|
34058
|
+
async upload(path3, fileBody, fileOptions) {
|
|
34059
|
+
return this.uploadOrUpdate("POST", path3, fileBody, fileOptions);
|
|
34060
34060
|
}
|
|
34061
34061
|
/**
|
|
34062
34062
|
* Upload a file with a token generated from `createSignedUploadUrl`.
|
|
@@ -34096,9 +34096,9 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
34096
34096
|
* - `objects` table permissions: none
|
|
34097
34097
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
34098
34098
|
*/
|
|
34099
|
-
async uploadToSignedUrl(
|
|
34099
|
+
async uploadToSignedUrl(path3, token, fileBody, fileOptions) {
|
|
34100
34100
|
var _this3 = this;
|
|
34101
|
-
const cleanPath = _this3._removeEmptyFolders(
|
|
34101
|
+
const cleanPath = _this3._removeEmptyFolders(path3);
|
|
34102
34102
|
const _path = _this3._getFinalPath(cleanPath);
|
|
34103
34103
|
const url2 = new URL(_this3.url + `/object/upload/sign/${_path}`);
|
|
34104
34104
|
url2.searchParams.set("token", token);
|
|
@@ -34167,10 +34167,10 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
34167
34167
|
* - `objects` table permissions: `insert`
|
|
34168
34168
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
34169
34169
|
*/
|
|
34170
|
-
async createSignedUploadUrl(
|
|
34170
|
+
async createSignedUploadUrl(path3, options) {
|
|
34171
34171
|
var _this4 = this;
|
|
34172
34172
|
return _this4.handleOperation(async () => {
|
|
34173
|
-
let _path = _this4._getFinalPath(
|
|
34173
|
+
let _path = _this4._getFinalPath(path3);
|
|
34174
34174
|
const headers = _objectSpread22({}, _this4.headers);
|
|
34175
34175
|
if (options === null || options === void 0 ? void 0 : options.upsert) headers["x-upsert"] = "true";
|
|
34176
34176
|
const data = await post(_this4.fetch, `${_this4.url}/object/upload/sign/${_path}`, {}, { headers });
|
|
@@ -34179,7 +34179,7 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
34179
34179
|
if (!token) throw new StorageError("No token returned by API");
|
|
34180
34180
|
return {
|
|
34181
34181
|
signedUrl: url2.toString(),
|
|
34182
|
-
path:
|
|
34182
|
+
path: path3,
|
|
34183
34183
|
token
|
|
34184
34184
|
};
|
|
34185
34185
|
});
|
|
@@ -34239,8 +34239,8 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
34239
34239
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
34240
34240
|
* - For React Native, using either `Blob`, `File` or `FormData` does not work as intended. Update file using `ArrayBuffer` from base64 file data instead, see example below.
|
|
34241
34241
|
*/
|
|
34242
|
-
async update(
|
|
34243
|
-
return this.uploadOrUpdate("PUT",
|
|
34242
|
+
async update(path3, fileBody, fileOptions) {
|
|
34243
|
+
return this.uploadOrUpdate("PUT", path3, fileBody, fileOptions);
|
|
34244
34244
|
}
|
|
34245
34245
|
/**
|
|
34246
34246
|
* Moves an existing file to a new path in the same bucket.
|
|
@@ -34391,10 +34391,10 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
34391
34391
|
* - `objects` table permissions: `select`
|
|
34392
34392
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
34393
34393
|
*/
|
|
34394
|
-
async createSignedUrl(
|
|
34394
|
+
async createSignedUrl(path3, expiresIn, options) {
|
|
34395
34395
|
var _this8 = this;
|
|
34396
34396
|
return _this8.handleOperation(async () => {
|
|
34397
|
-
let _path = _this8._getFinalPath(
|
|
34397
|
+
let _path = _this8._getFinalPath(path3);
|
|
34398
34398
|
const hasTransform = typeof (options === null || options === void 0 ? void 0 : options.transform) === "object" && options.transform !== null && Object.keys(options.transform).length > 0;
|
|
34399
34399
|
let data = await post(_this8.fetch, `${_this8.url}/object/sign/${_path}`, _objectSpread22({ expiresIn }, hasTransform ? { transform: options.transform } : {}), { headers: _this8.headers });
|
|
34400
34400
|
const query = new URLSearchParams();
|
|
@@ -34530,13 +34530,13 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
34530
34530
|
* - `objects` table permissions: `select`
|
|
34531
34531
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
34532
34532
|
*/
|
|
34533
|
-
download(
|
|
34533
|
+
download(path3, options, parameters) {
|
|
34534
34534
|
const renderPath = typeof (options === null || options === void 0 ? void 0 : options.transform) === "object" && options.transform !== null && Object.keys(options.transform).length > 0 ? "render/image/authenticated" : "object";
|
|
34535
34535
|
const query = new URLSearchParams();
|
|
34536
34536
|
if (options === null || options === void 0 ? void 0 : options.transform) this.applyTransformOptsToQuery(query, options.transform);
|
|
34537
34537
|
if ((options === null || options === void 0 ? void 0 : options.cacheNonce) != null) query.set("cacheNonce", String(options.cacheNonce));
|
|
34538
34538
|
const queryString = query.toString();
|
|
34539
|
-
const _path = this._getFinalPath(
|
|
34539
|
+
const _path = this._getFinalPath(path3);
|
|
34540
34540
|
const downloadFn = () => get(this.fetch, `${this.url}/${renderPath}/${_path}${queryString ? `?${queryString}` : ""}`, {
|
|
34541
34541
|
headers: this.headers,
|
|
34542
34542
|
noResolveJson: true
|
|
@@ -34567,9 +34567,9 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
34567
34567
|
* }
|
|
34568
34568
|
* ```
|
|
34569
34569
|
*/
|
|
34570
|
-
async info(
|
|
34570
|
+
async info(path3) {
|
|
34571
34571
|
var _this10 = this;
|
|
34572
|
-
const _path = _this10._getFinalPath(
|
|
34572
|
+
const _path = _this10._getFinalPath(path3);
|
|
34573
34573
|
return _this10.handleOperation(async () => {
|
|
34574
34574
|
return recursiveToCamel(await get(_this10.fetch, `${_this10.url}/object/info/${_path}`, { headers: _this10.headers }));
|
|
34575
34575
|
});
|
|
@@ -34590,9 +34590,9 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
34590
34590
|
* .exists('folder/avatar1.png')
|
|
34591
34591
|
* ```
|
|
34592
34592
|
*/
|
|
34593
|
-
async exists(
|
|
34593
|
+
async exists(path3) {
|
|
34594
34594
|
var _this11 = this;
|
|
34595
|
-
const _path = _this11._getFinalPath(
|
|
34595
|
+
const _path = _this11._getFinalPath(path3);
|
|
34596
34596
|
try {
|
|
34597
34597
|
await head(_this11.fetch, `${_this11.url}/object/${_path}`, { headers: _this11.headers });
|
|
34598
34598
|
return {
|
|
@@ -34671,8 +34671,8 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
34671
34671
|
* - `objects` table permissions: none
|
|
34672
34672
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
34673
34673
|
*/
|
|
34674
|
-
getPublicUrl(
|
|
34675
|
-
const _path = this._getFinalPath(
|
|
34674
|
+
getPublicUrl(path3, options) {
|
|
34675
|
+
const _path = this._getFinalPath(path3);
|
|
34676
34676
|
const query = new URLSearchParams();
|
|
34677
34677
|
if (options === null || options === void 0 ? void 0 : options.download) query.set("download", options.download === true ? "" : options.download);
|
|
34678
34678
|
if (options === null || options === void 0 ? void 0 : options.transform) this.applyTransformOptsToQuery(query, options.transform);
|
|
@@ -34811,10 +34811,10 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
34811
34811
|
* - `objects` table permissions: `select`
|
|
34812
34812
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
34813
34813
|
*/
|
|
34814
|
-
async list(
|
|
34814
|
+
async list(path3, options, parameters) {
|
|
34815
34815
|
var _this13 = this;
|
|
34816
34816
|
return _this13.handleOperation(async () => {
|
|
34817
|
-
const body = _objectSpread22(_objectSpread22(_objectSpread22({}, DEFAULT_SEARCH_OPTIONS), options), {}, { prefix:
|
|
34817
|
+
const body = _objectSpread22(_objectSpread22(_objectSpread22({}, DEFAULT_SEARCH_OPTIONS), options), {}, { prefix: path3 || "" });
|
|
34818
34818
|
return await post(_this13.fetch, `${_this13.url}/object/list/${_this13.bucketId}`, body, { headers: _this13.headers }, parameters);
|
|
34819
34819
|
});
|
|
34820
34820
|
}
|
|
@@ -34879,11 +34879,11 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
34879
34879
|
if (typeof Buffer !== "undefined") return Buffer.from(data).toString("base64");
|
|
34880
34880
|
return btoa(data);
|
|
34881
34881
|
}
|
|
34882
|
-
_getFinalPath(
|
|
34883
|
-
return `${this.bucketId}/${
|
|
34882
|
+
_getFinalPath(path3) {
|
|
34883
|
+
return `${this.bucketId}/${path3.replace(/^\/+/, "")}`;
|
|
34884
34884
|
}
|
|
34885
|
-
_removeEmptyFolders(
|
|
34886
|
-
return
|
|
34885
|
+
_removeEmptyFolders(path3) {
|
|
34886
|
+
return path3.replace(/^\/|\/$/g, "").replace(/\/+/g, "/");
|
|
34887
34887
|
}
|
|
34888
34888
|
/** Modifies the `query`, appending values the from `transform` */
|
|
34889
34889
|
applyTransformOptsToQuery(query, transform2) {
|
|
@@ -37920,8 +37920,8 @@ function getErrorMap2() {
|
|
|
37920
37920
|
|
|
37921
37921
|
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
|
|
37922
37922
|
var makeIssue = (params) => {
|
|
37923
|
-
const { data, path:
|
|
37924
|
-
const fullPath = [...
|
|
37923
|
+
const { data, path: path3, errorMaps, issueData } = params;
|
|
37924
|
+
const fullPath = [...path3, ...issueData.path || []];
|
|
37925
37925
|
const fullIssue = {
|
|
37926
37926
|
...issueData,
|
|
37927
37927
|
path: fullPath
|
|
@@ -38037,11 +38037,11 @@ var errorUtil;
|
|
|
38037
38037
|
|
|
38038
38038
|
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js
|
|
38039
38039
|
var ParseInputLazyPath = class {
|
|
38040
|
-
constructor(parent, value,
|
|
38040
|
+
constructor(parent, value, path3, key) {
|
|
38041
38041
|
this._cachedPath = [];
|
|
38042
38042
|
this.parent = parent;
|
|
38043
38043
|
this.data = value;
|
|
38044
|
-
this._path =
|
|
38044
|
+
this._path = path3;
|
|
38045
38045
|
this._key = key;
|
|
38046
38046
|
}
|
|
38047
38047
|
get path() {
|
|
@@ -41830,7 +41830,7 @@ Drafting can be assisted by agents. Activation is a human decision. When authori
|
|
|
41830
41830
|
order: 40,
|
|
41831
41831
|
title: "Agent staffing playbook",
|
|
41832
41832
|
summary: "How to decide whether a seat should be human, agent, or hybrid, and how to go live safely.",
|
|
41833
|
-
version: "2026-06-
|
|
41833
|
+
version: "2026-06-21.2",
|
|
41834
41834
|
public: true,
|
|
41835
41835
|
audiences: ["human", "cli", "mcp", "in_app_agent"],
|
|
41836
41836
|
stages: ["staffing"],
|
|
@@ -41889,7 +41889,7 @@ Two creation paths, both draft-first. Read the stock-agents guide for templates
|
|
|
41889
41889
|
- Custom: \`agent_setup.start\` / \`rost_start_agent_setup\` (returns a \`setup_id\`), iterate with \`agent_setup.get\` and \`agent_setup.update\`, then \`agent.create_custom\` / \`rost_create_custom_agent\`. Stage tools with \`agent.configure_tools\` (vault refs only) and sandbox with \`agent.run_dry_run\`.
|
|
41890
41890
|
- Inspect runtime: \`agent.status\` / \`rost_get_agent_status\` with \`{"seat_id":"<seat-id>"}\` returns lane, live state, steward chain, dry-run result, and Runner availability.
|
|
41891
41891
|
- Run on demand: \`{{cli}} agent run-now --seat-id <seat-id>\` / \`agent.run_now\` / \`rost_run_agent_now\` queues an immediate live run without changing the saved schedule. Cloud agents dispatch to the Inngest executor; runner agents queue work for the paired runner. The command is ungated but still requires a live staffed agent and the normal server-side tool guard.
|
|
41892
|
-
- Audit what an agent did (Trust Card): \`{{cli}} command agent.list_runs --json '{"seat_id":"<seat-id>"}'\` / \`rost_list_agent_runs\` returns the seat's run history with per-run tool-call and guard-held counts; \`{{cli}} agent get-run --seat-id <seat-id> --run-id <run-id>\` / \`agent.get_run\` / \`rost_get_agent_run_diagnostics\` reads one run's transcript reference, token/cost usage, outcome,
|
|
41892
|
+
- Audit what an agent did (Trust Card): \`{{cli}} command agent.list_runs --json '{"seat_id":"<seat-id>"}'\` / \`rost_list_agent_runs\` returns the seat's run history with per-run Skill activation counts plus tool-call and guard-held counts; \`{{cli}} agent get-run --seat-id <seat-id> --run-id <run-id>\` / \`agent.get_run\` / \`rost_get_agent_run_diagnostics\` reads one run's transcript reference, token/cost usage, outcome, product-visible run errors, and any Skill versions/files loaded for that run. Loaded Skill file hashes and sizes identify the immutable source package; the runtime may still bound or truncate prompt text before sending it to the model. \`{{cli}} command agent.list_tool_calls --json '{"seat_id":"<seat-id>"}'\` / \`rost_list_agent_tool_calls\` returns the tool-call ledger with each call's guard result. Both list commands include a \`denied_tool_call_count\` rollup \u2014 the actions held because they exceeded the charter. Pass \`{"seat_id":"<seat-id>","held_only":true}\` to \`agent.list_tool_calls\` for only the held calls. The web seat page shows the same facts as a Trust Card.
|
|
41893
41893
|
|
|
41894
41894
|
## Review readiness before go-live
|
|
41895
41895
|
|
|
@@ -41910,11 +41910,11 @@ No orphan agents. No raw secrets in prompts, logs, or tool arguments. No durable
|
|
|
41910
41910
|
order: 41,
|
|
41911
41911
|
title: "Add agents to your Responsibility Graph",
|
|
41912
41912
|
summary: "The visual journey for adding an agent seat: where to start, choosing a mode, placing the seat, naming a Steward, setup, the safety gates, and go-live.",
|
|
41913
|
-
version: "2026-06-
|
|
41913
|
+
version: "2026-06-21.3",
|
|
41914
41914
|
public: true,
|
|
41915
41915
|
audiences: ["human", "in_app_agent"],
|
|
41916
41916
|
stages: ["staffing"],
|
|
41917
|
-
relatedCommandIds: ["agent_template.list", "agent_setup.start", "agent.create_from_template", "agent.create_custom", "agent.run_dry_run", "agent.go_live", "staffing.assign_user", "confirmation.approve"],
|
|
41917
|
+
relatedCommandIds: ["agent_template.list", "agent_setup.start", "agent.create_from_template", "agent.create_custom", "skill.list", "skill.catalog", "skill.check_dependencies", "skill.assign_to_seat", "agent.run_dry_run", "agent.go_live", "staffing.assign_user", "confirmation.approve"],
|
|
41918
41918
|
legal: { publicRisk: "low", notes: ["{{brand}}-native visual guidance for the agent-creation journey."] },
|
|
41919
41919
|
sources: [
|
|
41920
41920
|
{
|
|
@@ -41959,10 +41959,11 @@ The wizard builds a teammate, not a prompt:
|
|
|
41959
41959
|
|
|
41960
41960
|
1. **Responsibilities and authority** \u2014 what the seat owns, what it may do alone, what needs approval, and what must escalate. Every clause is editable before sign-off.
|
|
41961
41961
|
2. **Signals** \u2014 the measurables the seat is judged on.
|
|
41962
|
-
3. **
|
|
41963
|
-
4. **
|
|
41962
|
+
3. **Skills** \u2014 pin published, immutable Skill versions that the agent should carry. Skills are procedures, not authority: selecting one creates a proposed assignment and surfaces required/optional tool dependencies before sign-off.
|
|
41963
|
+
4. **Tools** \u2014 connect or decline each proposed tool. Declining a tool updates the permission manifest and the dry-run task so the agent stays safe. Credentials go in through write-only credential ingress and are stored as vault references, never shown again. Missing required Skill tools block sign-off, dry-run, and go-live until resolved; missing optional Skill tools warn without blocking.
|
|
41964
|
+
5. **Schedule and lane** \u2014 when the agent runs and on which lane. These stay advanced unless the mode needs them.
|
|
41964
41965
|
|
|
41965
|
-
You can save and resume a draft setup at any point. Returning to the flow restores the parent, Steward, mode, answers, tool decisions, and dry-run result.
|
|
41966
|
+
You can save and resume a draft setup at any point. Returning to the flow restores the parent, Steward, mode, answers, Skill selections, tool decisions, and dry-run result.
|
|
41966
41967
|
|
|
41967
41968
|
## The safety gates
|
|
41968
41969
|
|
|
@@ -41983,18 +41984,20 @@ Reopening the builder for a seat whose agent is already live shows its live stat
|
|
|
41983
41984
|
- Parent or Steward seat archived during setup: go-live is blocked until you choose a live parent or reassign the Steward.
|
|
41984
41985
|
- Failed dry run or a declined tool: the draft is preserved; fix the Charter or tool decision and rerun. See the troubleshooting guide.
|
|
41985
41986
|
|
|
41986
|
-
In read-only or demo mode the **Add agent** affordance never starts a write. The public demo instead replays the add-an-agent journey end to end \u2014 describe the role, watch the draft Charter assemble, see the four safety gates light, and watch a sandbox dry run reach the must-escalate boundary and stop \u2014 then routes go-live to sign-up, because going live is a human decision
|
|
41987
|
+
In read-only or demo mode the **Add agent** affordance never starts a write. The public demo instead replays the add-an-agent journey end to end \u2014 describe the role, watch the draft Charter assemble, see the four safety gates light, and watch a sandbox dry run reach the must-escalate boundary and stop \u2014 then routes go-live to sign-up, because going live is a human decision.
|
|
41988
|
+
|
|
41989
|
+
For CLI and MCP setup, read agent-skill-setup-guide before adding or assigning Skills. List existing company Skills and the {{brand}} catalog first, read the full Skill file before proposing it, and run the dependency check before sign-off. A missing required Skill tool is fixed by updating the Charter permission manifest through tool configuration; it is never fixed by treating the Skill as authorization.`
|
|
41987
41990
|
},
|
|
41988
41991
|
{
|
|
41989
41992
|
slug: "custom-agents-guide",
|
|
41990
41993
|
order: 42,
|
|
41991
41994
|
title: "Design a custom agent",
|
|
41992
41995
|
summary: "How to build a custom agent from operational questions through the Charter Builder, tools, dry run, and go-live without writing prompts.",
|
|
41993
|
-
version: "2026-06-
|
|
41996
|
+
version: "2026-06-21.1",
|
|
41994
41997
|
public: true,
|
|
41995
41998
|
audiences: ["human", "cli", "mcp", "in_app_agent"],
|
|
41996
41999
|
stages: ["staffing", "charter_design"],
|
|
41997
|
-
relatedCommandIds: ["agent_setup.start", "agent_setup.get", "agent_setup.update", "agent.create_custom", "agent.configure_tools", "agent.run_dry_run", "agent.go_live", "charter.draft", "charter.sign_manifest", "credential.ingress", "confirmation.approve"],
|
|
42000
|
+
relatedCommandIds: ["agent_setup.start", "agent_setup.get", "agent_setup.update", "agent.create_custom", "skill.list", "skill.catalog", "skill.get", "skill.file.get", "skill.check_dependencies", "skill.assign_to_seat", "agent.configure_tools", "agent.run_dry_run", "agent.go_live", "charter.draft", "charter.sign_manifest", "credential.ingress", "confirmation.approve"],
|
|
41998
42001
|
legal: { publicRisk: "low", notes: ["{{brand}}-native custom-agent guidance."] },
|
|
41999
42002
|
sources: [
|
|
42000
42003
|
{
|
|
@@ -42049,8 +42052,11 @@ The same path is command-backed:
|
|
|
42049
42052
|
1. \`agent_setup.start\` / \`rost_start_agent_setup\` with mode \`custom\` returns a \`setup_id\`.
|
|
42050
42053
|
2. Iterate with \`agent_setup.get\` and \`agent_setup.update\` (parent, Steward, lane, schedule, and the operational answers).
|
|
42051
42054
|
3. \`agent.create_custom\` / \`rost_create_custom_agent\` seeds a \`custom\` agent and a draft Charter from the operational answers only.
|
|
42052
|
-
4. \`
|
|
42053
|
-
5. \`
|
|
42055
|
+
4. Read \`skill.list\` / \`rost_list_skills\` and, when appropriate, \`skill.catalog\` / \`rost_list_rost_skill_catalog\`; inspect \`skill.get\` plus \`skill.file.get\` for the full \`SKILL.md\` before asking a tenant-admin or human operator to assign a Skill.
|
|
42056
|
+
5. Run \`skill.check_dependencies\` before assignment. Missing required tools are blockers for approval; optional tools are warnings. Resolve required blockers through \`agent.configure_tools\`, not by changing the Skill.
|
|
42057
|
+
6. A tenant-admin command caller can propose the Skill with \`skill.assign_to_seat\` / \`rost_assign_skill_to_seat\` after dependency checks; a seat-scoped agent escalates the assignment request instead of calling that command.
|
|
42058
|
+
7. \`agent.configure_tools\` / \`rost_configure_agent_tools\` records connect/decline decisions and credential-ingress requests (vault refs only).
|
|
42059
|
+
8. \`agent.run_dry_run\` / \`rost_run_agent_dry_run\` rehearses the task after the manifest is signed.
|
|
42054
42060
|
|
|
42055
42061
|
## Dry run and go-live
|
|
42056
42062
|
|
|
@@ -42139,7 +42145,7 @@ Decisions should be recorded as human decisions. Handoffs should attach to seats
|
|
|
42139
42145
|
order: 45,
|
|
42140
42146
|
title: "How agents work",
|
|
42141
42147
|
summary: "How {{brand}} agents operate inside seats, use Charters, report work, and escalate beyond authority.",
|
|
42142
|
-
version: "2026-06-
|
|
42148
|
+
version: "2026-06-21.3",
|
|
42143
42149
|
public: true,
|
|
42144
42150
|
audiences: ["human", "cli", "mcp", "in_app_agent"],
|
|
42145
42151
|
stages: ["staffing", "operating_rhythm"],
|
|
@@ -42231,7 +42237,7 @@ Before an agent goes live, the sandbox dry run rehearses this against fake data
|
|
|
42231
42237
|
|
|
42232
42238
|
## What humans should review
|
|
42233
42239
|
|
|
42234
|
-
The Agents page shows fleet health first: live state, recent runs, failed runs, open held actions, last activity, cost, and the next operator action. It also shows configuration completeness for each staffed agent seat: Steward chain, lane or runtime substrate, vaulted credentials, granted tools, model config, sandbox dry run, and go-live state, each with a remediation link when incomplete. A seat's Trust Card drills into the same facts: run history, one-run detail, tool-call outcomes, product-visible errors, transcript references, and held confirmations or escalations. Open confirmations stay visible until they are decided or expire, even when they are older than the default activity window. Approving or rejecting a held confirmation from the seat page is scoped to that seat; rejection can include a short reason.
|
|
42240
|
+
The Agents page shows fleet health first: live state, recent runs, failed runs, open held actions, last activity, cost, and the next operator action. It also shows configuration completeness for each staffed agent seat: Steward chain, lane or runtime substrate, vaulted credentials, granted tools, model config, sandbox dry run, and go-live state, each with a remediation link when incomplete. A seat's Trust Card drills into the same facts: run history, one-run detail, tool-call outcomes, product-visible errors, transcript references, loaded Skill versions, and held confirmations or escalations. Open confirmations stay visible until they are decided or expire, even when they are older than the default activity window. Approving or rejecting a held confirmation from the seat page is scoped to that seat; rejection can include a short reason.
|
|
42235
42241
|
|
|
42236
42242
|
Review the first dry runs, fleet overview, tool-call audit rows, escalations, deliverables, and Signal impact. A seat's completed-work area combines explicit deliverables, work-log evidence, and successful run summaries into one operator-facing trail with safe links labelled as internal, Linear, GitHub, or external. The fleet view at \`/agents\` shows every staffed agent seat at a glance; the agent-native equivalents are \`{{cli}} command agent.list_fleet --json '{}'\` / \`rost_list_agent_fleet\` for the compact overview, and \`{{cli}} agent fleet-digest --json\` / \`agent.fleet_digest\` / \`rost_get_dogfood_fleet_health_digest\` for the daily dogfood evidence bundle. The digest returns live/idle state, 24h/7d turns, 7d/30d spend, recent failed runs, unresolved product errors, failed notifications, and a next action per seat. Fleet real-turn counts use the same seat-run association as \`agent.list_runs\`, filtered to real runs. Scheduled agents are checked in rounded five-minute buckets, so a minute-level cron inside the bucket queues one work order for that bucket rather than one order per minute. Sandbox dry runs do not count as real turns. If the agent is repeatedly blocked, revise the Charter or split the seat. If the agent is taking too much judgment, narrow its autonomous scope.`
|
|
42237
42243
|
},
|
|
@@ -42325,7 +42331,7 @@ There is exactly one way to give a connected tool its credential, and it is the
|
|
|
42325
42331
|
order: 47,
|
|
42326
42332
|
title: "Available tools guide",
|
|
42327
42333
|
summary: "How to think about tool categories available to seats and what each category should be used for.",
|
|
42328
|
-
version: "2026-06-
|
|
42334
|
+
version: "2026-06-21.1",
|
|
42329
42335
|
public: true,
|
|
42330
42336
|
audiences: ["human", "cli", "mcp", "in_app_agent"],
|
|
42331
42337
|
stages: ["staffing"],
|
|
@@ -42378,7 +42384,7 @@ External connectors are being rolled out provider by provider, conservatively (r
|
|
|
42378
42384
|
order: 48,
|
|
42379
42385
|
title: "CLI and MCP installation guide",
|
|
42380
42386
|
summary: "Install the public CLI, register remote token-backed MCP clients, and find the full command and tool catalog.",
|
|
42381
|
-
version: "2026-06-
|
|
42387
|
+
version: "2026-06-21.10",
|
|
42382
42388
|
public: true,
|
|
42383
42389
|
audiences: ["human", "cli", "mcp", "in_app_agent"],
|
|
42384
42390
|
stages: ["company_setup", "staffing"],
|
|
@@ -42418,6 +42424,22 @@ External connectors are being rolled out provider by provider, conservatively (r
|
|
|
42418
42424
|
"agent.get_run",
|
|
42419
42425
|
"agent.list_runs",
|
|
42420
42426
|
"agent.list_tool_calls",
|
|
42427
|
+
"skill.list",
|
|
42428
|
+
"skill.catalog",
|
|
42429
|
+
"skill.enable_catalog",
|
|
42430
|
+
"skill.install_local",
|
|
42431
|
+
"skill.sync_local",
|
|
42432
|
+
"skill.get",
|
|
42433
|
+
"skill.file.get",
|
|
42434
|
+
"skill.assigned.list",
|
|
42435
|
+
"skill.check_dependencies",
|
|
42436
|
+
"skill.create",
|
|
42437
|
+
"skill.update_draft",
|
|
42438
|
+
"skill.import_github",
|
|
42439
|
+
"skill.import_upload",
|
|
42440
|
+
"skill.publish",
|
|
42441
|
+
"skill.assign_to_seat",
|
|
42442
|
+
"skill.revoke_from_seat",
|
|
42421
42443
|
"integration.list",
|
|
42422
42444
|
"integration.readiness",
|
|
42423
42445
|
"integration.status",
|
|
@@ -42544,7 +42566,7 @@ For CI, do not run an interactive device login on every job (a device code still
|
|
|
42544
42566
|
|
|
42545
42567
|
## First-run path
|
|
42546
42568
|
|
|
42547
|
-
This is the install/auth quickstart \u2014 it gets you logged in, MCP registered, and onboarding started. It is a convenience view, not the full org-setup procedure: for the canonical end-to-end setup order beyond install, \`agent-reference-map\` is the source of truth
|
|
42569
|
+
This is the install/auth quickstart \u2014 it gets you logged in, MCP registered, and onboarding started. It is a convenience view, not the full org-setup procedure: for the canonical end-to-end setup order beyond install, \`agent-reference-map\` is the source of truth. Read it with \`{{cli}} reference get agent-reference-map\` (step 6 below).
|
|
42548
42570
|
|
|
42549
42571
|
1. Log in: \`npx {{cliPackage}}@latest login\` (or \`{{cli}} login --device\` for a headless agent)
|
|
42550
42572
|
2. Confirm identity: \`{{cli}} whoami\`
|
|
@@ -42701,12 +42723,12 @@ A leaked tenant-admin token can administer the whole tenant, not just one seat.
|
|
|
42701
42723
|
|
|
42702
42724
|
### Storing the Anthropic key and other credentials
|
|
42703
42725
|
|
|
42704
|
-
Storing the tenant model key or any other secret goes through **credential ingress** as a vault reference \u2014 the secret is never pasted into a prompt, config, or log. Use \`rost_save_tenant_anthropic_key\` (\`tenant.anthropic_key.save\`) for the tenant Anthropic key, or \`rost_store_credential\` (\`credential.ingress\`) for other secrets; \`rost_configure_agent_tools\` stages credential requests but never accepts raw secrets. Credential storage is a gated \`credential_flow\` confirmation that a human approves. For the vault model and the security posture behind this, see the security-model-guide and the tool-access-and-vault guide; for the confirmation gate, see the confirmations-guide.
|
|
42726
|
+
Storing the tenant model key or any other secret goes through **credential ingress** as a vault reference \u2014 the secret is never pasted into a prompt, config, or log. Use \`rost_save_tenant_anthropic_key\` (\`tenant.anthropic_key.save\`) for the tenant Anthropic key, or \`rost_store_credential\` (\`credential.ingress\`) for other secrets; \`rost_configure_agent_tools\` stages credential requests but never accepts raw secrets. Credential storage is a gated \`credential_flow\` confirmation that a human approves. For the vault model and the security posture behind this, see the security-model-guide and the tool-access-and-vault guide; for model-bound data, BYOK provider handling, and local-client provider settings, see the ai-model-data-handling-guide; for the confirmation gate, see the confirmations-guide.
|
|
42705
42727
|
|
|
42706
42728
|
## When to use MCP or CLI
|
|
42707
42729
|
|
|
42708
42730
|
- A technical operator wants to drive onboarding from a local agent session.
|
|
42709
|
-
- A partner wants to use their own local model subscription.
|
|
42731
|
+
- A partner wants to use their own local model subscription. Read the ai-model-data-handling-guide first so the operator can verify the local provider account, retention, telemetry, and transcript settings instead of assuming {{brand}} controls them.
|
|
42710
42732
|
- A Steward wants a local agent to inspect context, draft changes, or prepare work.
|
|
42711
42733
|
- A developer wants repeatable setup commands.
|
|
42712
42734
|
|
|
@@ -42784,6 +42806,8 @@ Ergonomic subcommands for everyday operation. Each wrapper is sugar over the sam
|
|
|
42784
42806
|
|
|
42785
42807
|
These ergonomic wrappers (including the \`{{cli}} agent\` group) require **{{cli}} 0.2.0 or newer** \u2014 run \`npx {{cliPackage}}@latest \u2026\` to get them. Older versions can still reach every command through the \`{{cli}} command <id> --json\` floor, since command execution is server-side.
|
|
42786
42808
|
|
|
42809
|
+
The signed-in app exposes the same Skill command surface under **Skills** in the left sidebar. Use \`/skills\` to filter the tenant library, \`/skills/new\` to build canonical \`SKILL.md\` frontmatter with \`tool.catalog\` dependencies, \`/skills/import\` for bounded GitHub or upload imports, and each Skill detail page to review validation, publish, check Seat dependencies, and assign a published version. During \`/agents/new\`, \`agent_setup.get\` can return \`next_action: "choose_skills"\`; selected Skills are proposed immutable-version assignments and required Skill tools block sign-off/go-live until tool configuration is ready.
|
|
42810
|
+
|
|
42787
42811
|
| Command | Command ids | Purpose | Scope | Safe example |
|
|
42788
42812
|
|---|---|---|---|---|
|
|
42789
42813
|
| \`{{cli}} task list|accept|decline|complete|create\` | \`task.list\`, \`task.accept\`, \`task.decline\`, \`task.complete\`, \`task.create\` | Operate a seat's task queue. | Seat | \`{{cli}} task list --json\` |
|
|
@@ -42798,14 +42822,34 @@ These ergonomic wrappers (including the \`{{cli}} agent\` group) require **{{cli
|
|
|
42798
42822
|
| \`{{cli}} integration list|readiness|status|test\` | \`integration.list\`, \`integration.readiness\`, \`integration.status\`, \`integration.test\` | List connector metadata, read the setup-readiness checklist, read one connector's health, and run the provider-specific connection test without exposing credentials. | Tenant | \`{{cli}} integration readiness --provider google --json\` |
|
|
42799
42823
|
| \`{{cli}} settings get|update\` | \`settings.get\`, \`settings.update\` | Read tenant settings; update budget caps. | Tenant | \`{{cli}} settings get --json\` |
|
|
42800
42824
|
| \`{{cli}} member invite|update|remove\` | \`member.invite\`, \`member.update\`, \`member.remove\` | Manage tenant members. | Tenant | \`{{cli}} member invite --email ops@example.com --role member\` |
|
|
42801
|
-
| \`{{cli}} agent templates|create|setup|tools|dry-run|go-live|status|run-now|fleet-digest|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.fleet_digest\`, \`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, capture the fleet-health digest, 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 fleet-digest --json\` |
|
|
42825
|
+
| \`{{cli}} agent templates|create|setup|tools|dry-run|go-live|status|run-now|fleet-digest|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.fleet_digest\`, \`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, capture the fleet-health digest, read one run's transcript/error diagnostics, and show a markdown readout. Human CLI dry-runs print the rehearsal transcript and, when present, the per-tool preview labels (\`Would run\`, \`Blocked\`, \`Escalated\`) before go-live. 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 fleet-digest --json\` |
|
|
42802
42826
|
| \`{{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\` |
|
|
42803
|
-
| \`{{cli}} skills list|get|file|assigned|check-dependencies\` | \`skill.list\`, \`skill.get\`, \`skill.file.get\`, \`skill.assigned.list\`, \`skill.check_dependencies\` | Discover reusable Skills, read descriptors and stored package files, list approved Seat assignments, and compare required/optional tool dependencies with a Seat's signed Charter manifest. Skills are instructions, not authority. | Tenant
|
|
42804
|
-
| \`{{cli}} skills
|
|
42827
|
+
| \`{{cli}} skills list|get|file|assigned|check-dependencies\` | \`skill.list\`, \`skill.get\`, \`skill.file.get\`, \`skill.assigned.list\`, \`skill.check_dependencies\` | Discover reusable Skills, read descriptors and stored package files, list approved Seat assignments, and compare required/optional tool dependencies with a Seat's signed Charter manifest. Skills are instructions, not authority. | Tenant-admin; seat-scoped reads for assigned Skills | \`{{cli}} skills list --json\`; \`{{cli}} skills file --slug invoice-review --path SKILL.md\` |
|
|
42828
|
+
| \`{{cli}} skills catalog|enable|install|sync\` | \`skill.catalog\`, \`skill.enable_catalog\`, \`skill.install_local\`, \`skill.sync_local\` | Discover entitled {{brand}} catalog Skills, enable a catalog Skill into the company library with human confirmation, and install or sync approved Skill files locally from {{brand}} APIs. Private catalog source URLs and GitHub tokens never go to local agents. | Tenant-admin for catalog enablement; seat-scoped sync for assigned Skills | \`{{cli}} skills sync --seat-id <id> --client codex\`; \`{{cli}} skills install rost/ap-review --seat-id <id> --client codex\` |
|
|
42829
|
+
| \`{{cli}} skills create|update-draft|import|publish|assign|revoke\` | \`skill.create\`, \`skill.update_draft\`, \`skill.import_github\`, \`skill.import_upload\`, \`skill.publish\`, \`skill.assign_to_seat\`, \`skill.revoke_from_seat\` | Create or import bounded text Skill packages, publish reviewed immutable versions, propose Seat assignments, and revoke future use without deleting historical activations. Publish, revoke, and approved assignment stop at human confirmation; blocked required tools cannot be approved. | Tenant-admin writes; seat agents read assignments and escalate requests | \`{{cli}} skills import github --url https://github.com/acme/skills/tree/main/ap --json\`; \`{{cli}} skills assign --seat-id <id> --slug invoice-review --json\` |
|
|
42805
42830
|
| \`{{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\` |
|
|
42806
42831
|
| \`{{cli}} compass show\` | \`compass.show_markdown\` | Render the current Compass as a clean markdown card for review. | Tenant | \`{{cli}} compass show --markdown\` |
|
|
42807
42832
|
| \`{{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\` |
|
|
42808
42833
|
|
|
42834
|
+
Skills wrapper help:
|
|
42835
|
+
|
|
42836
|
+
\`\`\`text
|
|
42837
|
+
{{cli}} skills list [--json]
|
|
42838
|
+
{{cli}} skills catalog [--json]
|
|
42839
|
+
{{cli}} skills get --slug <slug> [--json]
|
|
42840
|
+
{{cli}} skills file --slug <slug> --path SKILL.md
|
|
42841
|
+
{{cli}} skills enable rost/<slug> [--json]
|
|
42842
|
+
{{cli}} skills install <slug-or-rost/slug> [--seat-id <id>] [--client claude-code|codex|cursor] [--version <n>] [--local-only] [--json]
|
|
42843
|
+
{{cli}} skills sync --seat-id <id> [--client claude-code|codex|cursor] [--json]
|
|
42844
|
+
{{cli}} skills assign --seat-id <id> (--skill <slug>|--slug <slug>|--skill-version-id <id>) [--approve] [--allow-blocked-proposal] [--json]
|
|
42845
|
+
{{cli}} skills revoke (--assignment-id <id>|--seat-id <id> --skill <slug>) [--json]
|
|
42846
|
+
{{cli}} skills publish (--slug <slug>|--skill-version-id <id>) [--allow-warnings] [--json]
|
|
42847
|
+
\`\`\`
|
|
42848
|
+
|
|
42849
|
+
\`{{cli}} skills install\` writes into the client Skills directory and records \`.rost-skill.json\` with \`skill_version_id\`, \`content_sha256\`, source, client, and \`installed_from: "rost_api"\`. Set \`ROST_SKILL_INSTALL_ROOT\` to override the local root in CI or a sandbox. Use \`install\` for one Skill and \`sync\` as the default local-agent command because it installs every approved Skill assigned to the Seat and skips unchanged local copies by hash. Entitlement failures mean the tenant cannot access that {{brand}} catalog tier yet; stale local copies are fixed by rerunning \`sync\`; private catalog access is always served by {{brand}} APIs, not by giving the agent a private GitHub credential.
|
|
42850
|
+
|
|
42851
|
+
{{brand}}-maintained catalog entries are seeded from first-party Skill packages with stable content hashes, application descriptors, and declared required or optional tool dependencies. Catalog seed validation is fail-closed: a package with parser warnings is not published. Enabling a catalog Skill copies the current immutable version into the company library; later catalog refreshes update the global catalog row but do not silently rewrite already-enabled tenant Skill versions.
|
|
42852
|
+
|
|
42809
42853
|
### MCP registration
|
|
42810
42854
|
|
|
42811
42855
|
| Command | Purpose | Scope | Safe example |
|
|
@@ -42902,8 +42946,8 @@ Several rows here are seat-operating commands (\`task.create\`, the \`signal.*\`
|
|
|
42902
42946
|
| \`rost_list_agent_fleet\` | \`agent.list_fleet\` | Read every staffed agent seat at once: lane, live state, last real turn, 24h/7d real turns, measurable status, escalations, and 7-day spend. | Tenant | Call with \`{}\`; counts use the same seat-run association as \`agent.list_runs\`, with sandbox dry runs excluded from real turns. |
|
|
42903
42947
|
| \`rost_get_dogfood_fleet_health_digest\` | \`agent.fleet_digest\` | Capture the daily dogfood fleet-health digest: live/idle state, 24h/7d turns, spend, recent failed runs, unresolved errors, failed notifications, and next actions. | Tenant | Call with \`{}\`; optional \`window_hours\` bounds recent failed-run evidence, while \`error_limit\` caps linked evidence per seat. |
|
|
42904
42948
|
| \`rost_run_agent_now\` | \`agent.run_now\` | Queue an immediate run for a live staffed agent without changing its saved schedule; cloud lane dispatches to the executor and runner lane queues for the paired runner. | Tenant | Call with \`{"seat_id":"<seat-id>"}\`. |
|
|
42905
|
-
| \`rost_list_agent_runs\` | \`agent.list_runs\` | Read a seat's agent run history (status, lane, model, cost, per-run tool-call and guard-held counts) plus the seat's run/tool-call rollup including held-action count. | Seat or tenant-admin | Call with \`{"seat_id":"<seat-id>"}\`; pass \`limit\` for a deeper window. |
|
|
42906
|
-
| \`rost_get_agent_run_diagnostics\` | \`agent.get_run\` | Read one run's diagnostic record: transcript reference, token/cost usage, outcome,
|
|
42949
|
+
| \`rost_list_agent_runs\` | \`agent.list_runs\` | Read a seat's agent run history (status, lane, model, cost, per-run Skill activation, tool-call, and guard-held counts) plus the seat's run/tool-call rollup including held-action count. | Seat or tenant-admin | Call with \`{"seat_id":"<seat-id>"}\`; pass \`limit\` for a deeper window. |
|
|
42950
|
+
| \`rost_get_agent_run_diagnostics\` | \`agent.get_run\` | Read one run's diagnostic record: transcript reference, token/cost usage, outcome, linked product-visible run errors, and loaded Skill activation file metadata. File hashes/sizes identify the immutable source package, while model prompt text may be bounded or truncated. | Seat or tenant-admin | Call with \`{"seat_id":"<seat-id>","run_id":"<run-id>"}\`. |
|
|
42907
42951
|
| \`rost_list_agent_tool_calls\` | \`agent.list_tool_calls\` | Read a seat's tool-call ledger (tool name, guard result, manifest clause, outcome) with the held-action count as the hero metric. Never returns argument summaries or secret material. | Seat or tenant-admin | Call with \`{"seat_id":"<seat-id>"}\`; pass \`held_only: true\` for only guard-held calls. |
|
|
42908
42952
|
| \`rost_list_agent_templates\` | \`agent_template.list\` | List stock agent templates and metadata. | Tenant | Call with \`{}\`. |
|
|
42909
42953
|
| \`rost_create_agent_from_template\` | \`agent.create_from_template\` | Create a draft stock agent and draft Charter from a template (draft-only; occupancy needs a human steward). | Tenant | Call with \`seat_id\` and \`template_slug\`; expect human confirmation. |
|
|
@@ -42968,6 +43012,10 @@ Several rows here are seat-operating commands (\`task.create\`, the \`signal.*\`
|
|
|
42968
43012
|
| \`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>"}\`. |
|
|
42969
43013
|
| \`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"}\`. |
|
|
42970
43014
|
| \`rost_list_skills\` | \`skill.list\` | List tenant Skills with application descriptors, dependency metadata, source status, latest version, and assigned Seat count. Seat-scoped reads are available through \`rost://skills\`. | Tenant-admin | Call with \`{}\` or \`{"query":"invoice"}\`. |
|
|
43015
|
+
| \`rost_list_rost_skill_catalog\` | \`skill.catalog\` | List entitled {{brand}} catalog Skills. Private catalog source URLs and credentials stay server-side. | Tenant-admin | Call with \`{}\`; use \`{"include_unentitled":true}\` only to inspect tier availability. |
|
|
43016
|
+
| \`rost_enable_rost_catalog_skill\` | \`skill.enable_catalog\` | Enable an entitled {{brand}} catalog Skill into the company library with human confirmation. | Tenant-admin | Call with \`{"slug":"rost/ap-review"}\`; non-interactive callers receive a confirmation handoff. |
|
|
43017
|
+
| \`rost_install_skill_locally\` | \`skill.install_local\` | Resolve company or entitled {{brand}} catalog Skill files from {{brand}} APIs for a local client install. It returns package files and metadata, not private GitHub URLs. | Tenant-admin | Call with \`{"slug":"invoice-review","client":"codex"}\`; \`rost/<slug>\` enablement may require confirmation. |
|
|
43018
|
+
| \`rost_sync_assigned_skills_locally\` | \`skill.sync_local\` | Resolve every approved Skill assigned to a Seat plus revoked local-copy markers for a local client sync. | Tenant-admin | Call with \`{"seat_id":"<seat-id>","client":"codex"}\`; local clients remove revoked copies. |
|
|
42971
43019
|
| \`rost_get_skill\` | \`skill.get\` | Read one Skill descriptor and latest stored version metadata. Seat-scoped reads are available through \`rost://skills/{slug}\`. | Tenant-admin | Call with \`{"slug":"invoice-review"}\`. |
|
|
42972
43020
|
| \`rost_get_skill_file\` | \`skill.file.get\` | Read stored Skill package file content by slug and package path; paths resolve only inside the stored package payload. Seat-scoped reads are available through \`rost://skills/{slug}/files/{path}\`. | Tenant-admin | Call with \`{"slug":"invoice-review","path":"SKILL.md"}\`. |
|
|
42973
43021
|
| \`rost_list_assigned_skills\` | \`skill.assigned.list\` | List approved Skill assignments for a Seat, including immutable version, dependency status, rationale, and approval time. Seat-scoped reads are available through \`rost://seat/{id}/skills\`. | Tenant-admin | Call with \`{"seat_id":"<seat-id>"}\`. |
|
|
@@ -43037,11 +43085,285 @@ These rows are quick, at-a-glance triage. For deeper auth, tenant, scope, confir
|
|
|
43037
43085
|
`
|
|
43038
43086
|
},
|
|
43039
43087
|
{
|
|
43040
|
-
slug: "
|
|
43088
|
+
slug: "skill-builder-guide",
|
|
43041
43089
|
order: 49,
|
|
43090
|
+
title: "Skill builder guide",
|
|
43091
|
+
summary: "Create, import, review, publish, and assign reusable Skills without confusing procedures with authority.",
|
|
43092
|
+
version: "2026-06-21.1",
|
|
43093
|
+
public: true,
|
|
43094
|
+
audiences: ["human", "cli", "mcp", "in_app_agent"],
|
|
43095
|
+
stages: ["staffing", "operating_rhythm"],
|
|
43096
|
+
relatedCommandIds: ["skill.list", "skill.catalog", "skill.get", "skill.file.get", "skill.create", "skill.update_draft", "skill.import_github", "skill.import_upload", "skill.publish", "skill.check_dependencies", "skill.assign_to_seat", "skill.revoke_from_seat", "agent.configure_tools", "confirmation.approve"],
|
|
43097
|
+
legal: { publicRisk: "low", notes: ["Public guidance for tenant-authored and imported Skills."] },
|
|
43098
|
+
sources: [
|
|
43099
|
+
{
|
|
43100
|
+
label: "Agent Skills implementation plan",
|
|
43101
|
+
internalPath: "docs/specs/agent-skills-implementation-plan.md",
|
|
43102
|
+
note: "Defines the Skills product boundary, governance model, and setup workflow."
|
|
43103
|
+
}
|
|
43104
|
+
],
|
|
43105
|
+
body: `# Skill builder guide
|
|
43106
|
+
|
|
43107
|
+
Skills are reusable procedure packages. Use them for repeatable work patterns, domain-specific output contracts, local or client workflow setup, examples, templates, and company-standard operating routines.
|
|
43108
|
+
|
|
43109
|
+
Skills are not authority. A Skill cannot grant a tool, approve a payment, change a Charter, store a secret, or bypass a human confirmation. The Charter, signed permission manifest, and server-side tool guard remain the control plane.
|
|
43110
|
+
|
|
43111
|
+
## When to add a Skill
|
|
43112
|
+
|
|
43113
|
+
Add a Skill when the procedure will be reused by more than one task or run:
|
|
43114
|
+
|
|
43115
|
+
- A standard operating procedure such as AP exception review, weekly sync health checks, or support triage.
|
|
43116
|
+
- A required output contract such as named sections, evidence fields, or review checklist order.
|
|
43117
|
+
- A local-agent setup pattern that must be installed into Codex, Claude Code, or another client.
|
|
43118
|
+
- A reusable template, example, or evaluation fixture that helps agents produce consistent work.
|
|
43119
|
+
|
|
43120
|
+
Do not add a Skill for authorization, secrets, one-off task context, temporary preferences, or rules that belong in the Charter. Put durable authority, must-escalate boundaries, and tool permissions in the Charter and permission manifest.
|
|
43121
|
+
|
|
43122
|
+
## Package shape
|
|
43123
|
+
|
|
43124
|
+
Every package has a \`SKILL.md\` file and may include bounded support files under \`references/\`, \`templates/\`, \`examples/\`, \`evals/\`, or \`scripts/\`. The frontmatter should define:
|
|
43125
|
+
|
|
43126
|
+
- \`application\`: a short summary, when to use the Skill, and when not to use it.
|
|
43127
|
+
- \`required_tools\`: tool ids and minimum scope tiers that must exist before an approved assignment can be used safely.
|
|
43128
|
+
- \`optional_tools\`: useful tools that produce warnings when absent but do not block assignment.
|
|
43129
|
+
|
|
43130
|
+
Use tool ids from \`tool.catalog\` / \`rost_list_tool_catalog\`. Required and optional tool entries are dependency declarations only; they never grant access.
|
|
43131
|
+
|
|
43132
|
+
## Create or import
|
|
43133
|
+
|
|
43134
|
+
Use the shared command path from the app, CLI, or tenant-admin MCP:
|
|
43135
|
+
|
|
43136
|
+
- Create: \`skill.create\` / \`rost_create_skill\` with a bounded text package.
|
|
43137
|
+
- Update a draft: \`skill.update_draft\` / \`rost_update_skill_draft\`.
|
|
43138
|
+
- Import public GitHub: \`skill.import_github\` / \`rost_import_github_skill\`; {{brand}} records source URL, resolved ref, path, and content hash.
|
|
43139
|
+
- Import uploaded text: \`skill.import_upload\` / \`rost_import_uploaded_skill\`; MCP accepts structured text packages, not direct binary uploads.
|
|
43140
|
+
|
|
43141
|
+
Imported Skills are untrusted until parsed, scanned, validated, and reviewed. Validation warnings should be fixed before publication.
|
|
43142
|
+
|
|
43143
|
+
## Review and publish
|
|
43144
|
+
|
|
43145
|
+
Publishing creates an immutable Skill version. Later edits create a new version; they do not rewrite what a prior agent run used. \`skill.publish\` is human-gated. Agent actors may draft or import, but they do not approve publication.
|
|
43146
|
+
|
|
43147
|
+
Review before publishing:
|
|
43148
|
+
|
|
43149
|
+
- The procedure is reusable and bounded.
|
|
43150
|
+
- It contains no secrets, keys, private tokens, or raw credential material.
|
|
43151
|
+
- Required tools are truly required; optional tools are not blockers.
|
|
43152
|
+
- The output contract does not ask the agent to exceed the Charter.
|
|
43153
|
+
- Support files are necessary and small enough to load safely.
|
|
43154
|
+
|
|
43155
|
+
## Assign to a Seat
|
|
43156
|
+
|
|
43157
|
+
Assignment pins a published immutable version to a Seat. Run \`skill.check_dependencies\` before \`skill.assign_to_seat\`.
|
|
43158
|
+
|
|
43159
|
+
Dependency results mean:
|
|
43160
|
+
|
|
43161
|
+
- \`ready\`: required tools meet the Skill's minimum scope tiers.
|
|
43162
|
+
- \`blocked\`: at least one required tool is missing, declined, or under-scoped. Approval is blocked.
|
|
43163
|
+
- \`warning\`: optional tools are missing or under-scoped. Assignment can proceed, but the operator should understand the degraded path.
|
|
43164
|
+
|
|
43165
|
+
Fix blockers by updating the Seat's Charter permission manifest through \`agent.configure_tools\` and human sign-off. Do not edit the Skill to pretend authorization exists.
|
|
43166
|
+
|
|
43167
|
+
## {{brand}} catalog and local install
|
|
43168
|
+
|
|
43169
|
+
The {{brand}} catalog is first-party, entitlement-filtered, and private-source-safe. Use \`skill.catalog\` to list entitled catalog Skills, then \`skill.enable_catalog\` to copy an entitled catalog Skill into the company library with human confirmation. Standard tenants do not see private beta catalog entries unless explicitly entitled.
|
|
43170
|
+
|
|
43171
|
+
Use \`skill.install_local\` for one Skill and \`skill.sync_local\` for all approved Skills assigned to a Seat. Local clients receive package files and \`.rost-skill.json\` metadata from {{brand}} APIs; private catalog GitHub URLs, signed URLs, and credentials are not returned.`
|
|
43172
|
+
},
|
|
43173
|
+
{
|
|
43174
|
+
slug: "agent-skill-authoring-guide",
|
|
43175
|
+
order: 50,
|
|
43176
|
+
title: "Agent Skill authoring guide",
|
|
43177
|
+
summary: "How CLI and MCP agents should propose reusable Skills safely.",
|
|
43178
|
+
version: "2026-06-21.2",
|
|
43179
|
+
public: true,
|
|
43180
|
+
audiences: ["cli", "mcp", "in_app_agent"],
|
|
43181
|
+
stages: ["staffing", "operating_rhythm"],
|
|
43182
|
+
relatedCommandIds: ["skill.list", "skill.get", "skill.file.get", "skill.create", "skill.update_draft", "skill.import_github", "skill.import_upload", "skill.publish", "tool.catalog", "confirmation.approve"],
|
|
43183
|
+
legal: { publicRisk: "low", notes: ["Machine-facing authoring guidance for safe Skill creation."] },
|
|
43184
|
+
sources: [
|
|
43185
|
+
{
|
|
43186
|
+
label: "Agent Skills implementation plan",
|
|
43187
|
+
internalPath: "docs/specs/agent-skills-implementation-plan.md",
|
|
43188
|
+
note: "Defines agent-facing authoring constraints and safety boundaries."
|
|
43189
|
+
}
|
|
43190
|
+
],
|
|
43191
|
+
body: `# Agent Skill authoring guide
|
|
43192
|
+
|
|
43193
|
+
Use this guide when you are a CLI or MCP agent asked to create, import, or revise a Skill.
|
|
43194
|
+
|
|
43195
|
+
## First, check what already exists
|
|
43196
|
+
|
|
43197
|
+
Do not create a duplicate procedure. Before authoring:
|
|
43198
|
+
|
|
43199
|
+
1. Read \`agent-reference-map\`.
|
|
43200
|
+
2. Run \`skill.list\` / \`rost_list_skills\` and search by the job words.
|
|
43201
|
+
3. If the procedure may be first-party, run \`skill.catalog\` / \`rost_list_rost_skill_catalog\`.
|
|
43202
|
+
4. Read matching descriptors with \`skill.get\` and the full file with \`skill.file.get\`.
|
|
43203
|
+
|
|
43204
|
+
If an existing Skill is close, propose an update draft or assignment instead of a new Skill.
|
|
43205
|
+
|
|
43206
|
+
## Decide whether a Skill is appropriate
|
|
43207
|
+
|
|
43208
|
+
Create a Skill for repeatable procedures, domain-specific output contracts, local/client setup patterns, reusable examples, and company operating standards.
|
|
43209
|
+
|
|
43210
|
+
Do not create a Skill for:
|
|
43211
|
+
|
|
43212
|
+
- Authorization or tool access.
|
|
43213
|
+
- Secrets, credentials, API keys, or vault refs.
|
|
43214
|
+
- One-off evidence that belongs on the task.
|
|
43215
|
+
- Temporary style preferences.
|
|
43216
|
+
- Charter rules, escalation boundaries, or human decision policy.
|
|
43217
|
+
|
|
43218
|
+
If the user asks for authority, update the Charter path. If the user gives one-off evidence, keep it in the task context.
|
|
43219
|
+
|
|
43220
|
+
## Authoring checklist
|
|
43221
|
+
|
|
43222
|
+
The \`SKILL.md\` body should be short, procedural, and testable. Include:
|
|
43223
|
+
|
|
43224
|
+
- A clear title.
|
|
43225
|
+
- An \`application.summary\` that says when to use it.
|
|
43226
|
+
- \`application.not_for\` for risky or out-of-scope cases.
|
|
43227
|
+
- Required and optional tools only when the procedure genuinely needs them.
|
|
43228
|
+
- An output contract when consistency matters.
|
|
43229
|
+
- Missing-evidence behavior: state what is missing instead of guessing.
|
|
43230
|
+
|
|
43231
|
+
Use \`tool.catalog\` before naming a tool. Required tool scope tiers must be the minimum useful scope. Optional tools are for improved delivery, not hidden blockers.
|
|
43232
|
+
|
|
43233
|
+
## Safe command path
|
|
43234
|
+
|
|
43235
|
+
- Draft: \`skill.create\` or \`skill.update_draft\`.
|
|
43236
|
+
- Public GitHub import: \`skill.import_github\` with the URL, ref, and package path.
|
|
43237
|
+
- Uploaded text import: \`skill.import_upload\`.
|
|
43238
|
+
- Publish: \`skill.publish\` returns a human confirmation. Stop and ask the human to approve or reject.
|
|
43239
|
+
|
|
43240
|
+
Never approve your own publication. Never paste secrets into \`SKILL.md\`, support files, command JSON, issue comments, or logs.
|
|
43241
|
+
|
|
43242
|
+
## Quality bar
|
|
43243
|
+
|
|
43244
|
+
Before handing off, say what the Skill is for, why it is reusable, what tools it depends on, and what human gate remains. If validation warnings exist, fix them or call them out as blockers.`
|
|
43245
|
+
},
|
|
43246
|
+
{
|
|
43247
|
+
slug: "agent-skill-setup-guide",
|
|
43248
|
+
order: 51,
|
|
43249
|
+
title: "Agent Skill setup guide",
|
|
43250
|
+
summary: "CLI and MCP recipes for discovering, reading, dependency-checking, assigning, and locally syncing Skills.",
|
|
43251
|
+
version: "2026-06-21.1",
|
|
43252
|
+
public: true,
|
|
43253
|
+
audiences: ["cli", "mcp", "in_app_agent"],
|
|
43254
|
+
stages: ["staffing", "operating_rhythm"],
|
|
43255
|
+
relatedCommandIds: ["skill.list", "skill.catalog", "skill.enable_catalog", "skill.get", "skill.file.get", "skill.assigned.list", "skill.check_dependencies", "skill.install_local", "skill.sync_local", "skill.import_github", "skill.import_upload", "skill.assign_to_seat", "agent.configure_tools", "confirmation.approve"],
|
|
43256
|
+
legal: { publicRisk: "low", notes: ["Machine-facing setup recipes for Skills over CLI and MCP."] },
|
|
43257
|
+
sources: [
|
|
43258
|
+
{
|
|
43259
|
+
label: "Agent Skills implementation plan",
|
|
43260
|
+
internalPath: "docs/specs/agent-skills-implementation-plan.md",
|
|
43261
|
+
note: "Defines CLI/MCP setup sequence, dependency handling, and local sync behavior."
|
|
43262
|
+
}
|
|
43263
|
+
],
|
|
43264
|
+
body: `# Agent Skill setup guide
|
|
43265
|
+
|
|
43266
|
+
Use this guide before creating, enabling, assigning, or locally installing Skills from CLI or MCP.
|
|
43267
|
+
|
|
43268
|
+
## Setup sequence
|
|
43269
|
+
|
|
43270
|
+
1. Read \`agent-reference-map\`.
|
|
43271
|
+
2. List company Skills: \`skill.list\` / \`rost_list_skills\` or read \`rost://skills\`.
|
|
43272
|
+
3. List {{brand}} catalog Skills when needed: \`skill.catalog\` / \`rost_list_rost_skill_catalog\`.
|
|
43273
|
+
4. Read descriptors: \`skill.get\` / \`rost_get_skill\` or \`rost://skills/{slug}\`.
|
|
43274
|
+
5. Read full files before assignment: \`skill.file.get\` / \`rost_get_skill_file\` or \`rost://skills/{slug}/files/SKILL.md\`.
|
|
43275
|
+
6. Check dependencies for the target Seat: \`skill.check_dependencies\` / \`rost_check_skill_dependencies\`.
|
|
43276
|
+
7. Tenant-admin command callers propose assignment with \`skill.assign_to_seat\` / \`rost_assign_skill_to_seat\`; seat-scoped agents read assigned Skills and escalate assignment requests to a human or tenant-admin.
|
|
43277
|
+
8. After approval, list assignments with \`skill.assigned.list\` or \`rost://seat/{id}/skills\`.
|
|
43278
|
+
9. For local clients, run \`skill.sync_local\` / \`rost_sync_assigned_skills_locally\`.
|
|
43279
|
+
|
|
43280
|
+
Tenant-admin command callers may propose assignments; seat-scoped agents escalate assignment requests. Humans approve publication, approved assignment, revocation, and Charter or manifest changes.
|
|
43281
|
+
|
|
43282
|
+
## Attach an existing company Skill to a new Seat
|
|
43283
|
+
|
|
43284
|
+
Tenant-admin CLI:
|
|
43285
|
+
|
|
43286
|
+
\`\`\`bash
|
|
43287
|
+
{{cli}} skills list --json
|
|
43288
|
+
{{cli}} skills get --slug invoice-review --json
|
|
43289
|
+
{{cli}} skills file --slug invoice-review --path SKILL.md
|
|
43290
|
+
{{cli}} skills check-dependencies --seat-id <seat-id> --slug invoice-review --json
|
|
43291
|
+
{{cli}} skills assign --seat-id <seat-id> --slug invoice-review --rationale "Use for AP exception work." --json
|
|
43292
|
+
\`\`\`
|
|
43293
|
+
|
|
43294
|
+
Tenant-admin MCP:
|
|
43295
|
+
|
|
43296
|
+
1. Call \`rost_list_skills\` with \`{}\`.
|
|
43297
|
+
2. Call \`rost_get_skill\` and \`rost_get_skill_file\`.
|
|
43298
|
+
3. Call \`rost_check_skill_dependencies\` with \`{"seat_id":"<seat-id>","slug":"invoice-review"}\`.
|
|
43299
|
+
4. If ready, call \`rost_assign_skill_to_seat\` with \`status:"proposed"\`.
|
|
43300
|
+
|
|
43301
|
+
Seat-scoped MCP agents cannot call generated Skill assignment tools. They should read \`rost://seat/{id}/skills\`, read relevant assigned files through \`rost://skills/{slug}/files/{path}\`, and escalate when a new assignment or permission change is needed.
|
|
43302
|
+
|
|
43303
|
+
If required tools are blocked, call \`rost_configure_agent_tools\` only when the human wants to amend the permission manifest. Then wait for the normal Charter/tool approval path.
|
|
43304
|
+
|
|
43305
|
+
## Enable a {{brand}} catalog Skill and assign it
|
|
43306
|
+
|
|
43307
|
+
CLI:
|
|
43308
|
+
|
|
43309
|
+
\`\`\`bash
|
|
43310
|
+
{{cli}} skills catalog --json
|
|
43311
|
+
{{cli}} skills enable rost/ap-exception-brief --json
|
|
43312
|
+
{{cli}} skills check-dependencies --seat-id <seat-id> --slug ap-exception-brief --json
|
|
43313
|
+
{{cli}} skills assign --seat-id <seat-id> --slug ap-exception-brief --rationale "Use the first-party AP exception procedure." --json
|
|
43314
|
+
\`\`\`
|
|
43315
|
+
|
|
43316
|
+
\`skill.enable_catalog\` creates a company-owned immutable copy and may return a human confirmation. Do not re-run blindly after approval; read the approval output or list Skills again.
|
|
43317
|
+
|
|
43318
|
+
Tenant-admin MCP:
|
|
43319
|
+
|
|
43320
|
+
1. Call \`rost_list_rost_skill_catalog\` with \`{}\`.
|
|
43321
|
+
2. Call \`rost_enable_rost_catalog_skill\` with \`{"slug":"rost/ap-exception-brief"}\`; if it returns a confirmation, stop for the human approval output.
|
|
43322
|
+
3. Call \`rost_check_skill_dependencies\` with the enabled Skill slug and target Seat.
|
|
43323
|
+
4. Call \`rost_assign_skill_to_seat\` with \`status:"proposed"\`; do not self-approve assignment.
|
|
43324
|
+
|
|
43325
|
+
## Inspect, import, dependency-check, and propose a GitHub Skill
|
|
43326
|
+
|
|
43327
|
+
Tenant-admin MCP:
|
|
43328
|
+
|
|
43329
|
+
1. Call \`rost_import_github_skill\` with \`{"url":"https://github.com/acme/skills/tree/main/ap","status":"pending_review"}\`.
|
|
43330
|
+
2. Read the returned descriptor and validation findings.
|
|
43331
|
+
3. Call \`rost_get_skill_file\` for \`SKILL.md\`.
|
|
43332
|
+
4. If it should be assignable, ask a human to publish with \`rost_publish_skill\`.
|
|
43333
|
+
5. After publication, call \`rost_check_skill_dependencies\`.
|
|
43334
|
+
6. Propose assignment with \`rost_assign_skill_to_seat\`.
|
|
43335
|
+
|
|
43336
|
+
Uploaded packages use \`rost_import_uploaded_skill\` with structured text files. MCP does not accept direct binary upload in this release.
|
|
43337
|
+
|
|
43338
|
+
## Interpret dependency and entitlement output
|
|
43339
|
+
|
|
43340
|
+
- \`required_tools\`: must be present at or above \`min_scope_tier\`; missing or under-scoped required tools block approved assignment.
|
|
43341
|
+
- \`optional_tools\`: useful but not required; missing optional tools warn only.
|
|
43342
|
+
- \`application\`: when to use the Skill and when not to.
|
|
43343
|
+
- \`entitlement_status: not_entitled\`: the tenant cannot enable that {{brand}} catalog tier. Do not ask for private source URLs.
|
|
43344
|
+
- Duplicate slug or existing company Skill: use the existing Skill or choose a distinct slug; catalog enablement does not overwrite tenant Skills.
|
|
43345
|
+
- Local install result \`installed\`, \`unchanged\`, or \`removed\`: the local client wrote, skipped by hash, or removed a revoked copy.
|
|
43346
|
+
|
|
43347
|
+
Good assignment: the Seat's Charter already owns AP exception review, the Skill's application matches that work, and \`skill.check_dependencies\` is \`ready\`.
|
|
43348
|
+
|
|
43349
|
+
Bad assignment: the Skill requires a payment-write tool the Charter does not grant, or the operator wants the Skill to authorize an approval boundary. Configure the Charter/tool path or choose a narrower Skill instead.
|
|
43350
|
+
|
|
43351
|
+
## Local sync
|
|
43352
|
+
|
|
43353
|
+
Prefer sync for local agents:
|
|
43354
|
+
|
|
43355
|
+
\`\`\`bash
|
|
43356
|
+
{{cli}} skills sync --seat-id <seat-id> --client codex --json
|
|
43357
|
+
\`\`\`
|
|
43358
|
+
|
|
43359
|
+
Set \`ROST_SKILL_INSTALL_ROOT\` only for a sandbox or CI override. Local copies are derived from {{brand}} command output and include \`.rost-skill.json\` metadata. A local copy is not authority; the server still loads assigned immutable Skill versions and still guards every tool call.`
|
|
43360
|
+
},
|
|
43361
|
+
{
|
|
43362
|
+
slug: "agent-reference-map",
|
|
43363
|
+
order: 55,
|
|
43042
43364
|
title: "Agent reference map",
|
|
43043
43365
|
summary: "Where CLI sessions, MCP clients, and in-app agents should retrieve {{brand}} guidance before recommending setup changes.",
|
|
43044
|
-
version: "2026-06-
|
|
43366
|
+
version: "2026-06-21.2",
|
|
43045
43367
|
public: true,
|
|
43046
43368
|
audiences: ["cli", "mcp", "in_app_agent"],
|
|
43047
43369
|
stages: ["company_setup", "graph_design", "charter_design", "staffing", "operating_rhythm"],
|
|
@@ -43075,7 +43397,7 @@ Use this map when you are a CLI session, MCP client, or in-app agent and need to
|
|
|
43075
43397
|
- Search tool: rost_reference_search
|
|
43076
43398
|
- Get tool: rost_reference_get
|
|
43077
43399
|
- Reference resource template: rost://reference/{slug}
|
|
43078
|
-
- Operation resources (read-only, scope-enforced): rost://tenant/status, rost://graph, rost://seat/{id}/context, rost://compass/current, rost://sync/latest, rost://operations/reference-map
|
|
43400
|
+
- Operation resources (read-only, scope-enforced): rost://tenant/status, rost://graph, rost://seat/{id}/context, rost://compass/current, rost://sync/latest, rost://skills, rost://skills/{slug}, rost://skills/{slug}/files/{path}, rost://seat/{id}/skills, rost://operations/reference-map
|
|
43079
43401
|
|
|
43080
43402
|
Start with rost_reference_search when the user asks a broad question. Use rost_reference_get when a workflow or command metadata already names a guide slug. Read the operation resources to load current tenant/seat facts before mutating; tenant-wide resources need a tenant-admin token and a seat token may read only its own rost://seat/{id}/context.
|
|
43081
43403
|
|
|
@@ -43116,12 +43438,16 @@ Agents that run on {{brand}}-managed inference draw against a tenant inference b
|
|
|
43116
43438
|
11. tool-access-and-vault
|
|
43117
43439
|
12. available-tools-guide
|
|
43118
43440
|
13. mcp-and-cli-guide
|
|
43119
|
-
14.
|
|
43120
|
-
15.
|
|
43121
|
-
16.
|
|
43122
|
-
17.
|
|
43123
|
-
18.
|
|
43124
|
-
19.
|
|
43441
|
+
14. skill-builder-guide
|
|
43442
|
+
15. agent-skill-authoring-guide
|
|
43443
|
+
16. agent-skill-setup-guide
|
|
43444
|
+
17. ai-model-data-handling-guide
|
|
43445
|
+
18. cascade-guide
|
|
43446
|
+
19. signal-guide
|
|
43447
|
+
20. friction-guide
|
|
43448
|
+
21. confirmations-guide
|
|
43449
|
+
22. steward-queue-guide
|
|
43450
|
+
23. sync-rhythm-playbook
|
|
43125
43451
|
|
|
43126
43452
|
## Workflow to guide map
|
|
43127
43453
|
|
|
@@ -43135,6 +43461,9 @@ Read the listed guide before recommending or running each workflow. Every workfl
|
|
|
43135
43461
|
- Add an agent through the app (graph or sidebar, visual journey): add-agents-guide.
|
|
43136
43462
|
- Create an agent from a template: stock-agents-guide, then how-agents-work.
|
|
43137
43463
|
- 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.
|
|
43464
|
+
- Create, import, review, or publish a reusable Skill: skill-builder-guide for human workflow, then agent-skill-authoring-guide for CLI/MCP authoring rules.
|
|
43465
|
+
- Assign, dependency-check, enable a catalog Skill, import a GitHub Skill, or sync local Skill files: agent-skill-setup-guide, then mcp-and-cli-guide.
|
|
43466
|
+
- Explain AI model data handling, BYOK, local agent provider settings, or what data may enter prompts/tool calls: ai-model-data-handling-guide, then security-model-guide.
|
|
43138
43467
|
- 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).
|
|
43139
43468
|
- Connect an existing or local agent to a seat: stock-agents-guide (connect section), then mcp-and-cli-guide and runner-guide.
|
|
43140
43469
|
- Run the operating loop as a seat (context, tasks, status, escalate): how-agents-work.
|
|
@@ -43151,10 +43480,10 @@ Read the listed guide before recommending or running each workflow. Every workfl
|
|
|
43151
43480
|
- Company setup: rost-implementation-method, compass-authoring-guide, settings-guide, settings-members-and-invites-guide
|
|
43152
43481
|
- Graph design: responsibility-graph-playbook
|
|
43153
43482
|
- Charter design: charter-design-playbook, charter-authoring-deep-dive
|
|
43154
|
-
- Staffing: agent-staffing-playbook, add-agents-guide, custom-agents-guide, agent-builder-guide, how-agents-work, tool-access-and-vault, available-tools-guide, mcp-and-cli-guide, stock-agents-guide
|
|
43483
|
+
- Staffing: agent-staffing-playbook, add-agents-guide, custom-agents-guide, agent-builder-guide, how-agents-work, tool-access-and-vault, available-tools-guide, skill-builder-guide, agent-skill-authoring-guide, agent-skill-setup-guide, mcp-and-cli-guide, stock-agents-guide
|
|
43155
43484
|
- Operating rhythm: cascade-guide, signal-guide, friction-guide, confirmations-guide, steward-queue-guide, sync-rhythm-playbook, notifications-guide
|
|
43156
43485
|
- Local agents and runners: mcp-and-cli-guide, runner-guide, agent-reference-map
|
|
43157
|
-
- Security and troubleshooting: security-model-guide, troubleshooting-guide
|
|
43486
|
+
- Security and troubleshooting: ai-model-data-handling-guide, security-model-guide, troubleshooting-guide
|
|
43158
43487
|
|
|
43159
43488
|
## Agent behavior
|
|
43160
43489
|
|
|
@@ -43500,7 +43829,7 @@ Stop before: approving a Charter, signing a manifest, connecting a tool or crede
|
|
|
43500
43829
|
order: 72,
|
|
43501
43830
|
title: "Settings guide",
|
|
43502
43831
|
summary: "How to use Settings as the control plane for company access, channels, providers, tokens, and operating defaults.",
|
|
43503
|
-
version: "2026-06-
|
|
43832
|
+
version: "2026-06-21.1",
|
|
43504
43833
|
public: true,
|
|
43505
43834
|
audiences: ["human", "cli", "mcp", "in_app_agent"],
|
|
43506
43835
|
stages: ["company_setup", "staffing"],
|
|
@@ -43552,7 +43881,7 @@ Agents that run on {{brand}}-managed inference draw against a tenant inference b
|
|
|
43552
43881
|
|
|
43553
43882
|
- Set the hard cap with \`settings.update\` (CLI: \`{{cli}} settings update --hard-cap-usd <amount>\`). The optional soft cap warns before the hard cap and must be less than or equal to it.
|
|
43554
43883
|
- The sandbox dry run is free and is never blocked by the cap, so a fresh company can charter, dry-run, and take an agent live before setting a budget. The cap applies only to real managed-inference runs.
|
|
43555
|
-
- A company that brings its own provider key (BYOK) is metered on that key and is not subject to the {{brand}}-managed hard cap.
|
|
43884
|
+
- A company that brings its own provider key (BYOK) is metered on that key and is not subject to the {{brand}}-managed hard cap. BYOK changes the provider account used for eligible cloud calls, not the Charter, tool guard, human gate, or data-retention posture; see the ai-model-data-handling-guide before making provider-handling claims.
|
|
43556
43885
|
|
|
43557
43886
|
## Agent guidance
|
|
43558
43887
|
|
|
@@ -43869,15 +44198,200 @@ Most reads are safe to run while diagnosing. Any fix that changes authority, cre
|
|
|
43869
44198
|
Name the failing surface, collect evidence, recommend the smallest correction, and escalate when the fix changes authority, credentials, or go-live state. Never paste secrets into chat or tool arguments while troubleshooting.`
|
|
43870
44199
|
},
|
|
43871
44200
|
{
|
|
43872
|
-
slug: "
|
|
44201
|
+
slug: "ai-model-data-handling-guide",
|
|
43873
44202
|
order: 78,
|
|
44203
|
+
title: "AI model data handling guide",
|
|
44204
|
+
summary: "How {{brand}} cloud agents, local MCP sessions, runners, BYOK, and connected tools handle model-bound data.",
|
|
44205
|
+
version: "2026-06-21.4",
|
|
44206
|
+
public: true,
|
|
44207
|
+
audiences: ["human", "cli", "mcp", "in_app_agent"],
|
|
44208
|
+
stages: ["company_setup", "staffing", "operating_rhythm"],
|
|
44209
|
+
relatedCommandIds: [
|
|
44210
|
+
"tenant.anthropic_key.save",
|
|
44211
|
+
"credential.ingress",
|
|
44212
|
+
"agent.configure_tools",
|
|
44213
|
+
"mcp_token.create",
|
|
44214
|
+
"runner.pairing.start",
|
|
44215
|
+
"agent.run_now",
|
|
44216
|
+
"work_order.enqueue",
|
|
44217
|
+
"tool.catalog"
|
|
44218
|
+
],
|
|
44219
|
+
legal: {
|
|
44220
|
+
publicRisk: "medium",
|
|
44221
|
+
notes: [
|
|
44222
|
+
"Provider policy summary must stay conservative and source-linked.",
|
|
44223
|
+
"Does not claim zero-data-retention, HIPAA readiness, or model-training exclusions beyond provider account and contract scope."
|
|
44224
|
+
]
|
|
44225
|
+
},
|
|
44226
|
+
sources: [
|
|
44227
|
+
{
|
|
44228
|
+
label: "OpenAI API data controls",
|
|
44229
|
+
url: "https://developers.openai.com/api/docs/guides/your-data",
|
|
44230
|
+
note: "Official API data-use and retention controls verified 2026-06-21."
|
|
44231
|
+
},
|
|
44232
|
+
{
|
|
44233
|
+
label: "OpenAI enterprise privacy",
|
|
44234
|
+
url: "https://openai.com/enterprise-privacy/",
|
|
44235
|
+
note: "Official enterprise privacy and API retention summary verified 2026-06-21."
|
|
44236
|
+
},
|
|
44237
|
+
{
|
|
44238
|
+
label: "OpenAI Codex with ChatGPT plan",
|
|
44239
|
+
url: "https://help.openai.com/en/articles/11369540-using-codex-with-your-chatgpt-plan",
|
|
44240
|
+
note: "Official Codex plan data-control scope verified 2026-06-21."
|
|
44241
|
+
},
|
|
44242
|
+
{
|
|
44243
|
+
label: "Anthropic API and data retention",
|
|
44244
|
+
url: "https://platform.claude.com/docs/en/manage-claude/api-and-data-retention",
|
|
44245
|
+
note: "Official Claude API ZDR, HIPAA, and retention scope verified 2026-06-21."
|
|
44246
|
+
},
|
|
44247
|
+
{
|
|
44248
|
+
label: "Claude Code data usage",
|
|
44249
|
+
url: "https://code.claude.com/docs/en/data-usage",
|
|
44250
|
+
note: "Official local Claude Code data-flow, training, and retention summary verified 2026-06-21."
|
|
44251
|
+
},
|
|
44252
|
+
{
|
|
44253
|
+
label: "Reference corpus and docs spec",
|
|
44254
|
+
internalPath: "docs/specs/reference-corpus-and-docs.md",
|
|
44255
|
+
note: "Defines the public reference guide set and agent retrieval surfaces."
|
|
44256
|
+
}
|
|
44257
|
+
],
|
|
44258
|
+
body: `# AI model data handling guide
|
|
44259
|
+
|
|
44260
|
+
Use this guide when a human, CLI session, MCP client, or in-app agent needs to understand what data can reach an AI model, what {{brand}} controls, and what remains governed by the customer's provider account, local client, or connected tools.
|
|
44261
|
+
|
|
44262
|
+
This is product guidance, not a legal warranty. Provider terms, enterprise contracts, data-processing addenda, retention controls, regional settings, and endpoint-specific behavior can change. Verify the provider account and contract before relying on a zero-data-retention, HIPAA, regional, or no-training posture.
|
|
44263
|
+
|
|
44264
|
+
For {{brand}}'s own product-improvement posture, read the public Privacy Policy and Terms of Service at \`/privacy\` and \`/terms\`. They state that {{brand}} may analyze aggregated or de-identified data about usage, setup patterns, agent outcomes, and operating metrics to improve product features, defaults, templates, recommendations, safety checks, and reliability; they also state that {{brand}} does not sell customer data, share one customer's workspace data with another customer, or use identifiable customer content to train generalized AI models. Google user data and information derived from Google APIs stay under the Privacy Policy's Google user data limits and are not included in cross-customer product-improvement analytics. Do not turn this into a provider-side claim about a customer's local client, BYOK provider account, or third-party tool.
|
|
44265
|
+
|
|
44266
|
+
## The three agent lanes
|
|
44267
|
+
|
|
44268
|
+
{{brand}} names the execution lane on runs and work orders. Use these exact terms:
|
|
44269
|
+
|
|
44270
|
+
| Lane | Where model-bound data is assembled | Who controls provider handling |
|
|
44271
|
+
|---|---|---|
|
|
44272
|
+
| \`cloud\` | The {{brand}} cloud runtime builds bounded prompt context from the Seat Charter, signed permission manifest, task or work order, relevant operating facts, selected Skill files, and tool results. | The current managed cloud path uses Anthropic-backed model configuration, either through {{brand}}'s platform-managed provider account or the tenant's approved BYOK Anthropic credential when that tenant has saved one. |
|
|
44273
|
+
| \`mcp_session\` | A local agent client such as Claude Code, Codex, OpenCode, Cursor, or another MCP-capable client asks {{brand}} for scoped context, resources, and command results. | The customer's local client, model provider account, proxy, and provider settings. {{brand}} does not control that local provider's retention, training, telemetry, or local transcript storage. |
|
|
44274
|
+
| \`runner\` | A paired runner claims work from {{brand}}, receives bounded work-order context, and may invoke a local or customer-controlled model client to complete the work. | The runner host, local client, and provider account used by that runner. {{brand}} controls the work-order boundary and audit path, not every downstream local model setting. |
|
|
44275
|
+
|
|
44276
|
+
When answering "where did my data go?", name the lane first. Do not collapse \`cloud\`, \`mcp_session\`, and \`runner\` into one generic "agent" path.
|
|
44277
|
+
|
|
44278
|
+
## Cloud agents
|
|
44279
|
+
|
|
44280
|
+
For \`cloud\` runs, {{brand}} prepares the minimum context needed for the Seat to act:
|
|
44281
|
+
|
|
44282
|
+
- Charter purpose, responsibilities, autonomous scope, approval scope, escalation rules, Signals, and signed permission manifest.
|
|
44283
|
+
- The task, work order, Sync/Friction/Signal context, or human instruction for that run.
|
|
44284
|
+
- Assigned Skill summaries and the bounded contents of selected approved Skill files.
|
|
44285
|
+
- Tool results that the server-side guard allowed and that are relevant to the next model turn.
|
|
44286
|
+
- Model catalog choices and run metadata needed to attribute cost and diagnostics.
|
|
44287
|
+
|
|
44288
|
+
Cloud prompts should not include raw credentials, long exports, unrelated customer records, or secret values. A tool result can become model context, so keep tool scopes narrow and connect only the tools the Seat's Charter actually needs. The server-side guard decides whether a tool call is allowed, escalated, or denied; model output and Skill text never grant authority.
|
|
44289
|
+
|
|
44290
|
+
## BYOK Anthropic
|
|
44291
|
+
|
|
44292
|
+
Tenant BYOK changes which provider account is used for eligible \`cloud\` model calls. It does not loosen tool permissions, human gates, tenant isolation, or audit requirements.
|
|
44293
|
+
|
|
44294
|
+
Store a tenant Anthropic key only through \`tenant.anthropic_key.save\` / \`rost_save_tenant_anthropic_key\` or the generic credential ingress path. The key is handled as a vault-backed credential: {{brand}} stores a vault reference and safe metadata, not the raw key in prompts, config, logs, or command output. A human approves the credential flow.
|
|
44295
|
+
|
|
44296
|
+
After BYOK is saved, provider-side retention, training, regional, HIPAA, or zero-data-retention posture depends on that Anthropic organization, workspace, model, feature, and contract. Do not tell a customer "BYOK means zero retention" or "BYOK means no training" unless their provider arrangement actually says that.
|
|
44297
|
+
|
|
44298
|
+
## Local MCP sessions
|
|
44299
|
+
|
|
44300
|
+
In a \`mcp_session\`, {{brand}} is the governed operating-system surface. The local agent client is still its own model client.
|
|
44301
|
+
|
|
44302
|
+
{{brand}} can enforce token scope, tenant isolation, command schemas, human confirmations, tool guards, and redacted command output. It cannot decide whether the local client stores transcripts, sends telemetry, opts into model improvement, uses a consumer account, uses a commercial account, routes through a proxy, or applies zero-data-retention settings. Those are local client and provider settings.
|
|
44303
|
+
|
|
44304
|
+
{{brand}} command and resource outputs are returned to the local client. Seat context, Charter text, task and Signal facts, reference guide bodies, command JSON, and filtered tool results may become part of that client's provider request unless the operator narrows scope, redacts the input, or uses a provider setting that prevents it. Treat every MCP read as data that can enter the local model transcript.
|
|
44305
|
+
|
|
44306
|
+
Before connecting a local agent to sensitive work, verify:
|
|
44307
|
+
|
|
44308
|
+
- Which model provider and account the local client is using.
|
|
44309
|
+
- Whether the account is consumer, team, enterprise, API, or routed through another platform.
|
|
44310
|
+
- Whether model-improvement sharing, telemetry, transcript retention, and local logs are enabled.
|
|
44311
|
+
- Whether the client stores session files locally, and where those files live.
|
|
44312
|
+
- Whether screenshots, files, terminal output, browser data, or tool results can be included in the client transcript.
|
|
44313
|
+
|
|
44314
|
+
For example, official Claude Code docs distinguish consumer and commercial handling, describe local plaintext session transcripts, and state that local clients send prompts and outputs to the configured provider. Official OpenAI API docs distinguish API data controls from consumer products, while official Codex help says ChatGPT training data controls apply to content processed through Codex when Codex is used with a ChatGPT plan. Treat each local agent's provider settings as part of the customer's environment review.
|
|
44315
|
+
|
|
44316
|
+
## Runners
|
|
44317
|
+
|
|
44318
|
+
A \`runner\` is paired to {{brand}} and claims work orders. {{brand}} records the work-order state, lane, Seat, run diagnostics, and audited tool-call outcomes. The runner host controls the local execution environment.
|
|
44319
|
+
|
|
44320
|
+
Keep runner prompts bounded to the work order and Seat context. Do not paste runner bearer secrets, API keys, \`.env\` contents, SSH keys, OAuth tokens, database URLs, or private package credentials into prompts, tool args, screenshots, logs, or status updates. If a runner needs a credential, use the governed credential ingress and vault reference path or the customer's own secure local secret mechanism; do not turn the credential into model context.
|
|
44321
|
+
|
|
44322
|
+
If a runner invokes Claude Code, Codex, OpenCode, Cursor, or another local model client, provider data handling follows that local client and account, not the {{brand}} cloud provider path.
|
|
44323
|
+
|
|
44324
|
+
## Connected tools and tool results
|
|
44325
|
+
|
|
44326
|
+
Connected tools are often the highest-risk data path because a valid tool result may be summarized into the next model turn.
|
|
44327
|
+
|
|
44328
|
+
Use these rules:
|
|
44329
|
+
|
|
44330
|
+
- Connect the narrowest tool scopes needed for the Seat's Charter.
|
|
44331
|
+
- Prefer filtered reads over full exports.
|
|
44332
|
+
- Keep credentials in vault refs and tool handlers; do not send raw secret values to the model.
|
|
44333
|
+
- Treat third-party tool data handling separately from model-provider data handling.
|
|
44334
|
+
- Escalate when a tool would expose regulated data, unusually broad customer records, confidential legal or HR material, or data outside the Seat's approved scope.
|
|
44335
|
+
|
|
44336
|
+
Tool selection is never authorization. Every live tool call still passes the server-side guard and writes an audit record.
|
|
44337
|
+
|
|
44338
|
+
## What not to put in prompts or tool args
|
|
44339
|
+
|
|
44340
|
+
Do not intentionally put these into prompts, MCP tool arguments, runner work orders, Skill files, status updates, or screenshots unless the customer has a documented need and a matching provider/tool contract:
|
|
44341
|
+
|
|
44342
|
+
- API keys, OAuth tokens, passwords, session cookies, SSH keys, signing keys, or recovery codes.
|
|
44343
|
+
- Raw \`.env\` files, private database URLs, credential vault payloads, or unredacted logs containing secrets.
|
|
44344
|
+
- Full customer exports when a filtered subset would answer the question.
|
|
44345
|
+
- Payment card data, PHI, government identifiers, or other regulated records without the required contract and workflow.
|
|
44346
|
+
- Private source URLs with embedded tokens or signed URLs.
|
|
44347
|
+
- Data from another tenant, workspace, account, or seat.
|
|
44348
|
+
|
|
44349
|
+
If sensitive data appears by accident, stop, do not repeat it, and route cleanup through the customer's incident process.
|
|
44350
|
+
|
|
44351
|
+
## Provider policy checkpoints
|
|
44352
|
+
|
|
44353
|
+
For platform-managed \`cloud\` runs and BYOK Anthropic \`cloud\` runs, check the Anthropic account, workspace, model, and contract. As of 2026-06-21, official Anthropic Claude API documentation says retained API data is not used for model training without express permission, that some API features are ZDR-eligible while others are not, and that ZDR, HIPAA readiness, model-specific retention requirements, consumer products, Claude Code, and third-party integrations each have their own scope.
|
|
44354
|
+
|
|
44355
|
+
For local OpenAI API-key clients running through \`mcp_session\` or \`runner\`, check the customer's OpenAI organization, project, endpoint, and API data controls. As of 2026-06-21, official OpenAI API documentation says API data is not used to train or improve OpenAI models unless the customer explicitly opts in, and default abuse-monitoring logs may retain customer content for up to 30 days unless approved controls apply. OpenAI says zero data retention is available only for eligible customers, endpoints, and use cases.
|
|
44356
|
+
|
|
44357
|
+
For Codex specifically, first identify whether the operator is using Codex through a ChatGPT Free/Plus/Pro, Business, Enterprise, Edu, API, or other workspace path. Official OpenAI Codex help says ChatGPT training data controls apply to whether content processed through Codex may be used to improve OpenAI models when Codex is used with a ChatGPT plan, and that Pro and Plus conversations may be used unless training is disabled. Do not give a Codex user the OpenAI API answer unless they are actually using an API-governed Codex path.
|
|
44358
|
+
|
|
44359
|
+
For local Claude Code clients running through \`mcp_session\` or \`runner\`, check whether the customer is using a consumer, team, enterprise, API, or third-party-platform path. Official Claude Code documentation separately describes consumer versus commercial handling, local transcript storage, telemetry, feedback, and provider-specific defaults.
|
|
44360
|
+
|
|
44361
|
+
Use those statements only as current provider-doc summaries. Do not convert them into a blanket {{brand}} claim. The correct customer-facing answer is: "Here is the lane, here is what {{brand}} sends, here is which provider account or local client handles it, and here is what to verify in that account before treating the workflow as no-training, zero-retention, HIPAA-ready, or region-bound."
|
|
44362
|
+
|
|
44363
|
+
## Agent response checklist
|
|
44364
|
+
|
|
44365
|
+
When asked about AI data handling:
|
|
44366
|
+
|
|
44367
|
+
1. Identify the lane: \`cloud\`, \`mcp_session\`, or \`runner\`.
|
|
44368
|
+
2. Name the specific data classes that can enter the prompt or tool result.
|
|
44369
|
+
3. Name whether the provider path is platform-managed, tenant BYOK Anthropic, local client/account, or runner-controlled.
|
|
44370
|
+
4. Warn if the answer depends on provider settings, contract terms, ZDR approval, HIPAA readiness, model choice, endpoint, or third-party tool policy.
|
|
44371
|
+
5. Recommend the smallest safe next step: narrow the tool scope, use a vault ref, redact the input, switch to the approved provider account, or escalate for human/legal review.`
|
|
44372
|
+
},
|
|
44373
|
+
{
|
|
44374
|
+
slug: "security-model-guide",
|
|
44375
|
+
order: 79,
|
|
43874
44376
|
title: "Security model guide",
|
|
43875
44377
|
summary: "How {{brand}} protects tenant data, credentials, tool calls, and human decisions across web, MCP, CLI, and agents.",
|
|
43876
|
-
version: "2026-06-
|
|
44378
|
+
version: "2026-06-21.5",
|
|
43877
44379
|
public: true,
|
|
43878
44380
|
audiences: ["human", "cli", "mcp", "in_app_agent"],
|
|
43879
44381
|
stages: ["company_setup", "staffing", "operating_rhythm"],
|
|
43880
|
-
relatedCommandIds: [
|
|
44382
|
+
relatedCommandIds: [
|
|
44383
|
+
"mcp_token.create",
|
|
44384
|
+
"mcp_token.revoke",
|
|
44385
|
+
"charter.sign_manifest",
|
|
44386
|
+
"credential.ingress",
|
|
44387
|
+
"tenant.anthropic_key.save",
|
|
44388
|
+
"runner.pairing.start",
|
|
44389
|
+
"agent.configure_tools",
|
|
44390
|
+
"agent.list_tool_calls",
|
|
44391
|
+
"agent.get_run",
|
|
44392
|
+
"integration.status",
|
|
44393
|
+
"integration.readiness"
|
|
44394
|
+
],
|
|
43881
44395
|
legal: { publicRisk: "low", notes: ["Public security model summary without internal implementation details."] },
|
|
43882
44396
|
sources: [
|
|
43883
44397
|
{
|
|
@@ -43903,12 +44417,97 @@ Name the failing surface, collect evidence, recommend the smallest correction, a
|
|
|
43903
44417
|
- Tool calls are checked server-side and audited.
|
|
43904
44418
|
- Agents recommend and draft; humans approve durable decisions.
|
|
43905
44419
|
- Accepted knowledge changes by supersession, not silent mutation.
|
|
44420
|
+
- Skills are reusable procedures, not authority. They are versioned immutably, can declare tool dependencies, and are loaded only after assignment; they never grant tools or override the Charter.
|
|
44421
|
+
|
|
44422
|
+
## What {{brand}} stores
|
|
44423
|
+
|
|
44424
|
+
{{brand}} stores operating-system state for each tenant so humans and agents can run the company with an audit trail. The main stored categories are:
|
|
44425
|
+
|
|
44426
|
+
- Company setup, onboarding state, members, roles, invites, and tenant settings.
|
|
44427
|
+
- Compass answers and versions, Responsibility Graph seats, occupancies, Steward links, Charters, signed permission manifests, goals, Signals, Frictions, tasks, decisions, Sync briefs, and events.
|
|
44428
|
+
- Agent setup state, model/run metadata, work orders, run diagnostics, transcript references, token and cost usage, Skill assignments, and immutable Skill activation records.
|
|
44429
|
+
- Tool-call audit rows: tool id, canonical guard result, safe argument summaries, outcome, evidence labels, escalation state, and error linkage.
|
|
44430
|
+
- Integration records, OAuth connection metadata, channel/binding metadata, notification preferences, notification delivery errors, and connector readiness/test results.
|
|
44431
|
+
- MCP token metadata, Runner metadata, runner-pairing state, and revocation state. Raw token material and runner bearer secrets are shown only at issuance when the flow requires it and are not retrievable from normal reads.
|
|
44432
|
+
- Credential records that contain vault references and safe metadata only. Raw API keys, OAuth refresh tokens, tenant Anthropic keys, Slack tokens, Google tokens, and REST connector secrets stay outside Postgres in the configured vault path.
|
|
44433
|
+
- Uploaded or generated documents and bounded extracted context when a user intentionally adds them to onboarding, Compass, Charter, or reference workflows.
|
|
44434
|
+
|
|
44435
|
+
Do not store raw passwords, OAuth tokens, API keys, full \`.env\` files, session cookies, private signed URLs, or credential payloads in prompts, Skill files, command JSON, issue comments, logs, or reference docs. If a workflow needs a secret, route it through credential ingress and store a vault reference.
|
|
44436
|
+
|
|
44437
|
+
## Access and isolation
|
|
44438
|
+
|
|
44439
|
+
Every tenant-scoped product record is scoped by \`tenant_id\`, and database policies are written so one tenant cannot read another tenant's data through normal application access. Server-side tenant context comes from trusted server-side authority, not from client-supplied tenant ids: browser and CLI user sessions use authenticated Supabase claims plus membership, MCP sessions use the authenticated MCP token record, and runner sessions use the authenticated runner credential record.
|
|
44440
|
+
|
|
44441
|
+
Human access is role-based through tenant membership:
|
|
44442
|
+
|
|
44443
|
+
- Owners can administer tenant settings, integrations, members, MCP tokens, agent setup, and credential flows.
|
|
44444
|
+
- Stewards and members usually act through their seat occupancies and assigned responsibilities; some tenant-scoped setup, read, and credential workflows are also available to active tenant members when the command authorization layer allows them.
|
|
44445
|
+
|
|
44446
|
+
Seat Steward accountability is separate from the tenant membership role named \`steward\`. A Seat Steward is the human accountability chain for an agent seat and receives escalations for that seat, but being named as a Seat Steward does not silently grant a model permission to act.
|
|
44447
|
+
|
|
44448
|
+
Agent authority is seat-scoped even when the machine credential is broader. A seat-scoped MCP token can act only as the seat it was minted for. A paired runner authenticates as a tenant machine credential, claims tenant work orders, and receives seat-scoped work context plus a temporary seat-scoped MCP token for the claimed order; the runner bearer credential itself is not a single-seat credential. Tenant-admin MCP tokens are broader: they can reach workflows in the tenant-admin command surface, bounded by command authorization and guards. Reserve them for setup and administration, and prefer the narrowest scope that can do the job.
|
|
44449
|
+
|
|
44450
|
+
Local clients such as Claude Code, Codex, OpenCode, and Cursor may receive command/resource output through MCP. {{brand}} enforces token scope, schemas, tenant isolation, and redaction on the output it returns; the local client and provider account control local transcript storage, telemetry, and model-provider handling. For that model-bound path, use the ai-model-data-handling-guide.
|
|
44451
|
+
|
|
44452
|
+
## Credentials and integrations
|
|
44453
|
+
|
|
44454
|
+
Credentials are never authority by themselves. A connected Slack, Google, REST, Anthropic, or future integration credential can be used only when all required checks pass:
|
|
44455
|
+
|
|
44456
|
+
1. The actor is authorized for the tenant and command.
|
|
44457
|
+
2. The Seat Charter and signed permission manifest allow or escalate the tool.
|
|
44458
|
+
3. The tool handler exists and validates its input schema.
|
|
44459
|
+
4. The integration is connected for the tenant and has an active credential reference.
|
|
44460
|
+
5. Any extra binding exists, such as a Slack channel binding, REST host/method/path policy, or provider-specific setup requirement.
|
|
44461
|
+
6. Human confirmation is complete when the command or credential flow requires it.
|
|
44462
|
+
|
|
44463
|
+
Tool selection is never authorization. A selected tool in setup records the requested permission; live execution still goes through the server-side guard, and the system is designed to write a tool-call audit row for every execution attempt. Standard agent audit reads do not return argument summaries or secret material.
|
|
44464
|
+
|
|
44465
|
+
## Audit trail
|
|
44466
|
+
|
|
44467
|
+
{{brand}} is designed to explain who or what changed operating state:
|
|
44468
|
+
|
|
44469
|
+
- The event log is append-only. Corrections are new events, not edits to old events.
|
|
44470
|
+
- Decisions are human-decided records. Agents can draft or recommend, but durable decisions require a human.
|
|
44471
|
+
- Charters, Compass versions, and accepted knowledge change by supersession instead of silent overwrite.
|
|
44472
|
+
- Agent runs, work orders, tool calls, Skill activations, notification failures, and integration tests leave diagnostic records that can be inspected without exposing raw secrets.
|
|
44473
|
+
- Product-visible server/integration/runtime failures are recorded in \`error_logs\` when tenant context is available; pre-auth or tenant-less failures fall back to structured server logging.
|
|
44474
|
+
|
|
44475
|
+
When reporting evidence to a human, summarize the relevant fields and include stable ids only when they help trace the record. Do not paste raw secrets, full provider responses, full prompt text, or broad exports into status updates.
|
|
44476
|
+
|
|
44477
|
+
## Retention and support access boundaries
|
|
44478
|
+
|
|
44479
|
+
{{brand}} keeps the records needed to operate, secure, troubleshoot, audit, and improve the product. This guide does not promise a fixed deletion schedule, zero retention, regional residency, HIPAA readiness, or staff-access workflow beyond what is explicitly stated in the customer contract, product settings, or public legal pages.
|
|
44480
|
+
|
|
44481
|
+
Staff and support access should be treated as operationally sensitive. The current public posture is conservative: authorized personnel may access customer information when reasonably needed to operate, secure, or support the service; investigate abuse, reliability, or security issues; comply with law; or respond to a customer request. Google user data and information derived from Google APIs remain subject to the Privacy Policy's Google user data limits: humans may access that data only where the customer gives explicit permission for support, for security, to comply with law, or as required to operate the Google-connected features the customer uses. Do not claim that staff technically cannot access customer data in all circumstances unless that control is included in a separate written agreement and has been implemented for that account.
|
|
44482
|
+
|
|
44483
|
+
When support access is needed, use the least data needed to diagnose the issue, prefer tenant-visible product evidence when available, redact secrets, and do not export broad customer datasets for routine support. Avoid asking customers to paste secrets, OAuth tokens, full provider responses, or raw mailbox/spreadsheet content into chat, tickets, issues, or docs. If a customer asks for deletion, retention, legal hold, DPA, BAA, regional processing, customer-visible staff access logs, break-glass approval, or staff-access commitments, escalate instead of improvising an answer.
|
|
44484
|
+
|
|
44485
|
+
Retention language by category:
|
|
44486
|
+
|
|
44487
|
+
- Workspace operating records such as graph, Charter, goal, Signal, Friction, task, Sync, run, event, and tool-call records are retained while the workspace is active so the product can show history, audit trails, and diagnostics.
|
|
44488
|
+
- Connected-service credentials are revoked when an integration is disconnected or the account is closed. Normal reads return credential metadata and vault references, not raw secret material.
|
|
44489
|
+
- Security, audit, event, diagnostic, and abuse-prevention records may be retained after an account or workspace deletion request is completed when needed for integrity, legal compliance, dispute resolution, or service protection.
|
|
44490
|
+
- Product-improvement analytics use only aggregated or de-identified data under the public Privacy Policy and Terms. Aggregated or de-identified derived metrics may be retained after account closure because they no longer identify a workspace.
|
|
44491
|
+
- Google user data and information derived from Google APIs stay under the Privacy Policy's Google user data limits and are not included in cross-customer product-improvement analytics.
|
|
44492
|
+
|
|
44493
|
+
Deferred enterprise controls are not current promises: customer-visible staff access logs, formal break-glass approval, support-access approval workflows, customer-managed retention windows, full self-serve data export/deletion, regional data residency, DPA/BAA commitments, and HIPAA readiness require separate implementation or contract review before being promised.
|
|
43906
44494
|
|
|
43907
44495
|
The public Privacy Policy and Terms of Service are available at \`/privacy\` and \`/terms\` before sign-in and from the authenticated app chrome.
|
|
43908
44496
|
|
|
44497
|
+
Those legal pages state that {{brand}} may analyze aggregated or de-identified data about usage, setup patterns, agent outcomes, and operating metrics to improve product features, defaults, templates, recommendations, safety checks, and reliability. They also state that {{brand}} does not sell customer data, does not share one customer's workspace data with another customer, and does not use identifiable customer content to train generalized AI models. Google user data and information derived from Google APIs stay under the Privacy Policy's Google user data limits and are not included in cross-customer product-improvement analytics. Keep those limits intact when explaining product improvement analytics, and escalate legal/security questions about contracts, deletion, regulated data, or customer-specific commitments.
|
|
44498
|
+
|
|
44499
|
+
For model-bound data questions \u2014 including what \`cloud\`, \`mcp_session\`, or \`runner\` sends to an AI provider, what BYOK changes, and what local clients can store or transmit \u2014 read the ai-model-data-handling-guide before making a provider, retention, HIPAA, ZDR, or no-training claim.
|
|
44500
|
+
|
|
44501
|
+
## Where to read next
|
|
44502
|
+
|
|
44503
|
+
- Read the ai-model-data-handling-guide for model-provider, BYOK, local-client, MCP-session, and runner data paths.
|
|
44504
|
+
- Read the tool-access-and-vault guide for credential ingress, vault references, permission manifests, and tool execution boundaries.
|
|
44505
|
+
- Read the mcp-and-cli-guide for token scope, installation, rotation, and local-agent setup.
|
|
44506
|
+
- Read the runner-guide for runner pairing, local credential storage, bearer-token handling, and queue boundaries.
|
|
44507
|
+
|
|
43909
44508
|
## Agent guidance
|
|
43910
44509
|
|
|
43911
|
-
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.`
|
|
44510
|
+
Never infer permission from the user's wording, a local client configuration, a connected credential, a Skill, or a locally available tool. Check the tenant, role, seat occupancy, Charter, signed permission manifest, command schema, confirmation state, and server response. When in doubt, escalate with the evidence and the narrow question a human must decide.`
|
|
43912
44511
|
},
|
|
43913
44512
|
{
|
|
43914
44513
|
slug: "migration-and-legal-notes",
|
|
@@ -45214,6 +45813,18 @@ function field(record2, key) {
|
|
|
45214
45813
|
}
|
|
45215
45814
|
return String(value);
|
|
45216
45815
|
}
|
|
45816
|
+
function dryRunToolActionLabel(status) {
|
|
45817
|
+
switch (status) {
|
|
45818
|
+
case "intended":
|
|
45819
|
+
return "Would run";
|
|
45820
|
+
case "blocked":
|
|
45821
|
+
return "Blocked";
|
|
45822
|
+
case "escalated":
|
|
45823
|
+
return "Escalated";
|
|
45824
|
+
default:
|
|
45825
|
+
return status;
|
|
45826
|
+
}
|
|
45827
|
+
}
|
|
45217
45828
|
function formatDryRunTranscript(value) {
|
|
45218
45829
|
const transcript = asRecord(value);
|
|
45219
45830
|
const steps = asArray(transcript.steps);
|
|
@@ -45226,7 +45837,11 @@ function formatDryRunTranscript(value) {
|
|
|
45226
45837
|
const guard = record2.guard === null || record2.guard === void 0 ? "" : ` [${field(record2, "guard")}]`;
|
|
45227
45838
|
return ` ${kind}: ${field(record2, "text")}${guard}`;
|
|
45228
45839
|
});
|
|
45229
|
-
|
|
45840
|
+
const toolPreview = asArray(transcript.tool_preview).map((action) => {
|
|
45841
|
+
const record2 = asRecord(action);
|
|
45842
|
+
return ` ${dryRunToolActionLabel(field(record2, "status"))}: ${field(record2, "intended_action")} [${field(record2, "tool_name")}]`;
|
|
45843
|
+
});
|
|
45844
|
+
return ["rehearsal:", ...lines, ...toolPreview.length > 0 ? ["tool preview:", ...toolPreview] : []].join("\n");
|
|
45230
45845
|
}
|
|
45231
45846
|
function markdownLine(output) {
|
|
45232
45847
|
const markdown = asRecord(output).markdown;
|
|
@@ -46626,6 +47241,431 @@ function ensureTrailingSlash2(value) {
|
|
|
46626
47241
|
return value.endsWith("/") ? value : `${value}/`;
|
|
46627
47242
|
}
|
|
46628
47243
|
|
|
47244
|
+
// src/skills.ts
|
|
47245
|
+
import { existsSync, mkdirSync, readFileSync as readFileSync3, rmSync, writeFileSync } from "node:fs";
|
|
47246
|
+
import os from "node:os";
|
|
47247
|
+
import path2 from "node:path";
|
|
47248
|
+
var UsageError2 = class extends Error {
|
|
47249
|
+
};
|
|
47250
|
+
var CLIENTS = /* @__PURE__ */ new Set(["claude-code", "codex", "cursor"]);
|
|
47251
|
+
function skillsUsage2(binName = cliBrand.binName) {
|
|
47252
|
+
return [
|
|
47253
|
+
`${binName} skills list [--json]`,
|
|
47254
|
+
`${binName} skills catalog [--json]`,
|
|
47255
|
+
`${binName} skills get --slug <slug> [--json]`,
|
|
47256
|
+
`${binName} skills file --slug <slug> --path SKILL.md`,
|
|
47257
|
+
`${binName} skills enable rost/<slug> [--json]`,
|
|
47258
|
+
`${binName} skills install <slug-or-rost/slug> [--seat-id <id>] [--client claude-code|codex|cursor] [--version <n>] [--local-only] [--json]`,
|
|
47259
|
+
`${binName} skills sync --seat-id <id> [--client claude-code|codex|cursor] [--json]`,
|
|
47260
|
+
`${binName} skills assign --seat-id <id> (--skill <slug>|--slug <slug>|--skill-version-id <id>) [--approve] [--allow-blocked-proposal] [--json]`,
|
|
47261
|
+
`${binName} skills revoke (--assignment-id <id>|--seat-id <id> --skill <slug>) [--json]`,
|
|
47262
|
+
`${binName} skills publish (--slug <slug>|--skill-version-id <id>) [--allow-warnings] [--json]`
|
|
47263
|
+
].join("\n");
|
|
47264
|
+
}
|
|
47265
|
+
async function runSkills(context, args, env = process.env) {
|
|
47266
|
+
try {
|
|
47267
|
+
const [action, ...rest] = args;
|
|
47268
|
+
if (action === "help" || action === "--help" || action === "-h" || action === void 0) {
|
|
47269
|
+
context.io.stdout.write(`${skillsUsage2(context.binName)}
|
|
47270
|
+
`);
|
|
47271
|
+
return action === void 0 ? 1 : 0;
|
|
47272
|
+
}
|
|
47273
|
+
if (action === "list") {
|
|
47274
|
+
return context.run(context.client, "skill.list", {}, void 0);
|
|
47275
|
+
}
|
|
47276
|
+
if (action === "catalog") {
|
|
47277
|
+
const parsed = parseFlags2(rest, /* @__PURE__ */ new Set(["include-unentitled"]));
|
|
47278
|
+
return context.run(context.client, "skill.catalog", {
|
|
47279
|
+
...parsed.flags.has("include-unentitled") ? { include_unentitled: true } : {}
|
|
47280
|
+
}, parsed.json ? void 0 : formatCatalog);
|
|
47281
|
+
}
|
|
47282
|
+
if (action === "get") {
|
|
47283
|
+
const parsed = parseFlags2(rest);
|
|
47284
|
+
return context.run(context.client, "skill.get", { slug: requireValue3(parsed, "slug") }, parsed.json ? void 0 : formatSkillDetail2);
|
|
47285
|
+
}
|
|
47286
|
+
if (action === "file") {
|
|
47287
|
+
const parsed = parseFlags2(rest);
|
|
47288
|
+
return context.run(context.client, "skill.file.get", {
|
|
47289
|
+
slug: requireValue3(parsed, "slug"),
|
|
47290
|
+
path: requireValue3(parsed, "path")
|
|
47291
|
+
}, (output) => {
|
|
47292
|
+
const content = asRecord2(output).content;
|
|
47293
|
+
return typeof content === "string" ? content : JSON.stringify(output, null, 2);
|
|
47294
|
+
});
|
|
47295
|
+
}
|
|
47296
|
+
if (action === "enable") {
|
|
47297
|
+
const slug2 = rest[0];
|
|
47298
|
+
if (!slug2 || slug2.startsWith("--")) {
|
|
47299
|
+
throw new UsageError2(`Usage: ${context.binName} skills enable rost/<slug> [--json]`);
|
|
47300
|
+
}
|
|
47301
|
+
const parsed = parseFlags2(rest.slice(1));
|
|
47302
|
+
return context.run(context.client, "skill.enable_catalog", { slug: slug2 }, parsed.json ? void 0 : formatEnable);
|
|
47303
|
+
}
|
|
47304
|
+
if (action === "install") {
|
|
47305
|
+
return installOne(context, rest, env);
|
|
47306
|
+
}
|
|
47307
|
+
if (action === "sync") {
|
|
47308
|
+
return syncAssigned(context, rest, env);
|
|
47309
|
+
}
|
|
47310
|
+
if (action === "assign") {
|
|
47311
|
+
const parsed = parseFlags2(rest, /* @__PURE__ */ new Set(["approve", "allow-blocked-proposal"]));
|
|
47312
|
+
const body = withDefined({
|
|
47313
|
+
seat_id: requireValue3(parsed, "seat-id"),
|
|
47314
|
+
status: parsed.flags.has("approve") ? "approved" : "proposed",
|
|
47315
|
+
rationale: optionalValue2(parsed, "rationale") ?? "Skill selected for this Seat.",
|
|
47316
|
+
allow_blocked_proposal: parsed.flags.has("allow-blocked-proposal")
|
|
47317
|
+
}, {
|
|
47318
|
+
slug: optionalValue2(parsed, "skill") ?? optionalValue2(parsed, "slug"),
|
|
47319
|
+
skill_version_id: optionalValue2(parsed, "skill-version-id")
|
|
47320
|
+
});
|
|
47321
|
+
return context.run(context.client, "skill.assign_to_seat", body, parsed.json ? void 0 : formatAssignment2, { targetSeatId: body.seat_id });
|
|
47322
|
+
}
|
|
47323
|
+
if (action === "revoke") {
|
|
47324
|
+
const parsed = parseFlags2(rest);
|
|
47325
|
+
const seatId = optionalValue2(parsed, "seat-id");
|
|
47326
|
+
const body = withDefined({}, {
|
|
47327
|
+
assignment_id: optionalValue2(parsed, "assignment-id"),
|
|
47328
|
+
seat_id: seatId,
|
|
47329
|
+
slug: optionalValue2(parsed, "skill") ?? optionalValue2(parsed, "slug"),
|
|
47330
|
+
skill_version_id: optionalValue2(parsed, "skill-version-id"),
|
|
47331
|
+
rationale: optionalValue2(parsed, "rationale")
|
|
47332
|
+
});
|
|
47333
|
+
return context.run(context.client, "skill.revoke_from_seat", body, parsed.json ? void 0 : formatRevoke, seatId ? { targetSeatId: seatId } : {});
|
|
47334
|
+
}
|
|
47335
|
+
if (action === "publish") {
|
|
47336
|
+
const parsed = parseFlags2(rest, /* @__PURE__ */ new Set(["allow-warnings"]));
|
|
47337
|
+
const body = withDefined({
|
|
47338
|
+
allow_warnings: parsed.flags.has("allow-warnings")
|
|
47339
|
+
}, {
|
|
47340
|
+
slug: optionalValue2(parsed, "slug"),
|
|
47341
|
+
skill_version_id: optionalValue2(parsed, "skill-version-id")
|
|
47342
|
+
});
|
|
47343
|
+
return context.run(context.client, "skill.publish", body, parsed.json ? void 0 : formatPublish);
|
|
47344
|
+
}
|
|
47345
|
+
throw new UsageError2(`Unknown skills action: ${action}`);
|
|
47346
|
+
} catch (error51) {
|
|
47347
|
+
if (error51 instanceof UsageError2) {
|
|
47348
|
+
context.io.stderr.write(`${error51.message}
|
|
47349
|
+
`);
|
|
47350
|
+
return 1;
|
|
47351
|
+
}
|
|
47352
|
+
if (error51 instanceof CommandClientError) {
|
|
47353
|
+
return printCommandError(context.io, error51);
|
|
47354
|
+
}
|
|
47355
|
+
throw error51;
|
|
47356
|
+
}
|
|
47357
|
+
}
|
|
47358
|
+
async function installOne(context, args, env) {
|
|
47359
|
+
const slug2 = args[0];
|
|
47360
|
+
if (!slug2 || slug2.startsWith("--")) {
|
|
47361
|
+
throw new UsageError2(`Usage: ${context.binName} skills install <slug-or-rost/slug> [--seat-id <id>] [--client claude-code|codex|cursor] [--version <n>] [--local-only] [--json]`);
|
|
47362
|
+
}
|
|
47363
|
+
const parsed = parseFlags2(args.slice(1), /* @__PURE__ */ new Set(["local-only"]));
|
|
47364
|
+
const client = parseClient2(optionalValue2(parsed, "client") ?? "codex");
|
|
47365
|
+
const seatId = optionalValue2(parsed, "seat-id");
|
|
47366
|
+
const body = withDefined({
|
|
47367
|
+
slug: slug2,
|
|
47368
|
+
client,
|
|
47369
|
+
local_only: parsed.flags.has("local-only")
|
|
47370
|
+
}, {
|
|
47371
|
+
seat_id: seatId,
|
|
47372
|
+
version: optionalNumber2(parsed, "version")
|
|
47373
|
+
});
|
|
47374
|
+
const options = seatId ? { targetSeatId: seatId } : {};
|
|
47375
|
+
const output = await executeInstallCommand(context, body, options);
|
|
47376
|
+
const summary = applyLocalSkillChanges(output, client, env, { removeRevoked: false });
|
|
47377
|
+
const outputRecord = asRecord2(output);
|
|
47378
|
+
context.io.stdout.write(parsed.json ? `${JSON.stringify({ ...outputRecord, local: summary }, null, 2)}
|
|
47379
|
+
` : `${formatLocalSummary(summary)}
|
|
47380
|
+
`);
|
|
47381
|
+
return 0;
|
|
47382
|
+
}
|
|
47383
|
+
async function syncAssigned(context, args, env) {
|
|
47384
|
+
const parsed = parseFlags2(args);
|
|
47385
|
+
const seatId = requireValue3(parsed, "seat-id");
|
|
47386
|
+
const client = parseClient2(optionalValue2(parsed, "client") ?? "codex");
|
|
47387
|
+
const output = await executeSkillCommand(context, "skill.sync_local", {
|
|
47388
|
+
seat_id: seatId,
|
|
47389
|
+
client
|
|
47390
|
+
}, { targetSeatId: seatId });
|
|
47391
|
+
const summary = applyLocalSkillChanges(output, client, env, { removeRevoked: true });
|
|
47392
|
+
const outputRecord = asRecord2(output);
|
|
47393
|
+
context.io.stdout.write(parsed.json ? `${JSON.stringify({ ...outputRecord, local: summary }, null, 2)}
|
|
47394
|
+
` : `${formatLocalSummary(summary)}
|
|
47395
|
+
`);
|
|
47396
|
+
return 0;
|
|
47397
|
+
}
|
|
47398
|
+
async function executeInstallCommand(context, body, options) {
|
|
47399
|
+
const slug2 = typeof body.slug === "string" ? body.slug : "";
|
|
47400
|
+
if (slug2.startsWith("rost/") && body.local_only !== true) {
|
|
47401
|
+
try {
|
|
47402
|
+
return await executeSkillCommand(context, "skill.install_local", { ...body, local_only: true }, options);
|
|
47403
|
+
} catch (error51) {
|
|
47404
|
+
if (!isCommandConflict(error51)) {
|
|
47405
|
+
throw error51;
|
|
47406
|
+
}
|
|
47407
|
+
}
|
|
47408
|
+
}
|
|
47409
|
+
return executeSkillCommand(context, "skill.install_local", body, options);
|
|
47410
|
+
}
|
|
47411
|
+
async function executeSkillCommand(context, commandId, body, options = {}) {
|
|
47412
|
+
try {
|
|
47413
|
+
const output = await context.client.execute(commandId, body, options);
|
|
47414
|
+
return output.output;
|
|
47415
|
+
} catch (error51) {
|
|
47416
|
+
const pending = context.io.interactive === true ? pendingConfirmationFromError(error51) : null;
|
|
47417
|
+
if (pending && pending.commandId === commandId) {
|
|
47418
|
+
context.io.stderr.write(`Approving ${pending.commandId} confirmation ${pending.confirmationId} as the interactive CLI user.
|
|
47419
|
+
`);
|
|
47420
|
+
const approved = await context.client.execute("confirmation.approve", { confirmation_id: pending.confirmationId });
|
|
47421
|
+
return asRecord2(approved.output).output ?? approved.output;
|
|
47422
|
+
}
|
|
47423
|
+
throw error51;
|
|
47424
|
+
}
|
|
47425
|
+
}
|
|
47426
|
+
function applyLocalSkillChanges(output, client, env, options) {
|
|
47427
|
+
const root = installRoot(client, env);
|
|
47428
|
+
const changes = writeInstalls(output, root);
|
|
47429
|
+
if (options.removeRevoked) {
|
|
47430
|
+
changes.push(...removeRevokedInstalls(output, root));
|
|
47431
|
+
}
|
|
47432
|
+
return changes;
|
|
47433
|
+
}
|
|
47434
|
+
function writeInstalls(output, root) {
|
|
47435
|
+
const installs = asArray2(asRecord2(output).installs);
|
|
47436
|
+
return installs.map((entry) => {
|
|
47437
|
+
const install = asRecord2(entry);
|
|
47438
|
+
const slug2 = safeLocalSlug(String(install.slug ?? ""));
|
|
47439
|
+
const metadata = asRecord2(install.metadata);
|
|
47440
|
+
const files = asArray2(install.files).map(asRecord2);
|
|
47441
|
+
const dir = path2.join(root, slug2);
|
|
47442
|
+
const metadataPath = path2.join(dir, ".rost-skill.json");
|
|
47443
|
+
const expectedHash = String(metadata.content_sha256 ?? "");
|
|
47444
|
+
if (existingHash(metadataPath) === expectedHash) {
|
|
47445
|
+
return { slug: slug2, dir, status: "unchanged", files: files.length };
|
|
47446
|
+
}
|
|
47447
|
+
rmSync(dir, { recursive: true, force: true });
|
|
47448
|
+
mkdirSync(dir, { recursive: true });
|
|
47449
|
+
for (const file2 of files) {
|
|
47450
|
+
const relativePath = safeRelativePath(String(file2.path ?? ""));
|
|
47451
|
+
const content = String(file2.content ?? "");
|
|
47452
|
+
const target = path2.join(dir, relativePath);
|
|
47453
|
+
mkdirSync(path2.dirname(target), { recursive: true });
|
|
47454
|
+
writeFileSync(target, content, "utf8");
|
|
47455
|
+
}
|
|
47456
|
+
writeFileSync(metadataPath, `${JSON.stringify(metadata, null, 2)}
|
|
47457
|
+
`, "utf8");
|
|
47458
|
+
return { slug: slug2, dir, status: "installed", files: files.length };
|
|
47459
|
+
});
|
|
47460
|
+
}
|
|
47461
|
+
function removeRevokedInstalls(output, root) {
|
|
47462
|
+
const installs = new Set(asArray2(asRecord2(output).installs).map((entry) => {
|
|
47463
|
+
const slug2 = asRecord2(entry).slug;
|
|
47464
|
+
return typeof slug2 === "string" ? slug2 : "";
|
|
47465
|
+
}));
|
|
47466
|
+
const revoked = asArray2(asRecord2(output).revoked);
|
|
47467
|
+
const changes = [];
|
|
47468
|
+
for (const entry of revoked) {
|
|
47469
|
+
const slug2 = safeLocalSlug(String(asRecord2(entry).slug ?? ""));
|
|
47470
|
+
if (installs.has(slug2)) {
|
|
47471
|
+
continue;
|
|
47472
|
+
}
|
|
47473
|
+
const dir = path2.join(root, slug2);
|
|
47474
|
+
if (!existsSync(dir)) {
|
|
47475
|
+
continue;
|
|
47476
|
+
}
|
|
47477
|
+
rmSync(dir, { recursive: true, force: true });
|
|
47478
|
+
changes.push({ slug: slug2, dir, status: "removed", files: 0 });
|
|
47479
|
+
}
|
|
47480
|
+
return changes;
|
|
47481
|
+
}
|
|
47482
|
+
function installRoot(client, env) {
|
|
47483
|
+
const override = env.ROST_SKILL_INSTALL_ROOT;
|
|
47484
|
+
if (override && override.length > 0) {
|
|
47485
|
+
return path2.resolve(override, client);
|
|
47486
|
+
}
|
|
47487
|
+
if (client === "codex") {
|
|
47488
|
+
return path2.join(env.CODEX_HOME ?? path2.join(os.homedir(), ".codex"), "skills", "rost");
|
|
47489
|
+
}
|
|
47490
|
+
if (client === "claude-code") {
|
|
47491
|
+
return path2.join(env.CLAUDE_HOME ?? path2.join(os.homedir(), ".claude"), "skills", "rost");
|
|
47492
|
+
}
|
|
47493
|
+
return path2.join(os.homedir(), ".cursor", "skills", "rost");
|
|
47494
|
+
}
|
|
47495
|
+
function safeRelativePath(value) {
|
|
47496
|
+
const normalized = value.trim().replaceAll("\\", "/").replace(/^\.\/+/, "");
|
|
47497
|
+
if (!normalized || normalized.startsWith("/") || normalized.includes("//") || normalized.split("/").includes("..")) {
|
|
47498
|
+
throw new UsageError2("Server returned an invalid skill file path.");
|
|
47499
|
+
}
|
|
47500
|
+
return normalized;
|
|
47501
|
+
}
|
|
47502
|
+
function safeLocalSlug(value) {
|
|
47503
|
+
if (!/^[a-z0-9][a-z0-9-]{1,80}$/.test(value)) {
|
|
47504
|
+
throw new UsageError2("Server returned an invalid skill slug.");
|
|
47505
|
+
}
|
|
47506
|
+
return value;
|
|
47507
|
+
}
|
|
47508
|
+
function existingHash(metadataPath) {
|
|
47509
|
+
if (!existsSync(metadataPath)) {
|
|
47510
|
+
return null;
|
|
47511
|
+
}
|
|
47512
|
+
try {
|
|
47513
|
+
const parsed = JSON.parse(readFileSync3(metadataPath, "utf8"));
|
|
47514
|
+
const hash2 = asRecord2(parsed).content_sha256;
|
|
47515
|
+
return typeof hash2 === "string" ? hash2 : null;
|
|
47516
|
+
} catch {
|
|
47517
|
+
return null;
|
|
47518
|
+
}
|
|
47519
|
+
}
|
|
47520
|
+
function parseFlags2(args, booleanFlags = /* @__PURE__ */ new Set()) {
|
|
47521
|
+
const values = /* @__PURE__ */ new Map();
|
|
47522
|
+
const flags = /* @__PURE__ */ new Set();
|
|
47523
|
+
let json2 = false;
|
|
47524
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
47525
|
+
const token = args[index];
|
|
47526
|
+
if (token === void 0) {
|
|
47527
|
+
continue;
|
|
47528
|
+
}
|
|
47529
|
+
if (!token.startsWith("--")) {
|
|
47530
|
+
throw new UsageError2(`Unexpected argument: ${token}`);
|
|
47531
|
+
}
|
|
47532
|
+
const key = token.slice(2);
|
|
47533
|
+
if (key === "json") {
|
|
47534
|
+
json2 = true;
|
|
47535
|
+
continue;
|
|
47536
|
+
}
|
|
47537
|
+
if (booleanFlags.has(key)) {
|
|
47538
|
+
flags.add(key);
|
|
47539
|
+
continue;
|
|
47540
|
+
}
|
|
47541
|
+
const value = args[index + 1];
|
|
47542
|
+
if (value === void 0 || value.startsWith("--")) {
|
|
47543
|
+
flags.add(key);
|
|
47544
|
+
continue;
|
|
47545
|
+
}
|
|
47546
|
+
values.set(key, value);
|
|
47547
|
+
index += 1;
|
|
47548
|
+
}
|
|
47549
|
+
return { json: json2, values, flags };
|
|
47550
|
+
}
|
|
47551
|
+
function requireValue3(parsed, key) {
|
|
47552
|
+
const value = optionalValue2(parsed, key);
|
|
47553
|
+
if (value === void 0) {
|
|
47554
|
+
throw new UsageError2(`Missing required --${key} value.`);
|
|
47555
|
+
}
|
|
47556
|
+
return value;
|
|
47557
|
+
}
|
|
47558
|
+
function optionalValue2(parsed, key) {
|
|
47559
|
+
const value = parsed.values.get(key);
|
|
47560
|
+
return value && value.length > 0 ? value : void 0;
|
|
47561
|
+
}
|
|
47562
|
+
function optionalNumber2(parsed, key) {
|
|
47563
|
+
const value = optionalValue2(parsed, key);
|
|
47564
|
+
if (value === void 0) {
|
|
47565
|
+
return void 0;
|
|
47566
|
+
}
|
|
47567
|
+
const parsedNumber = Number(value);
|
|
47568
|
+
if (!Number.isSafeInteger(parsedNumber) || parsedNumber <= 0) {
|
|
47569
|
+
throw new UsageError2(`--${key} must be a positive integer.`);
|
|
47570
|
+
}
|
|
47571
|
+
return parsedNumber;
|
|
47572
|
+
}
|
|
47573
|
+
function parseClient2(value) {
|
|
47574
|
+
if (!CLIENTS.has(value)) {
|
|
47575
|
+
throw new UsageError2("--client must be claude-code, codex, or cursor.");
|
|
47576
|
+
}
|
|
47577
|
+
return value;
|
|
47578
|
+
}
|
|
47579
|
+
function isCommandConflict(error51) {
|
|
47580
|
+
return error51 instanceof CommandClientError && error51.status === 409;
|
|
47581
|
+
}
|
|
47582
|
+
function withDefined(base, extra) {
|
|
47583
|
+
const next = { ...base };
|
|
47584
|
+
for (const [key, value] of Object.entries(extra)) {
|
|
47585
|
+
if (value !== void 0) {
|
|
47586
|
+
next[key] = value;
|
|
47587
|
+
}
|
|
47588
|
+
}
|
|
47589
|
+
return next;
|
|
47590
|
+
}
|
|
47591
|
+
function asRecord2(value) {
|
|
47592
|
+
return typeof value === "object" && value !== null ? value : {};
|
|
47593
|
+
}
|
|
47594
|
+
function asArray2(value) {
|
|
47595
|
+
return Array.isArray(value) ? value : [];
|
|
47596
|
+
}
|
|
47597
|
+
function formatCatalog(output) {
|
|
47598
|
+
const entries = asArray2(asRecord2(output).catalog);
|
|
47599
|
+
if (entries.length === 0) {
|
|
47600
|
+
return "No ROST catalog skills are available for this tenant.";
|
|
47601
|
+
}
|
|
47602
|
+
return entries.map((entry) => {
|
|
47603
|
+
const record2 = asRecord2(entry);
|
|
47604
|
+
return `${record2.catalog_slug} [${record2.tier}/${record2.entitlement_status}] ${record2.name}`;
|
|
47605
|
+
}).join("\n");
|
|
47606
|
+
}
|
|
47607
|
+
function formatSkillDetail2(output) {
|
|
47608
|
+
const skill = asRecord2(asRecord2(output).skill);
|
|
47609
|
+
return `${skill.slug} v${skill.latest_version ?? "\u2014"} [${skill.status}] ${skill.name}
|
|
47610
|
+
${skill.description}`;
|
|
47611
|
+
}
|
|
47612
|
+
function formatEnable(output) {
|
|
47613
|
+
const skill = asRecord2(asRecord2(output).skill);
|
|
47614
|
+
const catalog = asRecord2(asRecord2(output).catalog);
|
|
47615
|
+
return `Enabled ${catalog.catalog_slug} as ${skill.slug} v${skill.version} (${skill.skill_version_id})`;
|
|
47616
|
+
}
|
|
47617
|
+
function formatAssignment2(output) {
|
|
47618
|
+
const assignment = asRecord2(asRecord2(output).assignment);
|
|
47619
|
+
return `${assignment.status} ${assignment.slug} for seat ${assignment.seat_id}; sync: ${String(asRecord2(output).local_sync_next_step)}`;
|
|
47620
|
+
}
|
|
47621
|
+
function formatRevoke(output) {
|
|
47622
|
+
const record2 = asRecord2(output);
|
|
47623
|
+
return `Revoked ${record2.slug} for seat ${record2.seat_id}; sync: ${record2.local_sync_next_step}`;
|
|
47624
|
+
}
|
|
47625
|
+
function formatPublish(output) {
|
|
47626
|
+
const skill = asRecord2(asRecord2(output).skill);
|
|
47627
|
+
return `Published ${skill.slug} v${skill.version} (${skill.skill_version_id})`;
|
|
47628
|
+
}
|
|
47629
|
+
function formatLocalSummary(summary) {
|
|
47630
|
+
if (summary.length === 0) {
|
|
47631
|
+
return "No skills to install.";
|
|
47632
|
+
}
|
|
47633
|
+
return summary.map((entry) => `${entry.status} ${entry.slug} -> ${entry.dir} (${entry.files} files)`).join("\n");
|
|
47634
|
+
}
|
|
47635
|
+
function printCommandError(io, error51) {
|
|
47636
|
+
if (error51.response && !error51.response.ok) {
|
|
47637
|
+
const payload = {
|
|
47638
|
+
code: error51.response.error.code,
|
|
47639
|
+
message: error51.response.error.message,
|
|
47640
|
+
...error51.response.error.details === void 0 ? {} : { details: error51.response.error.details },
|
|
47641
|
+
...error51.response.error.help === void 0 ? {} : { help: error51.response.error.help },
|
|
47642
|
+
...error51.response.requestId === void 0 ? {} : { requestId: error51.response.requestId }
|
|
47643
|
+
};
|
|
47644
|
+
io.stderr.write(`${redactForLog(payload)}
|
|
47645
|
+
`);
|
|
47646
|
+
if (error51.response.error.help !== void 0) {
|
|
47647
|
+
io.stderr.write(`\u2192 try: ${redactForLog(error51.response.error.help)}
|
|
47648
|
+
`);
|
|
47649
|
+
}
|
|
47650
|
+
return error51.status === 409 ? 3 : error51.status >= 400 && error51.status < 500 ? 1 : 2;
|
|
47651
|
+
}
|
|
47652
|
+
io.stderr.write(`${redactForLog(error51.message)}
|
|
47653
|
+
`);
|
|
47654
|
+
return error51.status >= 400 && error51.status < 500 ? 1 : 2;
|
|
47655
|
+
}
|
|
47656
|
+
function pendingConfirmationFromError(error51) {
|
|
47657
|
+
if (!(error51 instanceof CommandClientError) || !error51.response || error51.response.ok || error51.response.error.code !== "COMMAND_CONFIRMATION_REQUIRED") {
|
|
47658
|
+
return null;
|
|
47659
|
+
}
|
|
47660
|
+
const details = asRecord2(error51.response.error.details);
|
|
47661
|
+
const confirmationId = details.confirmationId;
|
|
47662
|
+
const commandId = details.commandId;
|
|
47663
|
+
if (typeof confirmationId !== "string" || confirmationId.length === 0 || typeof commandId !== "string" || commandId.length === 0) {
|
|
47664
|
+
return null;
|
|
47665
|
+
}
|
|
47666
|
+
return { confirmationId, commandId };
|
|
47667
|
+
}
|
|
47668
|
+
|
|
46629
47669
|
// src/index.ts
|
|
46630
47670
|
async function main(argv = process.argv.slice(2), options = {}) {
|
|
46631
47671
|
const io = options.io ?? {
|
|
@@ -46788,6 +47828,23 @@ Run ${cliBrand.binName} login --device again if the next command asks you to aut
|
|
|
46788
47828
|
if (command === "mcp") {
|
|
46789
47829
|
return executeMcp(io, client, config2.appUrl, args);
|
|
46790
47830
|
}
|
|
47831
|
+
if (command === "skills") {
|
|
47832
|
+
const skillsAction = args[0];
|
|
47833
|
+
if (skillsAction !== "catalog" && skillsAction !== "enable" && skillsAction !== "install" && skillsAction !== "sync") {
|
|
47834
|
+
return runOperation(command, args, {
|
|
47835
|
+
io,
|
|
47836
|
+
client,
|
|
47837
|
+
binName: cliBrand.binName,
|
|
47838
|
+
run: (wrapperClient, commandId, body, format, options2) => printCommandOutput(io, wrapperClient, commandId, body, format, options2)
|
|
47839
|
+
});
|
|
47840
|
+
}
|
|
47841
|
+
return runSkills({
|
|
47842
|
+
io,
|
|
47843
|
+
client,
|
|
47844
|
+
binName: cliBrand.binName,
|
|
47845
|
+
run: (wrapperClient, commandId, body, format, options2) => printCommandOutput(io, wrapperClient, commandId, body, format, options2)
|
|
47846
|
+
}, args);
|
|
47847
|
+
}
|
|
46791
47848
|
if (command === "init") {
|
|
46792
47849
|
return executeInit(io, client, config2.appUrl, args);
|
|
46793
47850
|
}
|
|
@@ -46887,7 +47944,7 @@ function extractSeatFlag(args) {
|
|
|
46887
47944
|
var SeatFlagError = class extends Error {
|
|
46888
47945
|
};
|
|
46889
47946
|
function formatCommandSchema(output) {
|
|
46890
|
-
const record2 =
|
|
47947
|
+
const record2 = asRecord3(output);
|
|
46891
47948
|
const lines = [
|
|
46892
47949
|
`${field2(record2, "id")} \u2014 ${field2(record2, "title")}`,
|
|
46893
47950
|
field2(record2, "description"),
|
|
@@ -46912,16 +47969,16 @@ function formatCommandSchema(output) {
|
|
|
46912
47969
|
return lines.join("\n");
|
|
46913
47970
|
}
|
|
46914
47971
|
function formatCommandList(output) {
|
|
46915
|
-
const commands = Array.isArray(
|
|
47972
|
+
const commands = Array.isArray(asRecord3(output).commands) ? asRecord3(output).commands : [];
|
|
46916
47973
|
if (commands.length === 0) {
|
|
46917
47974
|
return "No commands registered.";
|
|
46918
47975
|
}
|
|
46919
47976
|
return commands.map((entry) => {
|
|
46920
|
-
const record2 =
|
|
47977
|
+
const record2 = asRecord3(entry);
|
|
46921
47978
|
return `${field2(record2, "id")} [${field2(record2, "required_scope")}/${field2(record2, "confirmation")}] ${field2(record2, "title")}`;
|
|
46922
47979
|
}).join("\n");
|
|
46923
47980
|
}
|
|
46924
|
-
function
|
|
47981
|
+
function asRecord3(value) {
|
|
46925
47982
|
return typeof value === "object" && value !== null ? value : {};
|
|
46926
47983
|
}
|
|
46927
47984
|
function asStringArray(value) {
|
|
@@ -46982,7 +48039,7 @@ async function executeMcp(io, client, appUrl2, args, env = process.env) {
|
|
|
46982
48039
|
return 1;
|
|
46983
48040
|
}
|
|
46984
48041
|
if (error51 instanceof CommandClientError) {
|
|
46985
|
-
return
|
|
48042
|
+
return printCommandError2(io, error51);
|
|
46986
48043
|
}
|
|
46987
48044
|
io.stderr.write(`${redactForLog(error51 instanceof Error ? error51.message : String(error51))}
|
|
46988
48045
|
`);
|
|
@@ -47038,30 +48095,30 @@ async function printCommandOutput(io, client, commandId, body = {}, format, opti
|
|
|
47038
48095
|
return 0;
|
|
47039
48096
|
} catch (error51) {
|
|
47040
48097
|
if (io.interactive === true) {
|
|
47041
|
-
const pending =
|
|
48098
|
+
const pending = pendingConfirmationFromError2(error51);
|
|
47042
48099
|
if (pending && pending.commandId === commandId) {
|
|
47043
48100
|
io.stderr.write(`Approving ${pending.commandId} confirmation ${pending.confirmationId} as the interactive CLI user.
|
|
47044
48101
|
`);
|
|
47045
48102
|
try {
|
|
47046
48103
|
const approved = await client.execute("confirmation.approve", { confirmation_id: pending.confirmationId });
|
|
47047
|
-
const approvedOutput =
|
|
48104
|
+
const approvedOutput = asRecord3(approved.output).output ?? approved.output;
|
|
47048
48105
|
const rendered = format ? format(approvedOutput) : JSON.stringify(approvedOutput, null, 2);
|
|
47049
48106
|
io.stdout.write(`${rendered}
|
|
47050
48107
|
`);
|
|
47051
48108
|
return 0;
|
|
47052
48109
|
} catch (approvalError) {
|
|
47053
|
-
return
|
|
48110
|
+
return printCommandError2(io, approvalError);
|
|
47054
48111
|
}
|
|
47055
48112
|
}
|
|
47056
48113
|
}
|
|
47057
|
-
return
|
|
48114
|
+
return printCommandError2(io, error51);
|
|
47058
48115
|
}
|
|
47059
48116
|
}
|
|
47060
|
-
function
|
|
48117
|
+
function pendingConfirmationFromError2(error51) {
|
|
47061
48118
|
if (!(error51 instanceof CommandClientError) || !error51.response || error51.response.ok || error51.response.error.code !== "COMMAND_CONFIRMATION_REQUIRED") {
|
|
47062
48119
|
return null;
|
|
47063
48120
|
}
|
|
47064
|
-
const details =
|
|
48121
|
+
const details = asRecord3(error51.response.error.details);
|
|
47065
48122
|
const confirmationId = details.confirmationId;
|
|
47066
48123
|
const commandId = details.commandId;
|
|
47067
48124
|
if (typeof confirmationId !== "string" || confirmationId.length === 0 || typeof commandId !== "string" || commandId.length === 0) {
|
|
@@ -47069,7 +48126,7 @@ function pendingConfirmationFromError(error51) {
|
|
|
47069
48126
|
}
|
|
47070
48127
|
return { confirmationId, commandId };
|
|
47071
48128
|
}
|
|
47072
|
-
function
|
|
48129
|
+
function printCommandError2(io, error51) {
|
|
47073
48130
|
if (error51 instanceof CommandClientError && error51.response && !error51.response.ok) {
|
|
47074
48131
|
const help = error51.response.error.help;
|
|
47075
48132
|
const requestId = error51.response.requestId;
|
|
@@ -47106,7 +48163,7 @@ function parseJsonBody(args) {
|
|
|
47106
48163
|
return JSON.parse(body);
|
|
47107
48164
|
}
|
|
47108
48165
|
function isCommand(value) {
|
|
47109
|
-
return value === "login" || value === "logout" || value === "signup" || value === "whoami" || value === "tenants" || value === "use" || value === "command" || value === "onboard" || value === "mcp" || value === "init" || value === "docs" || value === "reference" || value === "help";
|
|
48166
|
+
return value === "login" || value === "logout" || value === "signup" || value === "whoami" || value === "tenants" || value === "use" || value === "command" || value === "onboard" || value === "mcp" || value === "skills" || value === "init" || value === "docs" || value === "reference" || value === "help";
|
|
47110
48167
|
}
|
|
47111
48168
|
function printUsage(io) {
|
|
47112
48169
|
io.stdout.write([
|
|
@@ -47126,6 +48183,7 @@ function printUsage(io) {
|
|
|
47126
48183
|
`${cliBrand.binName} mcp install --client claude-code|codex|cursor --scope tenant-admin|seat [--seat-id <id>] [--expires-in <days>|--no-expiry] [--skip-permissions]`,
|
|
47127
48184
|
`${cliBrand.binName} mcp install --client claude-code|codex|cursor --rotate <old-token-id> (inherits the old token's scope; no --scope)`,
|
|
47128
48185
|
`${cliBrand.binName} mcp install ... --skip-permissions (or ${cliBrand.envPrefix}_CLI_SKIP_PERMISSIONS=1 \u2014 auto-approves the token-mint confirmation in a non-interactive session)`,
|
|
48186
|
+
skillsUsage2(cliBrand.binName),
|
|
47129
48187
|
`${cliBrand.binName} init [--client claude-code|codex|cursor] (defaults --scope tenant-admin)`,
|
|
47130
48188
|
`${cliBrand.binName} docs`,
|
|
47131
48189
|
`${cliBrand.binName} reference <list|search|get> [options]`,
|