@rosthq/cli 0.7.67 → 0.7.69
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/generated/command-manifest.d.ts.map +1 -1
- package/dist/generator/flags.d.ts.map +1 -1
- package/dist/generator/groups.d.ts.map +1 -1
- package/dist/index.js +363 -171
- package/dist/index.js.map +4 -4
- package/dist/update-check.d.ts +11 -1
- package/dist/update-check.d.ts.map +1 -1
- package/package.json +1 -1
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(path8, preserveJsx) {
|
|
476
|
+
if (typeof path8 === "string" && /^\.\.?\//.test(path8)) {
|
|
477
|
+
return path8.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 path8;
|
|
482
482
|
}
|
|
483
483
|
var extendStatics, __assign, __createBinding, __setModuleDefault, ownKeys, _SuppressedError, tslib_es6_default;
|
|
484
484
|
var init_tslib_es6 = __esm({
|
|
@@ -14027,10 +14027,10 @@ function mergeDefs(...defs) {
|
|
|
14027
14027
|
function cloneDef(schema) {
|
|
14028
14028
|
return mergeDefs(schema._zod.def);
|
|
14029
14029
|
}
|
|
14030
|
-
function getElementAtPath(obj,
|
|
14031
|
-
if (!
|
|
14030
|
+
function getElementAtPath(obj, path8) {
|
|
14031
|
+
if (!path8)
|
|
14032
14032
|
return obj;
|
|
14033
|
-
return
|
|
14033
|
+
return path8.reduce((acc, key) => acc?.[key], obj);
|
|
14034
14034
|
}
|
|
14035
14035
|
function promiseAllObject(promisesObj) {
|
|
14036
14036
|
const keys = Object.keys(promisesObj);
|
|
@@ -14439,11 +14439,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
14439
14439
|
}
|
|
14440
14440
|
return false;
|
|
14441
14441
|
}
|
|
14442
|
-
function prefixIssues(
|
|
14442
|
+
function prefixIssues(path8, issues) {
|
|
14443
14443
|
return issues.map((iss) => {
|
|
14444
14444
|
var _a3;
|
|
14445
14445
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
14446
|
-
iss.path.unshift(
|
|
14446
|
+
iss.path.unshift(path8);
|
|
14447
14447
|
return iss;
|
|
14448
14448
|
});
|
|
14449
14449
|
}
|
|
@@ -14590,16 +14590,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
|
|
|
14590
14590
|
}
|
|
14591
14591
|
function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
14592
14592
|
const fieldErrors = { _errors: [] };
|
|
14593
|
-
const processError = (error52,
|
|
14593
|
+
const processError = (error52, path8 = []) => {
|
|
14594
14594
|
for (const issue2 of error52.issues) {
|
|
14595
14595
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
14596
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
14596
|
+
issue2.errors.map((issues) => processError({ issues }, [...path8, ...issue2.path]));
|
|
14597
14597
|
} else if (issue2.code === "invalid_key") {
|
|
14598
|
-
processError({ issues: issue2.issues }, [...
|
|
14598
|
+
processError({ issues: issue2.issues }, [...path8, ...issue2.path]);
|
|
14599
14599
|
} else if (issue2.code === "invalid_element") {
|
|
14600
|
-
processError({ issues: issue2.issues }, [...
|
|
14600
|
+
processError({ issues: issue2.issues }, [...path8, ...issue2.path]);
|
|
14601
14601
|
} else {
|
|
14602
|
-
const fullpath = [...
|
|
14602
|
+
const fullpath = [...path8, ...issue2.path];
|
|
14603
14603
|
if (fullpath.length === 0) {
|
|
14604
14604
|
fieldErrors._errors.push(mapper(issue2));
|
|
14605
14605
|
} else {
|
|
@@ -14626,17 +14626,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
|
14626
14626
|
}
|
|
14627
14627
|
function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
14628
14628
|
const result = { errors: [] };
|
|
14629
|
-
const processError = (error52,
|
|
14629
|
+
const processError = (error52, path8 = []) => {
|
|
14630
14630
|
var _a3, _b;
|
|
14631
14631
|
for (const issue2 of error52.issues) {
|
|
14632
14632
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
14633
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
14633
|
+
issue2.errors.map((issues) => processError({ issues }, [...path8, ...issue2.path]));
|
|
14634
14634
|
} else if (issue2.code === "invalid_key") {
|
|
14635
|
-
processError({ issues: issue2.issues }, [...
|
|
14635
|
+
processError({ issues: issue2.issues }, [...path8, ...issue2.path]);
|
|
14636
14636
|
} else if (issue2.code === "invalid_element") {
|
|
14637
|
-
processError({ issues: issue2.issues }, [...
|
|
14637
|
+
processError({ issues: issue2.issues }, [...path8, ...issue2.path]);
|
|
14638
14638
|
} else {
|
|
14639
|
-
const fullpath = [...
|
|
14639
|
+
const fullpath = [...path8, ...issue2.path];
|
|
14640
14640
|
if (fullpath.length === 0) {
|
|
14641
14641
|
result.errors.push(mapper(issue2));
|
|
14642
14642
|
continue;
|
|
@@ -14668,8 +14668,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
|
14668
14668
|
}
|
|
14669
14669
|
function toDotPath(_path) {
|
|
14670
14670
|
const segs = [];
|
|
14671
|
-
const
|
|
14672
|
-
for (const seg of
|
|
14671
|
+
const path8 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
14672
|
+
for (const seg of path8) {
|
|
14673
14673
|
if (typeof seg === "number")
|
|
14674
14674
|
segs.push(`[${seg}]`);
|
|
14675
14675
|
else if (typeof seg === "symbol")
|
|
@@ -27361,13 +27361,13 @@ function resolveRef(ref, ctx) {
|
|
|
27361
27361
|
if (!ref.startsWith("#")) {
|
|
27362
27362
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
27363
27363
|
}
|
|
27364
|
-
const
|
|
27365
|
-
if (
|
|
27364
|
+
const path8 = ref.slice(1).split("/").filter(Boolean);
|
|
27365
|
+
if (path8.length === 0) {
|
|
27366
27366
|
return ctx.rootSchema;
|
|
27367
27367
|
}
|
|
27368
27368
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
27369
|
-
if (
|
|
27370
|
-
const key =
|
|
27369
|
+
if (path8[0] === defsKey) {
|
|
27370
|
+
const key = path8[1];
|
|
27371
27371
|
if (!key || !ctx.defs[key]) {
|
|
27372
27372
|
throw new Error(`Reference not found: ${ref}`);
|
|
27373
27373
|
}
|
|
@@ -27829,7 +27829,7 @@ var CommandClient = class {
|
|
|
27829
27829
|
this.fetchImpl = options.fetchImpl ?? fetch;
|
|
27830
27830
|
}
|
|
27831
27831
|
async execute(commandId, body = {}, options = {}) {
|
|
27832
|
-
const
|
|
27832
|
+
const path8 = `/api/commands/${encodeURIComponent(commandId)}`;
|
|
27833
27833
|
const headers = {
|
|
27834
27834
|
authorization: `Bearer ${this.token}`,
|
|
27835
27835
|
"content-type": "application/json"
|
|
@@ -27837,7 +27837,7 @@ var CommandClient = class {
|
|
|
27837
27837
|
if (options.targetSeatId !== void 0 && options.targetSeatId.length > 0) {
|
|
27838
27838
|
headers["x-rost-seat"] = options.targetSeatId;
|
|
27839
27839
|
}
|
|
27840
|
-
const response = await this.fetchImpl(`${this.appUrl}${
|
|
27840
|
+
const response = await this.fetchImpl(`${this.appUrl}${path8}`, {
|
|
27841
27841
|
method: "POST",
|
|
27842
27842
|
headers,
|
|
27843
27843
|
body: JSON.stringify(body)
|
|
@@ -27850,7 +27850,7 @@ var CommandClient = class {
|
|
|
27850
27850
|
const snippet = redactSecrets(text.replace(/\s+/g, " ").trim()).slice(0, 200);
|
|
27851
27851
|
throw new CommandClientError(
|
|
27852
27852
|
response.status,
|
|
27853
|
-
`server returned HTTP ${response.status} (non-JSON) from ${
|
|
27853
|
+
`server returned HTTP ${response.status} (non-JSON) from ${path8}` + (snippet ? ` \u2014 ${snippet}` : "") + " \u2014 the deployment may be unhealthy"
|
|
27854
27854
|
);
|
|
27855
27855
|
}
|
|
27856
27856
|
const parsed = commandResponseSchema.parse(raw);
|
|
@@ -33181,8 +33181,8 @@ var IcebergError = class extends Error {
|
|
|
33181
33181
|
return this.status === 419;
|
|
33182
33182
|
}
|
|
33183
33183
|
};
|
|
33184
|
-
function buildUrl(baseUrl,
|
|
33185
|
-
const url2 = new URL(
|
|
33184
|
+
function buildUrl(baseUrl, path8, query) {
|
|
33185
|
+
const url2 = new URL(path8, baseUrl);
|
|
33186
33186
|
if (query) {
|
|
33187
33187
|
for (const [key, value] of Object.entries(query)) {
|
|
33188
33188
|
if (value !== void 0) {
|
|
@@ -33212,12 +33212,12 @@ function createFetchClient(options) {
|
|
|
33212
33212
|
return {
|
|
33213
33213
|
async request({
|
|
33214
33214
|
method,
|
|
33215
|
-
path:
|
|
33215
|
+
path: path8,
|
|
33216
33216
|
query,
|
|
33217
33217
|
body,
|
|
33218
33218
|
headers
|
|
33219
33219
|
}) {
|
|
33220
|
-
const url2 = buildUrl(options.baseUrl,
|
|
33220
|
+
const url2 = buildUrl(options.baseUrl, path8, query);
|
|
33221
33221
|
const authHeaders = await buildAuthHeaders(options.auth);
|
|
33222
33222
|
const res = await fetchFn(url2, {
|
|
33223
33223
|
method,
|
|
@@ -34079,7 +34079,7 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
34079
34079
|
* @param path The relative file path. Should be of the format `folder/subfolder/filename.png`. The bucket must already exist before attempting to upload.
|
|
34080
34080
|
* @param fileBody The body of the file to be stored in the bucket.
|
|
34081
34081
|
*/
|
|
34082
|
-
async uploadOrUpdate(method,
|
|
34082
|
+
async uploadOrUpdate(method, path8, fileBody, fileOptions) {
|
|
34083
34083
|
var _this = this;
|
|
34084
34084
|
return _this.handleOperation(async () => {
|
|
34085
34085
|
let body;
|
|
@@ -34103,7 +34103,7 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
34103
34103
|
if ((typeof ReadableStream !== "undefined" && body instanceof ReadableStream || body && typeof body === "object" && "pipe" in body && typeof body.pipe === "function") && !options.duplex) options.duplex = "half";
|
|
34104
34104
|
}
|
|
34105
34105
|
if (fileOptions === null || fileOptions === void 0 ? void 0 : fileOptions.headers) for (const [key, value] of Object.entries(fileOptions.headers)) headers = setHeader(headers, key, value);
|
|
34106
|
-
const cleanPath = _this._removeEmptyFolders(
|
|
34106
|
+
const cleanPath = _this._removeEmptyFolders(path8);
|
|
34107
34107
|
const _path = _this._getFinalPath(cleanPath);
|
|
34108
34108
|
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 } : {}));
|
|
34109
34109
|
return {
|
|
@@ -34180,8 +34180,8 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
34180
34180
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
34181
34181
|
* - 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.
|
|
34182
34182
|
*/
|
|
34183
|
-
async upload(
|
|
34184
|
-
return this.uploadOrUpdate("POST",
|
|
34183
|
+
async upload(path8, fileBody, fileOptions) {
|
|
34184
|
+
return this.uploadOrUpdate("POST", path8, fileBody, fileOptions);
|
|
34185
34185
|
}
|
|
34186
34186
|
/**
|
|
34187
34187
|
* Upload a file with a token generated from `createSignedUploadUrl`.
|
|
@@ -34221,9 +34221,9 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
34221
34221
|
* - `objects` table permissions: none
|
|
34222
34222
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
34223
34223
|
*/
|
|
34224
|
-
async uploadToSignedUrl(
|
|
34224
|
+
async uploadToSignedUrl(path8, token, fileBody, fileOptions) {
|
|
34225
34225
|
var _this3 = this;
|
|
34226
|
-
const cleanPath = _this3._removeEmptyFolders(
|
|
34226
|
+
const cleanPath = _this3._removeEmptyFolders(path8);
|
|
34227
34227
|
const _path = _this3._getFinalPath(cleanPath);
|
|
34228
34228
|
const url2 = new URL(_this3.url + `/object/upload/sign/${_path}`);
|
|
34229
34229
|
url2.searchParams.set("token", token);
|
|
@@ -34292,10 +34292,10 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
34292
34292
|
* - `objects` table permissions: `insert`
|
|
34293
34293
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
34294
34294
|
*/
|
|
34295
|
-
async createSignedUploadUrl(
|
|
34295
|
+
async createSignedUploadUrl(path8, options) {
|
|
34296
34296
|
var _this4 = this;
|
|
34297
34297
|
return _this4.handleOperation(async () => {
|
|
34298
|
-
let _path = _this4._getFinalPath(
|
|
34298
|
+
let _path = _this4._getFinalPath(path8);
|
|
34299
34299
|
const headers = _objectSpread22({}, _this4.headers);
|
|
34300
34300
|
if (options === null || options === void 0 ? void 0 : options.upsert) headers["x-upsert"] = "true";
|
|
34301
34301
|
const data = await post(_this4.fetch, `${_this4.url}/object/upload/sign/${_path}`, {}, { headers });
|
|
@@ -34304,7 +34304,7 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
34304
34304
|
if (!token) throw new StorageError("No token returned by API");
|
|
34305
34305
|
return {
|
|
34306
34306
|
signedUrl: url2.toString(),
|
|
34307
|
-
path:
|
|
34307
|
+
path: path8,
|
|
34308
34308
|
token
|
|
34309
34309
|
};
|
|
34310
34310
|
});
|
|
@@ -34364,8 +34364,8 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
34364
34364
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
34365
34365
|
* - 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.
|
|
34366
34366
|
*/
|
|
34367
|
-
async update(
|
|
34368
|
-
return this.uploadOrUpdate("PUT",
|
|
34367
|
+
async update(path8, fileBody, fileOptions) {
|
|
34368
|
+
return this.uploadOrUpdate("PUT", path8, fileBody, fileOptions);
|
|
34369
34369
|
}
|
|
34370
34370
|
/**
|
|
34371
34371
|
* Moves an existing file to a new path in the same bucket.
|
|
@@ -34516,10 +34516,10 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
34516
34516
|
* - `objects` table permissions: `select`
|
|
34517
34517
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
34518
34518
|
*/
|
|
34519
|
-
async createSignedUrl(
|
|
34519
|
+
async createSignedUrl(path8, expiresIn, options) {
|
|
34520
34520
|
var _this8 = this;
|
|
34521
34521
|
return _this8.handleOperation(async () => {
|
|
34522
|
-
let _path = _this8._getFinalPath(
|
|
34522
|
+
let _path = _this8._getFinalPath(path8);
|
|
34523
34523
|
const hasTransform = typeof (options === null || options === void 0 ? void 0 : options.transform) === "object" && options.transform !== null && Object.keys(options.transform).length > 0;
|
|
34524
34524
|
let data = await post(_this8.fetch, `${_this8.url}/object/sign/${_path}`, _objectSpread22({ expiresIn }, hasTransform ? { transform: options.transform } : {}), { headers: _this8.headers });
|
|
34525
34525
|
const query = new URLSearchParams();
|
|
@@ -34655,13 +34655,13 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
34655
34655
|
* - `objects` table permissions: `select`
|
|
34656
34656
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
34657
34657
|
*/
|
|
34658
|
-
download(
|
|
34658
|
+
download(path8, options, parameters) {
|
|
34659
34659
|
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";
|
|
34660
34660
|
const query = new URLSearchParams();
|
|
34661
34661
|
if (options === null || options === void 0 ? void 0 : options.transform) this.applyTransformOptsToQuery(query, options.transform);
|
|
34662
34662
|
if ((options === null || options === void 0 ? void 0 : options.cacheNonce) != null) query.set("cacheNonce", String(options.cacheNonce));
|
|
34663
34663
|
const queryString = query.toString();
|
|
34664
|
-
const _path = this._getFinalPath(
|
|
34664
|
+
const _path = this._getFinalPath(path8);
|
|
34665
34665
|
const downloadFn = () => get(this.fetch, `${this.url}/${renderPath}/${_path}${queryString ? `?${queryString}` : ""}`, {
|
|
34666
34666
|
headers: this.headers,
|
|
34667
34667
|
noResolveJson: true
|
|
@@ -34692,9 +34692,9 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
34692
34692
|
* }
|
|
34693
34693
|
* ```
|
|
34694
34694
|
*/
|
|
34695
|
-
async info(
|
|
34695
|
+
async info(path8) {
|
|
34696
34696
|
var _this10 = this;
|
|
34697
|
-
const _path = _this10._getFinalPath(
|
|
34697
|
+
const _path = _this10._getFinalPath(path8);
|
|
34698
34698
|
return _this10.handleOperation(async () => {
|
|
34699
34699
|
return recursiveToCamel(await get(_this10.fetch, `${_this10.url}/object/info/${_path}`, { headers: _this10.headers }));
|
|
34700
34700
|
});
|
|
@@ -34715,9 +34715,9 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
34715
34715
|
* .exists('folder/avatar1.png')
|
|
34716
34716
|
* ```
|
|
34717
34717
|
*/
|
|
34718
|
-
async exists(
|
|
34718
|
+
async exists(path8) {
|
|
34719
34719
|
var _this11 = this;
|
|
34720
|
-
const _path = _this11._getFinalPath(
|
|
34720
|
+
const _path = _this11._getFinalPath(path8);
|
|
34721
34721
|
try {
|
|
34722
34722
|
await head(_this11.fetch, `${_this11.url}/object/${_path}`, { headers: _this11.headers });
|
|
34723
34723
|
return {
|
|
@@ -34796,8 +34796,8 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
34796
34796
|
* - `objects` table permissions: none
|
|
34797
34797
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
34798
34798
|
*/
|
|
34799
|
-
getPublicUrl(
|
|
34800
|
-
const _path = this._getFinalPath(
|
|
34799
|
+
getPublicUrl(path8, options) {
|
|
34800
|
+
const _path = this._getFinalPath(path8);
|
|
34801
34801
|
const query = new URLSearchParams();
|
|
34802
34802
|
if (options === null || options === void 0 ? void 0 : options.download) query.set("download", options.download === true ? "" : options.download);
|
|
34803
34803
|
if (options === null || options === void 0 ? void 0 : options.transform) this.applyTransformOptsToQuery(query, options.transform);
|
|
@@ -34936,10 +34936,10 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
34936
34936
|
* - `objects` table permissions: `select`
|
|
34937
34937
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
34938
34938
|
*/
|
|
34939
|
-
async list(
|
|
34939
|
+
async list(path8, options, parameters) {
|
|
34940
34940
|
var _this13 = this;
|
|
34941
34941
|
return _this13.handleOperation(async () => {
|
|
34942
|
-
const body = _objectSpread22(_objectSpread22(_objectSpread22({}, DEFAULT_SEARCH_OPTIONS), options), {}, { prefix:
|
|
34942
|
+
const body = _objectSpread22(_objectSpread22(_objectSpread22({}, DEFAULT_SEARCH_OPTIONS), options), {}, { prefix: path8 || "" });
|
|
34943
34943
|
return await post(_this13.fetch, `${_this13.url}/object/list/${_this13.bucketId}`, body, { headers: _this13.headers }, parameters);
|
|
34944
34944
|
});
|
|
34945
34945
|
}
|
|
@@ -35004,11 +35004,11 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
35004
35004
|
if (typeof Buffer !== "undefined") return Buffer.from(data).toString("base64");
|
|
35005
35005
|
return btoa(data);
|
|
35006
35006
|
}
|
|
35007
|
-
_getFinalPath(
|
|
35008
|
-
return `${this.bucketId}/${
|
|
35007
|
+
_getFinalPath(path8) {
|
|
35008
|
+
return `${this.bucketId}/${path8.replace(/^\/+/, "")}`;
|
|
35009
35009
|
}
|
|
35010
|
-
_removeEmptyFolders(
|
|
35011
|
-
return
|
|
35010
|
+
_removeEmptyFolders(path8) {
|
|
35011
|
+
return path8.replace(/^\/|\/$/g, "").replace(/\/+/g, "/");
|
|
35012
35012
|
}
|
|
35013
35013
|
/** Modifies the `query`, appending values the from `transform` */
|
|
35014
35014
|
applyTransformOptsToQuery(query, transform2) {
|
|
@@ -40844,14 +40844,19 @@ var goalListAtRiskOutputSchema = external_exports.object({
|
|
|
40844
40844
|
}).strict();
|
|
40845
40845
|
var goalSignalStateSchema = external_exports.enum(["ok", "risk", "crit", "pending"]);
|
|
40846
40846
|
var goalStatusSourceSchema = external_exports.enum(["human", "agent", "rollup", "signal"]);
|
|
40847
|
+
var goalMeasurableRoleSchema = external_exports.enum(["drives_status", "informs"]);
|
|
40847
40848
|
var goalBindMeasurableInputSchema = external_exports.object({
|
|
40848
40849
|
goal_id: uuidSchema8,
|
|
40849
|
-
measurable_id: uuidSchema8
|
|
40850
|
+
measurable_id: uuidSchema8,
|
|
40851
|
+
// DER-1643: new operator bindings default to the conservative 'informs' role.
|
|
40852
|
+
// 'drives_status' is the deliberate leaf-only status driver (childless goal only,
|
|
40853
|
+
// one per goal) and stays human-confirmed.
|
|
40854
|
+
role: goalMeasurableRoleSchema.default("informs")
|
|
40850
40855
|
}).strict();
|
|
40851
40856
|
var goalBindMeasurableOutputSchema = external_exports.object({
|
|
40852
40857
|
goal_id: uuidSchema8,
|
|
40853
40858
|
measurable_id: uuidSchema8,
|
|
40854
|
-
role:
|
|
40859
|
+
role: goalMeasurableRoleSchema,
|
|
40855
40860
|
// Per-binding steward opt-in; a fresh binding is always created OFF.
|
|
40856
40861
|
auto_status_enabled: external_exports.boolean(),
|
|
40857
40862
|
// The current signal indicator + the status it would compute (surfaced even
|
|
@@ -40868,7 +40873,9 @@ var goalBindMeasurableOutputSchema = external_exports.object({
|
|
|
40868
40873
|
}).strict();
|
|
40869
40874
|
var goalUnbindMeasurableInputSchema = external_exports.object({
|
|
40870
40875
|
goal_id: uuidSchema8,
|
|
40871
|
-
measurable_id: uuidSchema8
|
|
40876
|
+
measurable_id: uuidSchema8,
|
|
40877
|
+
// Which binding to remove; defaults to the status driver (the historical unbind).
|
|
40878
|
+
role: goalMeasurableRoleSchema.default("drives_status")
|
|
40872
40879
|
}).strict();
|
|
40873
40880
|
var goalUnbindMeasurableOutputSchema = external_exports.object({
|
|
40874
40881
|
goal_id: uuidSchema8,
|
|
@@ -40912,6 +40919,23 @@ var goalListMeasurablesOutputSchema = external_exports.object({
|
|
|
40912
40919
|
goal_id: uuidSchema8,
|
|
40913
40920
|
bindings: external_exports.array(goalMeasurableBindingSchema)
|
|
40914
40921
|
}).strict();
|
|
40922
|
+
var goalCoreSchema = external_exports.object({
|
|
40923
|
+
id: uuidSchema8,
|
|
40924
|
+
title: external_exports.string(),
|
|
40925
|
+
kind: external_exports.enum(["objective", "cycle_goal", "company_objective", "seat_goal", "milestone"]),
|
|
40926
|
+
status: goalStatusSchema,
|
|
40927
|
+
status_source: goalStatusSourceSchema,
|
|
40928
|
+
progress_pct: external_exports.number().int().min(0).max(100).nullable(),
|
|
40929
|
+
seat_id: uuidSchema8.nullable(),
|
|
40930
|
+
parent_goal_id: uuidSchema8.nullable(),
|
|
40931
|
+
definition_of_done: external_exports.string()
|
|
40932
|
+
}).strict();
|
|
40933
|
+
var goalGetInputSchema = external_exports.object({
|
|
40934
|
+
goal_id: uuidSchema8
|
|
40935
|
+
}).strict();
|
|
40936
|
+
var goalGetOutputSchema = external_exports.object({
|
|
40937
|
+
goal: goalCoreSchema
|
|
40938
|
+
}).strict();
|
|
40915
40939
|
var issueStatusSchema = external_exports.enum(["open", "diagnosing", "resolved", "dropped"]);
|
|
40916
40940
|
var frictionListInputSchema = external_exports.object({
|
|
40917
40941
|
status: external_exports.enum(["open", "diagnosing", "resolved", "dropped", "active", "all"]).optional()
|
|
@@ -40934,6 +40958,28 @@ var frictionIssueSummarySchema = external_exports.object({
|
|
|
40934
40958
|
var frictionListOutputSchema = external_exports.object({
|
|
40935
40959
|
issues: external_exports.array(frictionIssueSummarySchema)
|
|
40936
40960
|
}).strict();
|
|
40961
|
+
var frictionIssueDetailSchema = frictionIssueSummarySchema.extend({
|
|
40962
|
+
raised_by_seat_type: external_exports.enum(["human", "agent", "hybrid"]),
|
|
40963
|
+
raised_by_seat_steward_name: external_exports.string().nullable(),
|
|
40964
|
+
origin_actor_kind: external_exports.enum(["user", "agent", "system"]).nullable(),
|
|
40965
|
+
origin_actor_id: uuidSchema8.nullable(),
|
|
40966
|
+
evidence: external_exports.unknown(),
|
|
40967
|
+
action_task_title: external_exports.string().nullable(),
|
|
40968
|
+
action_task_owner_seat_id: uuidSchema8.nullable(),
|
|
40969
|
+
action_task_owner_seat_name: external_exports.string().nullable(),
|
|
40970
|
+
action_task_due_on: external_exports.string().nullable(),
|
|
40971
|
+
decision_id: uuidSchema8.nullable(),
|
|
40972
|
+
decision_title: external_exports.string().nullable(),
|
|
40973
|
+
decision_summary: external_exports.string().nullable(),
|
|
40974
|
+
decided_by_name: external_exports.string().nullable(),
|
|
40975
|
+
updated_at: external_exports.string()
|
|
40976
|
+
}).strict();
|
|
40977
|
+
var frictionGetInputSchema = external_exports.object({
|
|
40978
|
+
issue_id: uuidSchema8
|
|
40979
|
+
}).strict();
|
|
40980
|
+
var frictionGetOutputSchema = external_exports.object({
|
|
40981
|
+
issue: frictionIssueDetailSchema
|
|
40982
|
+
}).strict();
|
|
40937
40983
|
var frictionUpdateStatusInputSchema = external_exports.object({
|
|
40938
40984
|
issue_id: uuidSchema8,
|
|
40939
40985
|
status: external_exports.enum(["open", "diagnosing"])
|
|
@@ -40945,17 +40991,34 @@ var frictionUpdateStatusOutputSchema = external_exports.object({
|
|
|
40945
40991
|
}).strict();
|
|
40946
40992
|
var frictionResolveInputSchema = external_exports.object({
|
|
40947
40993
|
issue_id: uuidSchema8,
|
|
40994
|
+
resolution_mode: external_exports.enum(["ids", "already_fixed"]).default("ids"),
|
|
40948
40995
|
root_cause: external_exports.string().trim().min(1),
|
|
40949
|
-
owner_seat_id: uuidSchema8,
|
|
40950
|
-
task_title: external_exports.string().trim().min(1),
|
|
40951
|
-
task_description: external_exports.string().trim().min(1),
|
|
40952
|
-
done_by: dateOnlySchema,
|
|
40996
|
+
owner_seat_id: uuidSchema8.optional(),
|
|
40997
|
+
task_title: external_exports.string().trim().min(1).optional(),
|
|
40998
|
+
task_description: external_exports.string().trim().min(1).optional(),
|
|
40999
|
+
done_by: dateOnlySchema.optional(),
|
|
40953
41000
|
resolving_seat_id: uuidSchema8.optional()
|
|
40954
|
-
}).strict()
|
|
41001
|
+
}).strict().superRefine((value, ctx) => {
|
|
41002
|
+
if (value.resolution_mode !== "ids") {
|
|
41003
|
+
return;
|
|
41004
|
+
}
|
|
41005
|
+
if (value.owner_seat_id === void 0) {
|
|
41006
|
+
ctx.addIssue({ code: "custom", path: ["owner_seat_id"], message: 'Required for resolution_mode "ids".' });
|
|
41007
|
+
}
|
|
41008
|
+
if (value.task_title === void 0) {
|
|
41009
|
+
ctx.addIssue({ code: "custom", path: ["task_title"], message: 'Required for resolution_mode "ids".' });
|
|
41010
|
+
}
|
|
41011
|
+
if (value.task_description === void 0) {
|
|
41012
|
+
ctx.addIssue({ code: "custom", path: ["task_description"], message: 'Required for resolution_mode "ids".' });
|
|
41013
|
+
}
|
|
41014
|
+
if (value.done_by === void 0) {
|
|
41015
|
+
ctx.addIssue({ code: "custom", path: ["done_by"], message: 'Required for resolution_mode "ids".' });
|
|
41016
|
+
}
|
|
41017
|
+
});
|
|
40955
41018
|
var frictionResolveOutputSchema = external_exports.object({
|
|
40956
41019
|
issue_id: uuidSchema8,
|
|
40957
41020
|
status: external_exports.literal("resolved"),
|
|
40958
|
-
action_task_id: uuidSchema8,
|
|
41021
|
+
action_task_id: uuidSchema8.nullable(),
|
|
40959
41022
|
decision_id: uuidSchema8
|
|
40960
41023
|
}).strict();
|
|
40961
41024
|
var frictionLinkTaskInputSchema = external_exports.object({
|
|
@@ -41558,6 +41621,18 @@ var compassShowMarkdownInputSchema = external_exports.object({}).strict();
|
|
|
41558
41621
|
var charterShowMarkdownInputSchema = external_exports.object({
|
|
41559
41622
|
seat_id: uuidSchema9
|
|
41560
41623
|
}).strict();
|
|
41624
|
+
var charterShowMarkdownOutputSchema = external_exports.object({
|
|
41625
|
+
markdown: external_exports.string().min(1),
|
|
41626
|
+
charter_version_id: uuidSchema9.nullable(),
|
|
41627
|
+
seat_id: uuidSchema9,
|
|
41628
|
+
version: external_exports.number().int().nonnegative().nullable(),
|
|
41629
|
+
status: external_exports.string().nullable(),
|
|
41630
|
+
doc: external_exports.unknown().nullable(),
|
|
41631
|
+
dry_run: external_exports.object({
|
|
41632
|
+
status: external_exports.enum(["passed", "failed"]),
|
|
41633
|
+
summary: external_exports.string()
|
|
41634
|
+
}).strict().nullable()
|
|
41635
|
+
}).strict();
|
|
41561
41636
|
var agentShowMarkdownInputSchema = external_exports.object({
|
|
41562
41637
|
seat_id: uuidSchema9
|
|
41563
41638
|
}).strict();
|
|
@@ -41792,6 +41867,27 @@ var confirmationRejectOutputSchema = external_exports.object({
|
|
|
41792
41867
|
command_id: external_exports.string().min(1),
|
|
41793
41868
|
rejected: external_exports.literal(true)
|
|
41794
41869
|
}).strict();
|
|
41870
|
+
var confirmationListInputSchema = external_exports.object({
|
|
41871
|
+
limit: external_exports.number().int().min(1).max(200).optional()
|
|
41872
|
+
}).strict();
|
|
41873
|
+
var confirmationSummarySchema = external_exports.object({
|
|
41874
|
+
id: uuidSchema10,
|
|
41875
|
+
command_id: external_exports.string(),
|
|
41876
|
+
redacted_args: external_exports.unknown(),
|
|
41877
|
+
actor_kind: external_exports.enum(["user", "agent", "system"]),
|
|
41878
|
+
source: external_exports.string(),
|
|
41879
|
+
scope_kind: external_exports.enum(["tenant_admin", "tenant", "seat"]),
|
|
41880
|
+
seat_id: uuidSchema10.nullable(),
|
|
41881
|
+
seat_name: external_exports.string().nullable(),
|
|
41882
|
+
seat_type: external_exports.enum(["human", "agent", "hybrid"]).nullable(),
|
|
41883
|
+
risk_level: external_exports.enum(["normal", "sensitive", "dangerous"]),
|
|
41884
|
+
summary: external_exports.string(),
|
|
41885
|
+
expires_at: external_exports.string(),
|
|
41886
|
+
created_at: external_exports.string()
|
|
41887
|
+
}).strict();
|
|
41888
|
+
var confirmationListOutputSchema = external_exports.object({
|
|
41889
|
+
confirmations: external_exports.array(confirmationSummarySchema)
|
|
41890
|
+
}).strict();
|
|
41795
41891
|
var credentialIngressInputSchema = external_exports.object({
|
|
41796
41892
|
seat_id: uuidSchema10.optional(),
|
|
41797
41893
|
provider: external_exports.string().trim().min(1),
|
|
@@ -42322,7 +42418,7 @@ var fleetDigestAgentSchema = fleetOverviewRowSchema.extend({
|
|
|
42322
42418
|
spend_7d_usd: external_exports.string(),
|
|
42323
42419
|
spend_30d_usd: external_exports.string(),
|
|
42324
42420
|
cost_drift_percent: external_exports.number().int().nullable(),
|
|
42325
|
-
health_status: external_exports.enum(["needs_review", "stale", "setup_gap", "awaiting_data", "healthy"]),
|
|
42421
|
+
health_status: external_exports.enum(["needs_review", "stale", "setup_gap", "awaiting_data", "awaiting_data_overdue", "healthy"]),
|
|
42326
42422
|
health_reasons: external_exports.array(external_exports.string()),
|
|
42327
42423
|
recent_failed_runs: external_exports.array(fleetDigestRunSchema),
|
|
42328
42424
|
unresolved_errors: external_exports.array(fleetDigestErrorSchema),
|
|
@@ -46254,7 +46350,7 @@ External connectors are being rolled out provider by provider, conservatively (r
|
|
|
46254
46350
|
order: 48,
|
|
46255
46351
|
title: "CLI and MCP installation guide",
|
|
46256
46352
|
summary: "Install the public CLI, register remote token-backed MCP clients, and find the full command and tool catalog.",
|
|
46257
|
-
version: "2026-07-12.
|
|
46353
|
+
version: "2026-07-12.3",
|
|
46258
46354
|
public: true,
|
|
46259
46355
|
audiences: ["human", "cli", "mcp", "in_app_agent"],
|
|
46260
46356
|
stages: ["company_setup", "staffing"],
|
|
@@ -46827,6 +46923,7 @@ Several rows here are seat-operating commands (\`task.create\`, the \`signal.*\`
|
|
|
46827
46923
|
| \`rost_skip_charter_draft\` | \`charter.skip\` | Mark a Charter draft as skipped. | Seat or tenant-admin | Call only when a human defers the seat. |
|
|
46828
46924
|
| \`rost_apply_charter_seat_type_recommendation\` | \`charter.apply_seat_type_recommendation\` | Apply a Charter's seat-type recommendation. | Seat or tenant-admin | Call after reviewing the draft. |
|
|
46829
46925
|
| \`rost_sign_charter_manifest\` | \`charter.sign_manifest\` | Request human confirmation for a permission manifest. | Seat or tenant-admin | Use after tool permissions are reviewed. |
|
|
46926
|
+
| \`rost_list_pending_confirmations\` | \`confirmation.list\` | List in-flight confirmations awaiting a human decision, scoped to the caller's authority (owner sees all; a member sees seats they occupy; an agent sees its own seat). | Seat or tenant-admin | Call with \`{}\`. |
|
|
46830
46927
|
| \`rost_draft_compass\` | \`compass.draft\` | Create a Compass draft. | Tenant | Call with a concise Compass document. |
|
|
46831
46928
|
| \`rost_update_compass_draft\` | \`compass.update_draft\` | Replace a Compass draft document. | Tenant | Call with the \`compass_version_id\` from \`compass.draft\` as \`draft_id\` and the updated document. |
|
|
46832
46929
|
| \`rost_approve_compass_version\` | \`compass.approve_version\` | Activate a Compass version by supersession. | Tenant | Call after human review. |
|
|
@@ -46927,18 +47024,20 @@ Several rows here are seat-operating commands (\`task.create\`, the \`signal.*\`
|
|
|
46927
47024
|
| \`rost_import_rocks_from_a_ninety_rocks_export\` | \`cascade.import\` | Bulk-import Rocks as Cascade cycle goals under a company objective in the active cycle (from a ninety Rocks export). Owners resolve to seats; idempotent re-import skips a cycle goal already imported for the same objective + seat + title. | Tenant | Call with the parsed \`rocks\` array. |
|
|
46928
47025
|
| \`rost_import_a_ninety_v_to_into_a_compass_draft\` | \`compass.import\` | AI-draft a Compass from a ninety V/TO (Core Values \u2192 principles, 10/3/1-Year \u2192 horizon goals, Rocks \u2192 cycle objectives), landed as a draft a human confirms by supersession \u2014 never an accepted Compass. Idempotent by document content (a re-upload of the same V/TO short-circuits without re-drafting). | Tenant | Call with the extracted V/TO \`text\` (and optional \`source_name\`). |
|
|
46929
47026
|
| \`rost_list_cascade_goals\` | \`goal.list\` | List Cascade goals, optionally by cycle or seat. | Seat or tenant-admin | Call with \`{}\` or \`{"cycle_id":"<id>"}\`. |
|
|
46930
|
-
| \`
|
|
47027
|
+
| \`rost_get_cascade_goal\` | \`goal.get\` | Get one goal's core detail and status by id. Seat-scoped callers may only read their own seat's goals. | Seat or tenant-admin | Call with \`{"goal_id":"<id>"}\`. |
|
|
47028
|
+
| \`rost_list_a_cascade_goals_signals\` | \`goal.list_measurables\` | List the goal's status-driving Signal binding (role drives_status; 0-or-1 per goal) with its current indicator and latest confirmed reading. Driver-only \u2014 informs bindings (direct indicators) are not returned. Read-only. | Seat or tenant-admin | Call with \`{"goal_id":"<id>"}\`. |
|
|
46931
47029
|
| \`rost_create_cascade_goal\` | \`goal.create\` | Create a cycle goal under an objective. | Tenant | Call with cycle, seat, parent, title, definition of done. |
|
|
46932
47030
|
| \`rost_update_cascade_goal\` | \`goal.update\` | Update a goal's title or definition of done. | Tenant | Call with \`goal_id\` and the changed fields. |
|
|
46933
47031
|
| \`rost_set_cascade_goal_status\` | \`goal.set_status\` | Set a goal's status (on/off/done). | Seat or tenant-admin | Seats may set only their own goals. |
|
|
46934
47032
|
| \`rost_set_cascade_goal_progress\` | \`goal.set_progress\` | Report a goal's quantified progress (0-100). An agent's progress is a proposal a human approves before the goal moves. | Seat or tenant-admin | Seats set only their own goals; expect confirmation. |
|
|
46935
|
-
| \`rost_bind_a_signal_to_a_cascade_goal\` | \`goal.bind_measurable\` | Bind a measurable to a
|
|
46936
|
-
| \`rost_unbind_a_signal_from_a_cascade_goal\` | \`goal.unbind_measurable\` | Remove a goal\u2194measurable binding. | Seat or tenant-admin | Call with \`{"goal_id":"<id>","measurable_id":"<id>"}\`. |
|
|
47033
|
+
| \`rost_bind_a_signal_to_a_cascade_goal\` | \`goal.bind_measurable\` | Bind a measurable to a goal. Defaults to role \`informs\` \u2014 a conservative indicator allowed at any goal level (many per goal) that never changes status. Pass role \`drives_status\` to make it the goal's status driver (childless leaf only, one per goal). Human-gated. | Seat or tenant-admin | Call with \`{"goal_id":"<id>","measurable_id":"<id>"}\` (add \`"role":"drives_status"\` for the driver); expect confirmation. |
|
|
47034
|
+
| \`rost_unbind_a_signal_from_a_cascade_goal\` | \`goal.unbind_measurable\` | Remove a goal\u2194measurable binding (role defaults to \`drives_status\`; pass \`"role":"informs"\` to remove an indicator). | Seat or tenant-admin | Call with \`{"goal_id":"<id>","measurable_id":"<id>"}\`. |
|
|
46937
47035
|
| \`rost_toggle_signal_driven_auto_status\` | \`goal.set_auto_status\` | Per-goal steward opt-in (default OFF) that lets the bound measurable's latest confirmed reading compute the goal's status. Enabling applies the current signal immediately. Human-gated. | Seat or tenant-admin | Call with \`{"goal_id":"<id>","enabled":true}\`; expect confirmation. |
|
|
46938
47036
|
| \`rost_list_at_risk_cascade_goals\` | \`goal.list_at_risk\` | List goals projected off pace (at-risk or projected-miss) with days behind pace. Read-only; status-only goals excluded. | Tenant | Call with \`{}\`. |
|
|
46939
47037
|
| \`rost_reparent_cascade_goal\` | \`goal.reparent\` | Move a goal under a new parent. | Tenant | Authority change; expect confirmation. |
|
|
46940
47038
|
| \`rost_drop_cascade_goal\` | \`goal.drop\` | Drop (retire) a goal, retained for audit. | Tenant | Expect confirmation. |
|
|
46941
47039
|
| \`rost_list_friction_issues\` | \`friction.list\` | List Friction issues ranked by impact and severity. | Seat or tenant-admin | Call with \`{}\` or \`{"status":"active"}\`. |
|
|
47040
|
+
| \`rost_get_friction_issue\` | \`friction.get\` | Get full detail for one Friction issue by id. | Seat or tenant-admin | Call with \`{"issue_id":"<id>"}\`. |
|
|
46942
47041
|
| \`rost_assist_friction_issue\` | \`friction.assist\` | Advisory IDS assist: the most-similar prior resolved issues with their root causes and decisions, a recurring-pattern flag, and recommended options. Read-only \u2014 it never resolves the issue. | Tenant | Call with \`{"issue_id":"<id>"}\`. |
|
|
46943
47042
|
| \`rost_update_friction_issue_status\` | \`friction.update_status\` | Move a non-terminal issue between open and diagnosing. | Seat or tenant-admin | Call with \`issue_id\` and \`status\`. |
|
|
46944
47043
|
| \`rost_resolve_friction_issue\` | \`friction.resolve\` | Resolve an issue with a root cause and remediation task. | Tenant | Human decision; expect confirmation. |
|
|
@@ -47500,7 +47599,7 @@ Retrieve the narrowest relevant guide before making a setup recommendation. Pref
|
|
|
47500
47599
|
order: 60,
|
|
47501
47600
|
title: "Cascade guide",
|
|
47502
47601
|
summary: "How to connect company goals to seat-level work without turning {{brand}} into a project-management tool.",
|
|
47503
|
-
version: "2026-07-
|
|
47602
|
+
version: "2026-07-12.1",
|
|
47504
47603
|
public: true,
|
|
47505
47604
|
audiences: ["human", "cli", "mcp", "in_app_agent"],
|
|
47506
47605
|
stages: ["operating_rhythm"],
|
|
@@ -47509,6 +47608,7 @@ Retrieve the narrowest relevant guide before making a setup recommendation. Pref
|
|
|
47509
47608
|
"compass.approve_version",
|
|
47510
47609
|
"onboarding.finish",
|
|
47511
47610
|
"goal.list",
|
|
47611
|
+
"goal.get",
|
|
47512
47612
|
"goal.create",
|
|
47513
47613
|
"goal.update",
|
|
47514
47614
|
"goal.set_status",
|
|
@@ -47578,9 +47678,9 @@ On human and function seat pages, goal visibility includes both direct goals and
|
|
|
47578
47678
|
|
|
47579
47679
|
## Drive a goal's status from a Signal
|
|
47580
47680
|
|
|
47581
|
-
A
|
|
47681
|
+
A Signal can be linked to a goal for visibility, or set to compute its status. Bind a Signal with \`goal.bind_measurable\`. By default the binding is **informative** (role \`informs\`): it appears as a direct indicator on the goal, is allowed at any level (company objective, parent, or leaf), can be one of many on the same goal, and never changes the goal's status. To let a Signal **drive** a leaf goal's status instead, bind it with \`--role drives_status\` (the goal must be a childless seat goal or milestone \u2014 a company objective or a goal with children rolls up from its children, so a driver there is rejected). A goal can have at most one driving Signal, and choosing a driver is a deliberate, human-gated act.
|
|
47582
47682
|
|
|
47583
|
-
|
|
47683
|
+
A \`drives_status\` binding starts as an indicator only: nothing changes until a steward opts in with \`goal.set_auto_status --enabled true\`. Once opted in, the goal's status is computed from the measurable's latest confirmed reading against its target and direction \u2014 on target reads on-track, below target reads off-track. Only confirmed readings drive status; an agent's draft reading never auto-flips a goal. A human who sets the status by hand pins it, and that pin wins over the computed value until they change it or re-run \`goal.set_auto_status\`. Remove a binding with \`goal.unbind_measurable\`; the goal keeps its last status. Until a binding is opted in, an off-track Signal never raises an at-risk alert on its own.
|
|
47584
47684
|
|
|
47585
47685
|
## What does not belong
|
|
47586
47686
|
|
|
@@ -47728,6 +47828,7 @@ Agents may record readings when the Charter allows it. Agent-reported readings s
|
|
|
47728
47828
|
"compass.answer_gap",
|
|
47729
47829
|
"friction.file_issue",
|
|
47730
47830
|
"friction.list",
|
|
47831
|
+
"friction.get",
|
|
47731
47832
|
"friction.assist",
|
|
47732
47833
|
"friction.update_status",
|
|
47733
47834
|
"friction.resolve",
|
|
@@ -47874,7 +47975,7 @@ Keep agent scope tight at first. Approve more autonomy only after evidence. Use
|
|
|
47874
47975
|
public: true,
|
|
47875
47976
|
audiences: ["human", "cli", "mcp", "in_app_agent"],
|
|
47876
47977
|
stages: ["graph_design", "charter_design", "staffing", "operating_rhythm"],
|
|
47877
|
-
relatedCommandIds: ["confirmation.approve", "confirmation.reject", "charter.approve", "agent.go_live", "credential.ingress", "mcp_token.create", "staffing.assign_user", "goal.reparent", "friction.resolve"],
|
|
47978
|
+
relatedCommandIds: ["confirmation.approve", "confirmation.list", "confirmation.reject", "charter.approve", "agent.go_live", "credential.ingress", "mcp_token.create", "staffing.assign_user", "goal.reparent", "friction.resolve"],
|
|
47878
47979
|
legal: { publicRisk: "low", notes: ["{{brand}}-native human-gate guidance."] },
|
|
47879
47980
|
sources: [
|
|
47880
47981
|
{
|
|
@@ -50019,6 +50120,11 @@ function helpText() {
|
|
|
50019
50120
|
].join("\n");
|
|
50020
50121
|
}
|
|
50021
50122
|
|
|
50123
|
+
// src/update-check.ts
|
|
50124
|
+
import { mkdir as mkdir2, readFile as readFile3, writeFile as writeFile2 } from "node:fs/promises";
|
|
50125
|
+
import { homedir as homedir2 } from "node:os";
|
|
50126
|
+
import path2 from "node:path";
|
|
50127
|
+
|
|
50022
50128
|
// src/cli-version.ts
|
|
50023
50129
|
import { readFile as readFile2 } from "node:fs/promises";
|
|
50024
50130
|
import { dirname as dirname2, resolve } from "node:path";
|
|
@@ -50040,15 +50146,23 @@ async function readCliVersion() {
|
|
|
50040
50146
|
var latestPackageSchema = external_exports.object({
|
|
50041
50147
|
version: external_exports.string()
|
|
50042
50148
|
});
|
|
50043
|
-
|
|
50044
|
-
|
|
50149
|
+
var updateCheckStateSchema = external_exports.object({ lastNaggedOn: external_exports.string() }).strict();
|
|
50150
|
+
async function maybePrintUpgradeNudge(io, options = {}) {
|
|
50151
|
+
if (!options.skipEnvGuard && (process.env.CI || process.env.VITEST || process.env.CLI_SKIP_UPDATE_CHECK === "1")) {
|
|
50152
|
+
return;
|
|
50153
|
+
}
|
|
50154
|
+
const statePath = options.statePath ?? defaultUpdateCheckStatePath();
|
|
50155
|
+
const today = toUtcDateOnly(options.now ?? /* @__PURE__ */ new Date());
|
|
50156
|
+
const state = await readUpdateCheckState(statePath);
|
|
50157
|
+
if (state?.lastNaggedOn === today) {
|
|
50045
50158
|
return;
|
|
50046
50159
|
}
|
|
50047
50160
|
const currentVersion = await readCliVersion();
|
|
50048
50161
|
if (!currentVersion || currentVersion === "0.0.0") {
|
|
50049
50162
|
return;
|
|
50050
50163
|
}
|
|
50051
|
-
const
|
|
50164
|
+
const fetchLatest = options.fetchLatest ?? fetchLatestVersion;
|
|
50165
|
+
const latestVersion = await fetchLatest(cliBrand.packageName);
|
|
50052
50166
|
if (!latestVersion || !isSemverBehind(currentVersion, latestVersion)) {
|
|
50053
50167
|
return;
|
|
50054
50168
|
}
|
|
@@ -50056,6 +50170,28 @@ async function maybePrintUpgradeNudge(io) {
|
|
|
50056
50170
|
`A newer ${cliBrand.binName} CLI is available: ${currentVersion} -> ${latestVersion}. Upgrade with npm i -g ${cliBrand.packageName}@latest.
|
|
50057
50171
|
`
|
|
50058
50172
|
);
|
|
50173
|
+
await writeUpdateCheckStateBestEffort(statePath, { lastNaggedOn: today });
|
|
50174
|
+
}
|
|
50175
|
+
function defaultUpdateCheckStatePath() {
|
|
50176
|
+
return path2.join(homedir2(), ".config", cliBrand.binName, "update-check.json");
|
|
50177
|
+
}
|
|
50178
|
+
function toUtcDateOnly(date5) {
|
|
50179
|
+
return date5.toISOString().slice(0, 10);
|
|
50180
|
+
}
|
|
50181
|
+
async function readUpdateCheckState(statePath) {
|
|
50182
|
+
try {
|
|
50183
|
+
return updateCheckStateSchema.parse(JSON.parse(await readFile3(statePath, "utf8")));
|
|
50184
|
+
} catch {
|
|
50185
|
+
return null;
|
|
50186
|
+
}
|
|
50187
|
+
}
|
|
50188
|
+
async function writeUpdateCheckStateBestEffort(statePath, state) {
|
|
50189
|
+
try {
|
|
50190
|
+
await mkdir2(path2.dirname(statePath), { recursive: true, mode: 448 });
|
|
50191
|
+
await writeFile2(statePath, `${JSON.stringify(state)}
|
|
50192
|
+
`, { mode: 384 });
|
|
50193
|
+
} catch {
|
|
50194
|
+
}
|
|
50059
50195
|
}
|
|
50060
50196
|
async function fetchLatestVersion(packageName) {
|
|
50061
50197
|
const controller = new AbortController();
|
|
@@ -50161,6 +50297,7 @@ var COMMAND_MANIFEST = [
|
|
|
50161
50297
|
{ "id": "compass.show_markdown", "namespace": "compass", "action": "show_markdown", "title": "Show Compass as markdown", "description": "Compose the current Compass and its open gaps into a clean, human-skimmable markdown card for review.", "requiredScope": "tenant", "confirmation": "none", "exposeOverMcp": true, "fields": [], "hasComplexInput": false, "help": "Render the current Compass and its open gaps as a clean markdown card to show your human a quick review." },
|
|
50162
50298
|
{ "id": "compass.update_draft", "namespace": "compass", "action": "update_draft", "title": "Update Compass draft", "description": "Replace a draft Compass document.", "requiredScope": "tenant", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "draft_id", "flag": "draft-id", "type": "string", "required": true }], "hasComplexInput": true, "help": "Pass the compass_version_id returned by compass.draft as draft_id; update_draft replaces only an unpublished draft in this tenant." },
|
|
50163
50299
|
{ "id": "confirmation.approve", "namespace": "confirmation", "action": "approve", "title": "Approve pending confirmation", "description": "Approve an in-flight confirmation and execute the original command as the approving human.", "requiredScope": "tenant", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "confirmation_id", "flag": "confirmation-id", "type": "string", "required": true }, { "name": "reviewed", "flag": "reviewed", "type": "boolean", "required": false }], "hasComplexInput": false, "help": "Approve pending confirmations only when the requested durable change is clear to the human owner." },
|
|
50300
|
+
{ "id": "confirmation.list", "namespace": "confirmation", "action": "list", "title": "List pending confirmations", "description": "List in-flight confirmations awaiting a human decision, scoped to the caller's authority (owner sees all; a member sees seats they occupy; an agent sees its own seat).", "requiredScope": "tenant", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "limit", "flag": "limit", "type": "integer", "required": false }], "hasComplexInput": false, "help": "List pending confirmations awaiting a human decision before approving or rejecting them." },
|
|
50164
50301
|
{ "id": "confirmation.reject", "namespace": "confirmation", "action": "reject", "title": "Reject pending confirmation", "description": "Reject an in-flight confirmation without executing the original command.", "requiredScope": "tenant", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "confirmation_id", "flag": "confirmation-id", "type": "string", "required": true }, { "name": "reason", "flag": "reason", "type": "string", "required": false }], "hasComplexInput": false, "help": "Reject pending confirmations when authority, evidence, or human intent is unclear." },
|
|
50165
50302
|
{ "id": "credential.ingress", "namespace": "credential", "action": "ingress", "title": "Store credential", "description": "Store a secret through the vault and persist only the credential vault reference.", "requiredScope": "seat", "confirmation": "credential_flow", "exposeOverMcp": false, "fields": [{ "name": "seat_id", "flag": "seat-id", "type": "string", "required": false }, { "name": "provider", "flag": "provider", "type": "string", "required": true }, { "name": "scope_description", "flag": "scope-description", "type": "string", "required": true }, { "name": "secret_name", "flag": "secret-name", "type": "string", "required": true }], "hasComplexInput": false, "secretBlocked": true, "help": "Ingress credentials only through vault-backed flows; never place raw secrets in prompts, logs, or docs." },
|
|
50166
50303
|
{ "id": "deliverable.accept", "namespace": "deliverable", "action": "accept", "title": "Accept deliverable value", "description": "Record a human-confirmed accepted value (USD) on a deliverable. Humans decide; agents cannot self-accept. Re-accepting records a correction as a new event; prior events are never mutated.", "requiredScope": "tenant_admin", "confirmation": "human_required", "exposeOverMcp": true, "fields": [{ "name": "deliverable_id", "flag": "deliverable-id", "type": "string", "required": true }, { "name": "impact_value_usd", "flag": "impact-value-usd", "type": "number", "required": true }], "hasComplexInput": false, "help": "Record a human-confirmed accepted value (USD) on a deliverable; owner-only and human-gated. Humans decide \u2014 agents cannot self-accept. Re-accepting records a correction as a new event." },
|
|
@@ -50178,22 +50315,24 @@ var COMMAND_MANIFEST = [
|
|
|
50178
50315
|
{ "id": "escalation.resolve", "namespace": "escalation", "action": "resolve", "title": "Resolve escalation", "description": "Approve an open escalation (or convert it to Friction). Writes a human decision; agents cannot resolve.", "requiredScope": "tenant", "confirmation": "none", "exposeOverMcp": false, "fields": [{ "name": "id", "flag": "id", "type": "string", "required": true }, { "name": "action", "flag": "action", "type": "enum", "required": false, "enumValues": ["approve", "convert_to_issue"] }, { "name": "rationale", "flag": "rationale", "type": "string", "required": false }], "hasComplexInput": false, "help": "Resolve an escalation as a human Steward; the decision records decided_by as the approving human. Agents cannot resolve." },
|
|
50179
50316
|
{ "id": "friction.assist", "namespace": "friction", "action": "assist", "title": "Assist Friction issue", "description": "Advisory IDS assist for an issue: the most-similar prior resolved issues with their root causes and decisions, a recurring-pattern flag, and recommended options. Read-only \u2014 it never resolves the issue.", "requiredScope": "tenant", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "issue_id", "flag": "issue-id", "type": "string", "required": true }, { "name": "limit", "flag": "limit", "type": "integer", "required": false }], "hasComplexInput": false, "help": "Advisory IDS assist: the most-similar prior resolved issues with their root causes and decisions, plus a recurring-pattern flag. Read-only \u2014 it never resolves the issue." },
|
|
50180
50317
|
{ "id": "friction.file_issue", "namespace": "friction", "action": "file_issue", "title": "File Friction issue", "description": "Emit an issue event and open a Friction issue raised by the acting seat.", "requiredScope": "seat", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "summary", "flag": "summary", "type": "string", "required": true }, { "name": "blocking_goal_id", "flag": "blocking-goal-id", "type": "string", "required": false }, { "name": "broken_measurable_id", "flag": "broken-measurable-id", "type": "string", "required": false }, { "name": "severity", "flag": "severity", "type": "enum", "required": true, "enumValues": ["low", "med", "high", "critical"] }], "hasComplexInput": true, "help": "File a Friction issue with evidence when a goal or measurable is blocked or broken." },
|
|
50318
|
+
{ "id": "friction.get", "namespace": "friction", "action": "get", "title": "Get Friction issue", "description": "Get full detail for one Friction issue by id.", "requiredScope": "tenant", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "issue_id", "flag": "issue-id", "type": "string", "required": true }], "hasComplexInput": false, "help": "Get full detail for one Friction issue by id, including its root cause, action task, and resolution decision when present." },
|
|
50181
50319
|
{ "id": "friction.import", "namespace": "friction", "action": "import", "title": "Import Friction issues from a ninety Issues List", "description": "Bulk-import a ninety Issues List export into Friction. Owners are seat names resolved to seats; each issue is raised by the resolved seat and attributed to the importing human. Idempotent \u2014 re-importing the same export is a no-op, and an existing open issue with the same seat + summary is skipped.", "requiredScope": "tenant_admin", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "dry_run", "flag": "dry-run", "type": "boolean", "required": false }], "hasComplexInput": true, "help": "Import a ninety Issues List export into Friction; owners resolve to seats, idempotent by file + seat/summary." },
|
|
50182
50320
|
{ "id": "friction.link_task", "namespace": "friction", "action": "link_task", "title": "Link task to Friction issue", "description": "Attach an existing tenant task as the action task for a non-terminal issue. Both ids must belong to the tenant.", "requiredScope": "tenant", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "issue_id", "flag": "issue-id", "type": "string", "required": true }, { "name": "task_id", "flag": "task-id", "type": "string", "required": true }], "hasComplexInput": false, "help": "Attach an existing task as the action task for a non-terminal issue." },
|
|
50183
50321
|
{ "id": "friction.list", "namespace": "friction", "action": "list", "title": "List Friction issues", "description": "List Friction issues ranked by status, impact, and severity. Defaults to active (open + diagnosing).", "requiredScope": "tenant", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "status", "flag": "status", "type": "enum", "required": false, "enumValues": ["open", "diagnosing", "resolved", "dropped", "active", "all"] }], "hasComplexInput": false, "help": "List Friction issues ranked by impact and severity to find the issue id before updating or resolving it." },
|
|
50184
|
-
{ "id": "friction.resolve", "namespace": "friction", "action": "resolve", "title": "Resolve Friction issue", "description":
|
|
50322
|
+
{ "id": "friction.resolve", "namespace": "friction", "action": "resolve", "title": "Resolve Friction issue", "description": 'Resolve an issue with a root cause. In the default "ids" resolution_mode this also creates a remediation follow-up task; "already_fixed" records only the root cause (no follow-up task). Always records a human decision (decided_by) in the same transaction.', "requiredScope": "tenant_admin", "confirmation": "human_required", "exposeOverMcp": true, "fields": [{ "name": "issue_id", "flag": "issue-id", "type": "string", "required": true }, { "name": "resolution_mode", "flag": "resolution-mode", "type": "enum", "required": false, "enumValues": ["ids", "already_fixed"] }, { "name": "root_cause", "flag": "root-cause", "type": "string", "required": true }, { "name": "owner_seat_id", "flag": "owner-seat-id", "type": "string", "required": false }, { "name": "task_title", "flag": "task-title", "type": "string", "required": false }, { "name": "task_description", "flag": "task-description", "type": "string", "required": false }, { "name": "done_by", "flag": "done-by", "type": "string", "required": false }, { "name": "resolving_seat_id", "flag": "resolving-seat-id", "type": "string", "required": false }], "hasComplexInput": false, "help": "Resolve an issue with a root cause and remediation task; resolution is a human decision." },
|
|
50185
50323
|
{ "id": "friction.update_status", "namespace": "friction", "action": "update_status", "title": "Update Friction issue status", "description": "Move a non-terminal issue between open and diagnosing. Terminal issues (resolved/dropped) cannot be reopened here.", "requiredScope": "tenant", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "issue_id", "flag": "issue-id", "type": "string", "required": true }, { "name": "status", "flag": "status", "type": "enum", "required": true, "enumValues": ["open", "diagnosing"] }], "hasComplexInput": false, "help": "Move a non-terminal issue between open and diagnosing while it is being worked." },
|
|
50186
|
-
{ "id": "goal.bind_measurable", "namespace": "goal", "action": "bind_measurable", "title": "Bind a Signal to a Cascade goal", "description": "Bind a measurable to a goal
|
|
50324
|
+
{ "id": "goal.bind_measurable", "namespace": "goal", "action": "bind_measurable", "title": "Bind a Signal to a Cascade goal", "description": "Bind a measurable to a goal. Role defaults to 'informs' \u2014 a conservative informative indicator allowed at any goal level (many per goal) that never changes goal status. Role 'drives_status' makes it the goal's status driver: allowed only on a childless seat goal or milestone, at most one per goal, and auto-status starts OFF until a steward opts in with goal.set_auto_status. Binding is human-gated.", "requiredScope": "seat", "confirmation": "human_required", "exposeOverMcp": true, "fields": [{ "name": "goal_id", "flag": "goal-id", "type": "string", "required": true }, { "name": "measurable_id", "flag": "measurable-id", "type": "string", "required": true }, { "name": "role", "flag": "role", "type": "enum", "required": false, "enumValues": ["drives_status", "informs"] }], "hasComplexInput": false, "help": "Bind a Signal to a goal. Defaults to role informs (a conservative indicator at any level that never changes status); pass role drives_status to make it a childless leaf goal's status driver (auto-status starts OFF until a steward opts in)." },
|
|
50187
50325
|
{ "id": "goal.create", "namespace": "goal", "action": "create", "title": "Create Cascade goal", "description": "Create a cycle goal under an existing objective. The parent chain must terminate at a Compass objective in the same cycle (enforced server-side).", "requiredScope": "tenant", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "cycle_id", "flag": "cycle-id", "type": "string", "required": true }, { "name": "seat_id", "flag": "seat-id", "type": "string", "required": true }, { "name": "parent_goal_id", "flag": "parent-goal-id", "type": "string", "required": true }, { "name": "title", "flag": "title", "type": "string", "required": true }, { "name": "definition_of_done", "flag": "definition-of-done", "type": "string", "required": true }, { "name": "status", "flag": "status", "type": "enum", "required": false, "enumValues": ["on", "off"] }], "hasComplexInput": false, "help": "Create cycle goals under an existing objective; the parent chain must terminate at a Compass objective." },
|
|
50188
50326
|
{ "id": "goal.drop", "namespace": "goal", "action": "drop", "title": "Drop Cascade goal", "description": "Drop (retire) a goal by setting status to dropped. Dropping retires the commitment, so it is human-gated. The row is retained for audit (never deleted).", "requiredScope": "tenant_admin", "confirmation": "human_required", "exposeOverMcp": true, "fields": [{ "name": "goal_id", "flag": "goal-id", "type": "string", "required": true }], "hasComplexInput": false, "help": "Drop a goal to retire a commitment; the goal is retained for audit and dropping is human-gated." },
|
|
50327
|
+
{ "id": "goal.get", "namespace": "goal", "action": "get", "title": "Get Cascade goal", "description": "Get one goal's core detail and status by id. Seat-scoped callers may only read their own seat's goals.", "requiredScope": "tenant", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "goal_id", "flag": "goal-id", "type": "string", "required": true }], "hasComplexInput": false, "help": "Get one goal's core detail and status by id; seat tokens may only read their own goals." },
|
|
50189
50328
|
{ "id": "goal.list", "namespace": "goal", "action": "list", "title": "List Cascade goals", "description": "List goals in the tenant, optionally filtered by cycle or seat. Seat-scoped callers see only their own seat's goals.", "requiredScope": "tenant", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "cycle_id", "flag": "cycle-id", "type": "string", "required": false }, { "name": "seat_id", "flag": "seat-id", "type": "string", "required": false }], "hasComplexInput": false, "help": "List Cascade goals to find goal ids, parentage, and seat ownership before mutating the tree." },
|
|
50190
50329
|
{ "id": "goal.list_at_risk", "namespace": "goal", "action": "list_at_risk", "title": "List at-risk Cascade goals", "description": "List goals projected to miss their cycle pace (at-risk or projected-miss), with how many days behind pace. Read-only; status-only goals (no progress) are excluded.", "requiredScope": "tenant", "confirmation": "none", "exposeOverMcp": true, "fields": [], "hasComplexInput": false, "help": "List goals projected off pace (at-risk or projected-miss), with how many days behind pace. Read-only; status-only goals are excluded." },
|
|
50191
|
-
{ "id": "goal.list_measurables", "namespace": "goal", "action": "list_measurables", "title": "List a Cascade goal's Signals", "description": "List the
|
|
50330
|
+
{ "id": "goal.list_measurables", "namespace": "goal", "action": "list_measurables", "title": "List a Cascade goal's Signals", "description": "List the status-driver Signal bound to a Cascade goal (role drives_status), with its current signal indicator and latest confirmed reading. Read-only. Informative (informs) bindings appear in the goal-detail panel's Direct indicators, not here.", "requiredScope": "tenant", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "goal_id", "flag": "goal-id", "type": "string", "required": true }], "hasComplexInput": false, "help": "List the Signals bound to a goal (role drives_status) with each one's current indicator and latest confirmed reading." },
|
|
50192
50331
|
{ "id": "goal.reparent", "namespace": "goal", "action": "reparent", "title": "Reparent Cascade goal", "description": "Move a goal under a different parent. Reparenting changes accountable structure, so it is human-gated. One-root and no-cycle are enforced server-side.", "requiredScope": "tenant_admin", "confirmation": "human_required", "exposeOverMcp": true, "fields": [{ "name": "goal_id", "flag": "goal-id", "type": "string", "required": true }, { "name": "parent_goal_id", "flag": "parent-goal-id", "type": "string", "required": true }], "hasComplexInput": false, "help": "Reparent a goal only when it clarifies accountable structure; reparenting changes authority and is human-gated." },
|
|
50193
50332
|
{ "id": "goal.set_auto_status", "namespace": "goal", "action": "set_auto_status", "title": "Toggle Signal-driven auto-status", "description": "Opt a goal's drives_status binding into (or out of) auto-status. Default OFF. Enabling lets confirmed readings drive the goal's status; a human status pin still wins. Human-gated opt-in.", "requiredScope": "seat", "confirmation": "human_required", "exposeOverMcp": true, "fields": [{ "name": "goal_id", "flag": "goal-id", "type": "string", "required": true }, { "name": "measurable_id", "flag": "measurable-id", "type": "string", "required": true }, { "name": "enabled", "flag": "enabled", "type": "boolean", "required": true }], "hasComplexInput": false, "help": "Opt a goal's Signal binding into (or out of) auto-status. Default OFF. Enabling lets confirmed readings drive the status; a human status pin still wins." },
|
|
50194
50333
|
{ "id": "goal.set_progress", "namespace": "goal", "action": "set_progress", "title": "Set Cascade goal progress", "description": "Set a goal's quantified progress (0\u2013100). Seat-scoped callers may set progress only for their own goals. An agent's progress is a proposal a human approves before it lands.", "requiredScope": "seat", "confirmation": "human_required", "exposeOverMcp": true, "fields": [{ "name": "goal_id", "flag": "goal-id", "type": "string", "required": true }, { "name": "progress_pct", "flag": "progress-pct", "type": "integer", "required": true }], "hasComplexInput": false, "help": "Report a goal's quantified progress (0-100). An agent's progress is a proposal a human approves before the goal moves." },
|
|
50195
50334
|
{ "id": "goal.set_status", "namespace": "goal", "action": "set_status", "title": "Set Cascade goal status", "description": "Set a goal's status (on/off/done). Seat-scoped callers may set status only for their own goals.", "requiredScope": "seat", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "goal_id", "flag": "goal-id", "type": "string", "required": true }, { "name": "status", "flag": "status", "type": "enum", "required": true, "enumValues": ["on", "off", "done"] }], "hasComplexInput": false, "help": "Set a goal's status; seat tokens may only set status for their own goals." },
|
|
50196
|
-
{ "id": "goal.unbind_measurable", "namespace": "goal", "action": "unbind_measurable", "title": "Unbind a Signal from a Cascade goal", "description": "Remove a measurable's
|
|
50335
|
+
{ "id": "goal.unbind_measurable", "namespace": "goal", "action": "unbind_measurable", "title": "Unbind a Signal from a Cascade goal", "description": "Remove a measurable's binding from a goal. Role defaults to 'drives_status'; pass role 'informs' to remove an informative indicator. Removing a driver keeps the goal's last status; unbinding only stops future signal-driven updates.", "requiredScope": "seat", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "goal_id", "flag": "goal-id", "type": "string", "required": true }, { "name": "measurable_id", "flag": "measurable-id", "type": "string", "required": true }, { "name": "role", "flag": "role", "type": "enum", "required": false, "enumValues": ["drives_status", "informs"] }], "hasComplexInput": false, "help": "Remove a Signal's drives_status binding from a goal; the goal keeps its last status and stops receiving signal-driven updates." },
|
|
50197
50336
|
{ "id": "goal.update", "namespace": "goal", "action": "update", "title": "Update Cascade goal", "description": "Update a goal's title or definition of done. Topology (parent/seat) and status have dedicated commands.", "requiredScope": "tenant_admin", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "goal_id", "flag": "goal-id", "type": "string", "required": true }, { "name": "title", "flag": "title", "type": "string", "required": false }, { "name": "definition_of_done", "flag": "definition-of-done", "type": "string", "required": false }], "hasComplexInput": false, "help": "Update a goal's title or definition of done; topology and status have dedicated commands." },
|
|
50198
50337
|
{ "id": "graph.get", "namespace": "graph", "action": "get", "title": "Get Responsibility Graph", "description": "Return the tenant's Responsibility Graph: seats, edges, root, occupants, and status rollups.", "requiredScope": "tenant", "confirmation": "none", "exposeOverMcp": true, "fields": [], "hasComplexInput": false, "help": "Read the Responsibility Graph to discover seat ids, parentage, occupants, and status before mutating or routing work." },
|
|
50199
50338
|
{ "id": "integration.connect_rest", "namespace": "integration", "action": "connect_rest", "title": "Connect REST integration", "description": "Create or rotate the tenant Baserow REST integration using a vault-backed secret. Stores endpoint metadata only; never returns secrets or vault refs.", "requiredScope": "tenant_admin", "confirmation": "credential_flow", "exposeOverMcp": false, "fields": [{ "name": "provider", "flag": "provider", "type": "enum", "required": true, "enumValues": ["baserow"] }, { "name": "endpoint_url", "flag": "endpoint-url", "type": "string", "required": true }, { "name": "scope_description", "flag": "scope-description", "type": "string", "required": true }, { "name": "secret_name", "flag": "secret-name", "type": "string", "required": true }, { "name": "account_label", "flag": "account-label", "type": "string", "required": false }], "hasComplexInput": false, "secretBlocked": true, "help": "Create or rotate a vault-backed Baserow REST integration for Signal pulls. Use the credential flow; never pass secrets through CLI argv." },
|
|
@@ -50490,6 +50629,19 @@ function execute(context, parsed, commandId, body, format) {
|
|
|
50490
50629
|
}
|
|
50491
50630
|
|
|
50492
50631
|
// src/generator/flags.ts
|
|
50632
|
+
var SEAT_FLAG_FILLS_REQUIRED_SEAT_ID = /* @__PURE__ */ new Set([
|
|
50633
|
+
"agent.status",
|
|
50634
|
+
"agent.show_markdown",
|
|
50635
|
+
"agent.get_run",
|
|
50636
|
+
"agent.list_runs",
|
|
50637
|
+
"agent.list_tool_calls",
|
|
50638
|
+
"charter.show_markdown",
|
|
50639
|
+
"seat.get",
|
|
50640
|
+
"seat.decommission_preview",
|
|
50641
|
+
"deliverable.get",
|
|
50642
|
+
"deliverable.list",
|
|
50643
|
+
"skill.check_dependencies"
|
|
50644
|
+
]);
|
|
50493
50645
|
function booleanFlagsFor(entry, overrides = {}) {
|
|
50494
50646
|
const booleanFields = new Set(entry.fields.filter((field3) => field3.type === "boolean").map((field3) => field3.name));
|
|
50495
50647
|
const flags = /* @__PURE__ */ new Set(["yes", "y"]);
|
|
@@ -50579,6 +50731,9 @@ function buildBodyFromFlags(entry, parsed, positional, overrides = {}) {
|
|
|
50579
50731
|
if (raw === void 0 && positional !== void 0 && overrides.primaryPositional === field3.name) {
|
|
50580
50732
|
raw = positional;
|
|
50581
50733
|
}
|
|
50734
|
+
if (raw === void 0 && field3.name === "seat_id" && (!field3.required || SEAT_FLAG_FILLS_REQUIRED_SEAT_ID.has(entry.id))) {
|
|
50735
|
+
raw = parsed.seat;
|
|
50736
|
+
}
|
|
50582
50737
|
if (raw === void 0 || raw.length === 0) {
|
|
50583
50738
|
continue;
|
|
50584
50739
|
}
|
|
@@ -50983,6 +51138,15 @@ function renderGoalStatus(output) {
|
|
|
50983
51138
|
const record2 = asRecord(output);
|
|
50984
51139
|
return `Goal ${field(record2, "goal_id")} status set to ${field(record2, "status")}.`;
|
|
50985
51140
|
}
|
|
51141
|
+
function renderGoalGet(output) {
|
|
51142
|
+
const record2 = asRecord(asRecord(output).goal);
|
|
51143
|
+
return [
|
|
51144
|
+
`${field(record2, "id")} ${field(record2, "status")} ${field(record2, "title")}`,
|
|
51145
|
+
`kind: ${field(record2, "kind")} status source: ${field(record2, "status_source")}`,
|
|
51146
|
+
`progress: ${field(record2, "progress_pct")}`,
|
|
51147
|
+
`definition of done: ${field(record2, "definition_of_done")}`
|
|
51148
|
+
].join("\n");
|
|
51149
|
+
}
|
|
50986
51150
|
function renderGoalReparent(output) {
|
|
50987
51151
|
const record2 = asRecord(output);
|
|
50988
51152
|
return `Goal ${field(record2, "goal_id")} reparented under ${field(record2, "parent_goal_id")}.`;
|
|
@@ -51013,6 +51177,27 @@ function renderFrictionLink(output) {
|
|
|
51013
51177
|
const record2 = asRecord(output);
|
|
51014
51178
|
return `Linked task ${field(record2, "action_task_id")} to issue ${field(record2, "issue_id")}.`;
|
|
51015
51179
|
}
|
|
51180
|
+
function renderFrictionGet(output) {
|
|
51181
|
+
const record2 = asRecord(asRecord(output).issue);
|
|
51182
|
+
return [
|
|
51183
|
+
`${field(record2, "issue_id")} ${field(record2, "status")} ${field(record2, "severity")}`,
|
|
51184
|
+
`summary: ${field(record2, "summary")}`,
|
|
51185
|
+
`raised by: ${field(record2, "raised_by_seat_name")}`,
|
|
51186
|
+
`impact score: ${field(record2, "impact_score")}`,
|
|
51187
|
+
`root cause: ${field(record2, "root_cause")}`,
|
|
51188
|
+
`action task: ${field(record2, "action_task_id")}`
|
|
51189
|
+
].join("\n");
|
|
51190
|
+
}
|
|
51191
|
+
function renderConfirmationList(output) {
|
|
51192
|
+
const confirmations = asArray(asRecord(output).confirmations);
|
|
51193
|
+
if (confirmations.length === 0) {
|
|
51194
|
+
return "No pending confirmations.";
|
|
51195
|
+
}
|
|
51196
|
+
return confirmations.map((entry) => {
|
|
51197
|
+
const record2 = asRecord(entry);
|
|
51198
|
+
return `${field(record2, "id")} ${field(record2, "risk_level")} ${field(record2, "command_id")} ${field(record2, "summary")}`;
|
|
51199
|
+
}).join("\n");
|
|
51200
|
+
}
|
|
51016
51201
|
function renderEscalationList(output) {
|
|
51017
51202
|
const escalations = asArray(asRecord(output).escalations);
|
|
51018
51203
|
if (escalations.length === 0) {
|
|
@@ -51915,7 +52100,8 @@ var GROUP_SPECS = {
|
|
|
51915
52100
|
list: { commandId: "goal.list", render: renderGoalList },
|
|
51916
52101
|
create: { commandId: "goal.create", render: renderGoalCreate },
|
|
51917
52102
|
update: { commandId: "goal.update", handler: goalUpdateHandler, render: renderGoalUpdate },
|
|
51918
|
-
status: { commandId: "goal.
|
|
52103
|
+
status: { commandId: "goal.get", render: renderGoalGet, primaryPositional: "goal_id" },
|
|
52104
|
+
"set-status": { commandId: "goal.set_status", render: renderGoalStatus },
|
|
51919
52105
|
reparent: { commandId: "goal.reparent", render: renderGoalReparent },
|
|
51920
52106
|
drop: { commandId: "goal.drop", render: renderGoalDrop }
|
|
51921
52107
|
}
|
|
@@ -51939,6 +52125,7 @@ var GROUP_SPECS = {
|
|
|
51939
52125
|
friction: {
|
|
51940
52126
|
verbs: {
|
|
51941
52127
|
list: { commandId: "friction.list", render: renderFrictionList },
|
|
52128
|
+
get: { commandId: "friction.get", render: renderFrictionGet, primaryPositional: "issue_id" },
|
|
51942
52129
|
file: { commandId: "friction.file_issue", handler: frictionFileHandler, render: renderFrictionFile },
|
|
51943
52130
|
resolve: { commandId: "friction.resolve", render: renderFrictionResolve },
|
|
51944
52131
|
link: { commandId: "friction.link_task", render: renderFrictionLink },
|
|
@@ -51960,7 +52147,7 @@ var GROUP_SPECS = {
|
|
|
51960
52147
|
verbs: {
|
|
51961
52148
|
list: { commandId: "escalation.list", render: renderEscalationList },
|
|
51962
52149
|
get: { commandId: "escalation.get", render: renderEscalationGet, primaryPositional: "id" },
|
|
51963
|
-
resolve: { commandId: "escalation.resolve", render: renderEscalationResolve },
|
|
52150
|
+
resolve: { commandId: "escalation.resolve", render: renderEscalationResolve, primaryPositional: "id" },
|
|
51964
52151
|
reject: { commandId: "escalation.reject", render: renderEscalationReject }
|
|
51965
52152
|
}
|
|
51966
52153
|
},
|
|
@@ -52082,6 +52269,11 @@ var GROUP_SPECS = {
|
|
|
52082
52269
|
verbs: {
|
|
52083
52270
|
health: { commandId: "system.health", handler: systemHealthHandler, render: formatSystemHealth }
|
|
52084
52271
|
}
|
|
52272
|
+
},
|
|
52273
|
+
confirmation: {
|
|
52274
|
+
verbs: {
|
|
52275
|
+
list: { commandId: "confirmation.list", render: renderConfirmationList }
|
|
52276
|
+
}
|
|
52085
52277
|
}
|
|
52086
52278
|
};
|
|
52087
52279
|
|
|
@@ -52371,7 +52563,7 @@ function ensureTrailingSlash2(value) {
|
|
|
52371
52563
|
// src/skills.ts
|
|
52372
52564
|
import { existsSync, mkdirSync, readFileSync as readFileSync3, rmSync, writeFileSync } from "node:fs";
|
|
52373
52565
|
import os from "node:os";
|
|
52374
|
-
import
|
|
52566
|
+
import path3 from "node:path";
|
|
52375
52567
|
var UsageError2 = class extends Error {
|
|
52376
52568
|
};
|
|
52377
52569
|
var CLIENTS = /* @__PURE__ */ new Set(["claude-code", "codex", "cursor"]);
|
|
@@ -52566,8 +52758,8 @@ function writeInstalls(output, root) {
|
|
|
52566
52758
|
const slug2 = safeLocalSlug(String(install.slug ?? ""));
|
|
52567
52759
|
const metadata = asRecord2(install.metadata);
|
|
52568
52760
|
const files = asArray2(install.files).map(asRecord2);
|
|
52569
|
-
const dir =
|
|
52570
|
-
const metadataPath =
|
|
52761
|
+
const dir = path3.join(root, slug2);
|
|
52762
|
+
const metadataPath = path3.join(dir, ".rost-skill.json");
|
|
52571
52763
|
const expectedHash = String(metadata.content_sha256 ?? "");
|
|
52572
52764
|
if (existingHash(metadataPath) === expectedHash) {
|
|
52573
52765
|
return { slug: slug2, dir, status: "unchanged", files: files.length };
|
|
@@ -52577,8 +52769,8 @@ function writeInstalls(output, root) {
|
|
|
52577
52769
|
for (const file2 of files) {
|
|
52578
52770
|
const relativePath = safeRelativePath(String(file2.path ?? ""));
|
|
52579
52771
|
const content = String(file2.content ?? "");
|
|
52580
|
-
const target =
|
|
52581
|
-
mkdirSync(
|
|
52772
|
+
const target = path3.join(dir, relativePath);
|
|
52773
|
+
mkdirSync(path3.dirname(target), { recursive: true });
|
|
52582
52774
|
writeFileSync(target, content, "utf8");
|
|
52583
52775
|
}
|
|
52584
52776
|
writeFileSync(metadataPath, `${JSON.stringify(metadata, null, 2)}
|
|
@@ -52598,7 +52790,7 @@ function removeRevokedInstalls(output, root) {
|
|
|
52598
52790
|
if (installs.has(slug2)) {
|
|
52599
52791
|
continue;
|
|
52600
52792
|
}
|
|
52601
|
-
const dir =
|
|
52793
|
+
const dir = path3.join(root, slug2);
|
|
52602
52794
|
if (!existsSync(dir)) {
|
|
52603
52795
|
continue;
|
|
52604
52796
|
}
|
|
@@ -52610,15 +52802,15 @@ function removeRevokedInstalls(output, root) {
|
|
|
52610
52802
|
function installRoot(client, env) {
|
|
52611
52803
|
const override = env.ROST_SKILL_INSTALL_ROOT;
|
|
52612
52804
|
if (override && override.length > 0) {
|
|
52613
|
-
return
|
|
52805
|
+
return path3.resolve(override, client);
|
|
52614
52806
|
}
|
|
52615
52807
|
if (client === "codex") {
|
|
52616
|
-
return
|
|
52808
|
+
return path3.join(env.CODEX_HOME ?? path3.join(os.homedir(), ".codex"), "skills", "rost");
|
|
52617
52809
|
}
|
|
52618
52810
|
if (client === "claude-code") {
|
|
52619
|
-
return
|
|
52811
|
+
return path3.join(env.CLAUDE_HOME ?? path3.join(os.homedir(), ".claude"), "skills", "rost");
|
|
52620
52812
|
}
|
|
52621
|
-
return
|
|
52813
|
+
return path3.join(os.homedir(), ".cursor", "skills", "rost");
|
|
52622
52814
|
}
|
|
52623
52815
|
function safeRelativePath(value) {
|
|
52624
52816
|
const normalized = value.trim().replaceAll("\\", "/").replace(/^\.\/+/, "");
|
|
@@ -52827,9 +53019,9 @@ import { promisify as promisify3 } from "node:util";
|
|
|
52827
53019
|
import { existsSync as existsSync2, realpathSync } from "node:fs";
|
|
52828
53020
|
import { readdir, rm as rm2, stat as stat2 } from "node:fs/promises";
|
|
52829
53021
|
import { tmpdir } from "node:os";
|
|
52830
|
-
import
|
|
53022
|
+
import path4 from "node:path";
|
|
52831
53023
|
var SANDBOX_EXEC_PATH = "/usr/bin/sandbox-exec";
|
|
52832
|
-
var RUNNER_ASKPASS_DIR =
|
|
53024
|
+
var RUNNER_ASKPASS_DIR = path4.join(tmpdir(), "rost-runner-askpass");
|
|
52833
53025
|
var RUNNER_TEMP_PREFIXES = [
|
|
52834
53026
|
"rost-runner-mcp-",
|
|
52835
53027
|
"rost-runner-sandbox-",
|
|
@@ -52999,7 +53191,7 @@ function canonical(p) {
|
|
|
52999
53191
|
}
|
|
53000
53192
|
}
|
|
53001
53193
|
function canonicalFile(p) {
|
|
53002
|
-
return
|
|
53194
|
+
return path4.join(canonical(path4.dirname(p)), path4.basename(p));
|
|
53003
53195
|
}
|
|
53004
53196
|
function isSandboxExecAvailable() {
|
|
53005
53197
|
try {
|
|
@@ -53082,7 +53274,7 @@ async function sweepStaleRunnerTempFiles(dir, options = {}) {
|
|
|
53082
53274
|
if (!RUNNER_TEMP_PREFIXES.some((prefix) => name.startsWith(prefix))) {
|
|
53083
53275
|
return;
|
|
53084
53276
|
}
|
|
53085
|
-
const full =
|
|
53277
|
+
const full = path4.join(dir, name);
|
|
53086
53278
|
try {
|
|
53087
53279
|
const info = await stat2(full);
|
|
53088
53280
|
if (now - info.mtimeMs < maxAgeMs) {
|
|
@@ -53100,9 +53292,9 @@ async function sweepStaleRunnerTempFiles(dir, options = {}) {
|
|
|
53100
53292
|
// src/runner-service.ts
|
|
53101
53293
|
import { execFile as execFileCallback2 } from "node:child_process";
|
|
53102
53294
|
import { realpathSync as realpathSync2 } from "node:fs";
|
|
53103
|
-
import { access, mkdir as
|
|
53104
|
-
import { homedir as
|
|
53105
|
-
import
|
|
53295
|
+
import { access, mkdir as mkdir3, readFile as readFile4, readdir as readdir2, rm as rm3, writeFile as writeFile3 } from "node:fs/promises";
|
|
53296
|
+
import { homedir as homedir3 } from "node:os";
|
|
53297
|
+
import path5 from "node:path";
|
|
53106
53298
|
import { promisify as promisify2 } from "node:util";
|
|
53107
53299
|
var execFile2 = promisify2(execFileCallback2);
|
|
53108
53300
|
var SERVICE_VERBS = ["install-service", "start", "stop", "restart", "status", "logs", "uninstall"];
|
|
@@ -53119,9 +53311,9 @@ function isRunnerServiceInvocation(args) {
|
|
|
53119
53311
|
function runnerServicePaths(homeDir, runnerName) {
|
|
53120
53312
|
const safeName = safeRunnerName(runnerName);
|
|
53121
53313
|
return {
|
|
53122
|
-
launchAgentPath:
|
|
53123
|
-
stateFile:
|
|
53124
|
-
logDir:
|
|
53314
|
+
launchAgentPath: path5.join(homeDir, "Library", "LaunchAgents", `${serviceLabel(safeName)}.plist`),
|
|
53315
|
+
stateFile: path5.join(homeDir, "Library", "Application Support", cliBrand.name, `runner-${safeName}.json`),
|
|
53316
|
+
logDir: path5.join(homeDir, "Library", "Logs", cliBrand.name, "runner", safeName)
|
|
53125
53317
|
};
|
|
53126
53318
|
}
|
|
53127
53319
|
function renderLaunchdPlist(config2) {
|
|
@@ -53163,9 +53355,9 @@ ${config2.allowDevelopmentAppUrl === true ? ` <key>${allowInsecureAppUrlEnv}<
|
|
|
53163
53355
|
<key>RunAtLoad</key>
|
|
53164
53356
|
<true/>
|
|
53165
53357
|
<key>StandardOutPath</key>
|
|
53166
|
-
<string>${escapePlist(
|
|
53358
|
+
<string>${escapePlist(path5.join(config2.logDir, "stdout.log"))}</string>
|
|
53167
53359
|
<key>StandardErrorPath</key>
|
|
53168
|
-
<string>${escapePlist(
|
|
53360
|
+
<string>${escapePlist(path5.join(config2.logDir, "stderr.log"))}</string>
|
|
53169
53361
|
</dict>
|
|
53170
53362
|
</plist>
|
|
53171
53363
|
`;
|
|
@@ -53201,7 +53393,7 @@ ${serviceUsage()}
|
|
|
53201
53393
|
userCode: parsed.userCode,
|
|
53202
53394
|
nodePath: options.nodePath ?? resolveNodePath(),
|
|
53203
53395
|
binPath: options.binPath ?? resolveBinPath(),
|
|
53204
|
-
homeDir: options.homeDir ??
|
|
53396
|
+
homeDir: options.homeDir ?? homedir3(),
|
|
53205
53397
|
platform: options.platform ?? process.platform,
|
|
53206
53398
|
exec: options.exec ?? defaultExec,
|
|
53207
53399
|
uid: options.uid ?? (process.getuid ? process.getuid() : 0)
|
|
@@ -53232,9 +53424,9 @@ async function installService(options) {
|
|
|
53232
53424
|
const safeName = safeRunnerName(options.runnerName);
|
|
53233
53425
|
const paths = runnerServicePaths(options.homeDir, safeName);
|
|
53234
53426
|
const label = serviceLabel(safeName);
|
|
53235
|
-
await
|
|
53236
|
-
await
|
|
53237
|
-
await
|
|
53427
|
+
await mkdir3(paths.logDir, { recursive: true });
|
|
53428
|
+
await mkdir3(path5.dirname(paths.stateFile), { recursive: true });
|
|
53429
|
+
await mkdir3(path5.dirname(paths.launchAgentPath), { recursive: true });
|
|
53238
53430
|
if (options.userCode !== void 0) {
|
|
53239
53431
|
const paired = await pairRunnerOnce(options, safeName, paths.stateFile, options.userCode);
|
|
53240
53432
|
if (!paired) {
|
|
@@ -53252,7 +53444,7 @@ async function installService(options) {
|
|
|
53252
53444
|
servicePath: buildServicePath(options.nodePath, options.homeDir),
|
|
53253
53445
|
execute: options.execute
|
|
53254
53446
|
});
|
|
53255
|
-
await
|
|
53447
|
+
await writeFile3(paths.launchAgentPath, plist, { mode: 420 });
|
|
53256
53448
|
await bootoutQuietly(options.exec, options.uid, paths.launchAgentPath);
|
|
53257
53449
|
try {
|
|
53258
53450
|
const bootstrapped = await bootstrapService(options.exec, options.uid, paths.launchAgentPath);
|
|
@@ -53389,8 +53581,8 @@ async function logsService(options) {
|
|
|
53389
53581
|
const safeName = safeRunnerName(options.runnerName);
|
|
53390
53582
|
const paths = runnerServicePaths(options.homeDir, safeName);
|
|
53391
53583
|
const label = serviceLabel(safeName);
|
|
53392
|
-
const stdoutLog =
|
|
53393
|
-
const stderrLog =
|
|
53584
|
+
const stdoutLog = path5.join(paths.logDir, "stdout.log");
|
|
53585
|
+
const stderrLog = path5.join(paths.logDir, "stderr.log");
|
|
53394
53586
|
options.io.stdout.write(
|
|
53395
53587
|
`${[
|
|
53396
53588
|
`runner service logs for ${label}:`,
|
|
@@ -53493,8 +53685,8 @@ function serviceTargets(uid, label) {
|
|
|
53493
53685
|
return launchdDomains(uid).map((domain2) => `${domain2}/${label}`);
|
|
53494
53686
|
}
|
|
53495
53687
|
async function inspectRunnerServiceInstallations(options = {}) {
|
|
53496
|
-
const homeDir = options.homeDir ??
|
|
53497
|
-
const launchAgentsDir =
|
|
53688
|
+
const homeDir = options.homeDir ?? homedir3();
|
|
53689
|
+
const launchAgentsDir = path5.join(homeDir, "Library", "LaunchAgents");
|
|
53498
53690
|
let names = [];
|
|
53499
53691
|
try {
|
|
53500
53692
|
const entries = await readdir2(launchAgentsDir);
|
|
@@ -53514,7 +53706,7 @@ async function inspectRunnerService(options) {
|
|
|
53514
53706
|
const paths = runnerServicePaths(options.homeDir, safeName);
|
|
53515
53707
|
const label = serviceLabel(safeName);
|
|
53516
53708
|
const installed = await fileExists(paths.launchAgentPath);
|
|
53517
|
-
const plist = installed ? await
|
|
53709
|
+
const plist = installed ? await readFile4(paths.launchAgentPath, "utf8").catch(() => null) : null;
|
|
53518
53710
|
const programArgs = plist ? extractProgramArguments(plist) : [];
|
|
53519
53711
|
const appUrl2 = plist ? extractPlistEnvironmentValue(plist, `${cliBrand.envPrefix}_APP_URL`) : null;
|
|
53520
53712
|
const urlPolicyEnv = extractPlistEnvironmentValue(plist ?? "", allowInsecureAppUrlEnv) === "1" ? "set" : "unset";
|
|
@@ -53623,11 +53815,11 @@ function resolveNodePath() {
|
|
|
53623
53815
|
}
|
|
53624
53816
|
function buildServicePath(nodePath, homeDir) {
|
|
53625
53817
|
const entries = [
|
|
53626
|
-
|
|
53818
|
+
path5.dirname(nodePath),
|
|
53627
53819
|
"/opt/homebrew/bin",
|
|
53628
53820
|
"/usr/local/bin",
|
|
53629
|
-
|
|
53630
|
-
|
|
53821
|
+
path5.join(homeDir, ".local", "bin"),
|
|
53822
|
+
path5.join(homeDir, "bin"),
|
|
53631
53823
|
"/usr/bin",
|
|
53632
53824
|
"/bin",
|
|
53633
53825
|
"/usr/sbin",
|
|
@@ -53782,7 +53974,7 @@ async function fileExists(file2) {
|
|
|
53782
53974
|
}
|
|
53783
53975
|
async function readTail(file2, maxBytes) {
|
|
53784
53976
|
try {
|
|
53785
|
-
const content = await
|
|
53977
|
+
const content = await readFile4(file2, "utf8");
|
|
53786
53978
|
return content.length > maxBytes ? content.slice(content.length - maxBytes) : content;
|
|
53787
53979
|
} catch {
|
|
53788
53980
|
return null;
|
|
@@ -53929,17 +54121,17 @@ function parseSemver2(value) {
|
|
|
53929
54121
|
// src/runner-serve.ts
|
|
53930
54122
|
import { execFile as execFileCallback5, spawn } from "node:child_process";
|
|
53931
54123
|
import { createHash as createHash2 } from "node:crypto";
|
|
53932
|
-
import { chmod as chmod2, mkdir as
|
|
53933
|
-
import { cpus, homedir as
|
|
53934
|
-
import
|
|
54124
|
+
import { chmod as chmod2, mkdir as mkdir5, readFile as readFile5, rename, rm as rm5, statfs, writeFile as writeFile5 } from "node:fs/promises";
|
|
54125
|
+
import { cpus, homedir as homedir4, hostname as hostname3, platform, totalmem, tmpdir as tmpdir2 } from "node:os";
|
|
54126
|
+
import path7 from "node:path";
|
|
53935
54127
|
import { setTimeout as sleep3 } from "node:timers/promises";
|
|
53936
54128
|
import { promisify as promisify5 } from "node:util";
|
|
53937
54129
|
|
|
53938
54130
|
// src/forge-workspace.ts
|
|
53939
54131
|
import { execFile as execFileCallback4 } from "node:child_process";
|
|
53940
54132
|
import { createHash } from "node:crypto";
|
|
53941
|
-
import { chmod, lstat, mkdir as
|
|
53942
|
-
import
|
|
54133
|
+
import { chmod, lstat, mkdir as mkdir4, mkdtemp, realpath, rm as rm4, stat as stat3, writeFile as writeFile4 } from "node:fs/promises";
|
|
54134
|
+
import path6 from "node:path";
|
|
53943
54135
|
import { setTimeout as sleep2 } from "node:timers/promises";
|
|
53944
54136
|
import { promisify as promisify4 } from "node:util";
|
|
53945
54137
|
|
|
@@ -54076,20 +54268,20 @@ function shortRequestId(buildRequestId) {
|
|
|
54076
54268
|
return slice.length > 0 ? slice : createHash("sha1").update(buildRequestId).digest("hex").slice(0, 8);
|
|
54077
54269
|
}
|
|
54078
54270
|
function requestRoot(baseDir, buildRequestId) {
|
|
54079
|
-
return
|
|
54271
|
+
return path6.join(baseDir, "work", shortRequestId(buildRequestId));
|
|
54080
54272
|
}
|
|
54081
54273
|
function baseRepoDir(baseDir, buildRequestId) {
|
|
54082
|
-
return
|
|
54274
|
+
return path6.join(requestRoot(baseDir, buildRequestId), "base");
|
|
54083
54275
|
}
|
|
54084
54276
|
function branchName(buildRequestId, changeset) {
|
|
54085
54277
|
const short = shortRequestId(buildRequestId);
|
|
54086
54278
|
return changeset.total > 1 ? `forge/${short}-cs${changeset.ordinal}` : `forge/${short}`;
|
|
54087
54279
|
}
|
|
54088
54280
|
function buildWorktreeDir(baseDir, buildRequestId, ordinal) {
|
|
54089
|
-
return
|
|
54281
|
+
return path6.join(requestRoot(baseDir, buildRequestId), `cs${ordinal}`);
|
|
54090
54282
|
}
|
|
54091
54283
|
function reviewWorktreeDir(baseDir, buildRequestId, ordinal) {
|
|
54092
|
-
return
|
|
54284
|
+
return path6.join(requestRoot(baseDir, buildRequestId), `review-cs${ordinal}`);
|
|
54093
54285
|
}
|
|
54094
54286
|
function remoteUrlFor(options) {
|
|
54095
54287
|
if (options.remoteUrl) {
|
|
@@ -54106,7 +54298,7 @@ async function pathExists(target) {
|
|
|
54106
54298
|
}
|
|
54107
54299
|
}
|
|
54108
54300
|
async function isGitRepo(dir) {
|
|
54109
|
-
return await pathExists(
|
|
54301
|
+
return await pathExists(path6.join(dir, ".git")) || await pathExists(path6.join(dir, "HEAD"));
|
|
54110
54302
|
}
|
|
54111
54303
|
async function runGit(args, cwd, timeoutMs = LOCAL_GIT_TIMEOUT_MS) {
|
|
54112
54304
|
try {
|
|
@@ -54159,10 +54351,10 @@ async function withNetworkRetries(op, fn, retryCounter) {
|
|
|
54159
54351
|
throw new Error(`${op} exhausted retries: ${lastError instanceof Error ? redactSecrets(lastError.message) : redactSecrets(String(lastError))}`);
|
|
54160
54352
|
}
|
|
54161
54353
|
async function canonicalAskpassBase(baseDir) {
|
|
54162
|
-
return
|
|
54354
|
+
return path6.join(await realpath(path6.dirname(baseDir)), path6.basename(baseDir));
|
|
54163
54355
|
}
|
|
54164
54356
|
async function prepareAskpassTurnDir(baseDir) {
|
|
54165
|
-
await
|
|
54357
|
+
await mkdir4(baseDir, { recursive: true, mode: 448 });
|
|
54166
54358
|
const baseInfo = await lstat(baseDir);
|
|
54167
54359
|
if (baseInfo.isSymbolicLink() || !baseInfo.isDirectory()) {
|
|
54168
54360
|
throw new Error(`refusing to use askpass dir ${baseDir}: not a real directory (possible symlink attack)`);
|
|
@@ -54171,10 +54363,10 @@ async function prepareAskpassTurnDir(baseDir) {
|
|
|
54171
54363
|
throw new Error(`refusing to use askpass dir ${baseDir}: not owned by this user (possible pre-planted dir)`);
|
|
54172
54364
|
}
|
|
54173
54365
|
await chmod(baseDir, 448);
|
|
54174
|
-
const turnDir = await mkdtemp(
|
|
54366
|
+
const turnDir = await mkdtemp(path6.join(baseDir, "rost-runner-askpass-"));
|
|
54175
54367
|
const canonicalBase = await canonicalAskpassBase(baseDir);
|
|
54176
54368
|
const realTurn = await realpath(turnDir);
|
|
54177
|
-
if (
|
|
54369
|
+
if (path6.dirname(realTurn) !== canonicalBase) {
|
|
54178
54370
|
await rm4(turnDir, { recursive: true, force: true });
|
|
54179
54371
|
throw new Error(`refusing to use askpass dir ${turnDir}: resolved outside ${canonicalBase} (possible symlink attack)`);
|
|
54180
54372
|
}
|
|
@@ -54182,7 +54374,7 @@ async function prepareAskpassTurnDir(baseDir) {
|
|
|
54182
54374
|
}
|
|
54183
54375
|
async function openAskpassSession(credential, baseDir = RUNNER_ASKPASS_DIR) {
|
|
54184
54376
|
const turnDir = await prepareAskpassTurnDir(baseDir);
|
|
54185
|
-
const helperPath =
|
|
54377
|
+
const helperPath = path6.join(turnDir, "askpass.sh");
|
|
54186
54378
|
const helper = [
|
|
54187
54379
|
"#!/bin/sh",
|
|
54188
54380
|
"# One-shot Forge GIT_ASKPASS helper. Contains no secret; reads the token from env.",
|
|
@@ -54192,7 +54384,7 @@ async function openAskpassSession(credential, baseDir = RUNNER_ASKPASS_DIR) {
|
|
|
54192
54384
|
"esac",
|
|
54193
54385
|
""
|
|
54194
54386
|
].join("\n");
|
|
54195
|
-
await
|
|
54387
|
+
await writeFile4(helperPath, helper, { mode: 448 });
|
|
54196
54388
|
await chmod(helperPath, 448);
|
|
54197
54389
|
const env = {
|
|
54198
54390
|
...process.env,
|
|
@@ -54243,8 +54435,8 @@ async function localBranchExists(baseRepo, branch) {
|
|
|
54243
54435
|
async function worktreeRegistered(baseRepo, worktreeDir) {
|
|
54244
54436
|
try {
|
|
54245
54437
|
const listing = await runGit(["worktree", "list", "--porcelain"], baseRepo);
|
|
54246
|
-
const target =
|
|
54247
|
-
return listing.split("\n").some((line) => line.startsWith("worktree ") &&
|
|
54438
|
+
const target = path6.resolve(worktreeDir);
|
|
54439
|
+
return listing.split("\n").some((line) => line.startsWith("worktree ") && path6.resolve(line.slice("worktree ".length).trim()) === target);
|
|
54248
54440
|
} catch {
|
|
54249
54441
|
return false;
|
|
54250
54442
|
}
|
|
@@ -54255,7 +54447,7 @@ async function configureForgeIdentity(baseRepo) {
|
|
|
54255
54447
|
}
|
|
54256
54448
|
async function ensureBaseClone(input) {
|
|
54257
54449
|
const baseRepo = baseRepoDir(input.baseDir, input.buildRequestId);
|
|
54258
|
-
await
|
|
54450
|
+
await mkdir4(path6.dirname(baseRepo), { recursive: true, mode: 448 });
|
|
54259
54451
|
await withLedgerStep(input.ledger, "clone", (retryCounter) => withAskpass(input.credential, async (netEnv) => {
|
|
54260
54452
|
if (await isGitRepo(baseRepo)) {
|
|
54261
54453
|
await runGitNetwork("git fetch", ["fetch", "--prune", "--quiet", input.url, "+refs/heads/*:refs/remotes/origin/*"], netEnv, baseRepo, FETCH_TIMEOUT_MS, retryCounter);
|
|
@@ -54304,7 +54496,7 @@ async function prepareMergeWorkspace(options) {
|
|
|
54304
54496
|
ledger: options.ledger
|
|
54305
54497
|
});
|
|
54306
54498
|
const branch = options.headBranch;
|
|
54307
|
-
const worktreeDir =
|
|
54499
|
+
const worktreeDir = path6.join(requestRoot(options.baseDir, options.buildRequestId), "merge");
|
|
54308
54500
|
const originDefault = `origin/${options.repo.default_branch}`;
|
|
54309
54501
|
const originHead = `origin/${branch}`;
|
|
54310
54502
|
await withLedgerStep(options.ledger, "branch", async () => {
|
|
@@ -54782,7 +54974,7 @@ async function runRunnerServe(options) {
|
|
|
54782
54974
|
const env = options.env ?? process.env;
|
|
54783
54975
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
54784
54976
|
const cliVersion = await readCliVersion();
|
|
54785
|
-
const homeDir = options.homeDir ??
|
|
54977
|
+
const homeDir = options.homeDir ?? homedir4();
|
|
54786
54978
|
let config2;
|
|
54787
54979
|
try {
|
|
54788
54980
|
config2 = parseServeArgs(options.args, options.appUrl, env, homeDir);
|
|
@@ -54968,7 +55160,7 @@ function detectTelemetry(capabilities, env, activeSessions, cliVersion) {
|
|
|
54968
55160
|
}
|
|
54969
55161
|
function parseServeArgs(args, appUrl2, env, homeDir) {
|
|
54970
55162
|
let name = env.RUNNER_NAME ?? `headless-${hostname3()}`;
|
|
54971
|
-
let stateFile = env.RUNNER_STATE_FILE ??
|
|
55163
|
+
let stateFile = env.RUNNER_STATE_FILE ?? path7.join(tmpdir2(), `rost-runner-${createHash2("sha1").update(appUrl2).digest("hex").slice(0, 8)}.json`);
|
|
54972
55164
|
let heartbeatMs = Number(env.RUNNER_HEARTBEAT_MS ?? 3e4);
|
|
54973
55165
|
let interactiveClaimMs = Number(env.RUNNER_INTERACTIVE_CLAIM_MS ?? 1e3);
|
|
54974
55166
|
let execute2 = env.RUNNER_EXECUTE === "1";
|
|
@@ -55019,7 +55211,7 @@ function parseServeArgs(args, appUrl2, env, homeDir) {
|
|
|
55019
55211
|
tmpDir: tmpdir2(),
|
|
55020
55212
|
homeDir,
|
|
55021
55213
|
stateFile,
|
|
55022
|
-
runnerBaseDir:
|
|
55214
|
+
runnerBaseDir: path7.join(homeDir, ".rost"),
|
|
55023
55215
|
allowNetwork: network.allowNetwork
|
|
55024
55216
|
});
|
|
55025
55217
|
return {
|
|
@@ -55125,7 +55317,7 @@ async function pairIfNeeded(client, fetchImpl, appUrl2, config2, io) {
|
|
|
55125
55317
|
}
|
|
55126
55318
|
async function loadState(filePath, expectedTenantId) {
|
|
55127
55319
|
try {
|
|
55128
|
-
const parsed = JSON.parse(await
|
|
55320
|
+
const parsed = JSON.parse(await readFile5(filePath, "utf8"));
|
|
55129
55321
|
if (typeof parsed.runner_id === "string" && typeof parsed.runner_secret === "string") {
|
|
55130
55322
|
if (expectedTenantId && parsed.tenant_id !== expectedTenantId) {
|
|
55131
55323
|
return null;
|
|
@@ -55156,10 +55348,10 @@ function isRuntimeSessionMap(value) {
|
|
|
55156
55348
|
});
|
|
55157
55349
|
}
|
|
55158
55350
|
async function saveState(filePath, state) {
|
|
55159
|
-
await
|
|
55351
|
+
await mkdir5(path7.dirname(filePath), { recursive: true, mode: 448 });
|
|
55160
55352
|
const tempPath = `${filePath}.${process.pid}.${createHash2("sha1").update(`${Date.now()}:${Math.random()}`).digest("hex").slice(0, 8)}.tmp`;
|
|
55161
55353
|
try {
|
|
55162
|
-
await
|
|
55354
|
+
await writeFile5(tempPath, `${JSON.stringify(state)}
|
|
55163
55355
|
`, { mode: 384 });
|
|
55164
55356
|
await chmod2(tempPath, 384);
|
|
55165
55357
|
await rename(tempPath, filePath);
|
|
@@ -55209,8 +55401,8 @@ function resolveSandboxKind(env, homeDir) {
|
|
|
55209
55401
|
workspaceDir: tmpdir2(),
|
|
55210
55402
|
tmpDir: tmpdir2(),
|
|
55211
55403
|
homeDir,
|
|
55212
|
-
stateFile:
|
|
55213
|
-
runnerBaseDir:
|
|
55404
|
+
stateFile: path7.join(tmpdir2(), "runner-sandbox-probe.json"),
|
|
55405
|
+
runnerBaseDir: path7.join(homeDir, ".rost"),
|
|
55214
55406
|
allowNetwork: resolveSandboxNetworkFlag(env) === "allow"
|
|
55215
55407
|
}).kind;
|
|
55216
55408
|
}
|
|
@@ -55309,9 +55501,9 @@ async function probeGhAuth() {
|
|
|
55309
55501
|
}
|
|
55310
55502
|
}
|
|
55311
55503
|
async function probeForgeDiskFreeMb(homeDir) {
|
|
55312
|
-
const dir =
|
|
55504
|
+
const dir = path7.join(homeDir, ".rost", "forge");
|
|
55313
55505
|
try {
|
|
55314
|
-
await
|
|
55506
|
+
await mkdir5(dir, { recursive: true, mode: 448 });
|
|
55315
55507
|
const stats = await statfs(dir);
|
|
55316
55508
|
return Math.floor(stats.bavail * stats.bsize / (1024 * 1024));
|
|
55317
55509
|
} catch {
|
|
@@ -55643,7 +55835,7 @@ async function prepareForgeTurn(ctx, workOrder, execution) {
|
|
|
55643
55835
|
let workspace;
|
|
55644
55836
|
try {
|
|
55645
55837
|
workspace = await prepareForgeWorkspace({
|
|
55646
|
-
baseDir:
|
|
55838
|
+
baseDir: path7.join(ctx.config.homeDir, ".rost", "forge", ctx.state.runner_id),
|
|
55647
55839
|
tenantId,
|
|
55648
55840
|
buildRequestId,
|
|
55649
55841
|
changeset: { id: buildRequestId, ordinal: 1, total: 1 },
|
|
@@ -55663,7 +55855,7 @@ async function prepareForgeTurn(ctx, workOrder, execution) {
|
|
|
55663
55855
|
tmpDir: tmpdir2(),
|
|
55664
55856
|
homeDir: ctx.config.homeDir,
|
|
55665
55857
|
stateFile: ctx.config.stateFile,
|
|
55666
|
-
runnerBaseDir:
|
|
55858
|
+
runnerBaseDir: path7.join(ctx.config.homeDir, ".rost"),
|
|
55667
55859
|
allowWritePaths: [workspace.baseRepo],
|
|
55668
55860
|
// Re-allow the shared object store for local commits, but DENY the model writing the
|
|
55669
55861
|
// repo's hook + config (and the worktree's gitdir pointer). The harness runs git
|
|
@@ -55671,9 +55863,9 @@ async function prepareForgeTurn(ctx, workOrder, execution) {
|
|
|
55671
55863
|
// hook or `ext::`/`insteadOf` config would otherwise exfiltrate it (DER-1327 review).
|
|
55672
55864
|
// `.git/{objects,refs,worktrees,logs,index,HEAD}` stay writable so the model can commit.
|
|
55673
55865
|
denyWritePaths: [
|
|
55674
|
-
`${
|
|
55675
|
-
|
|
55676
|
-
|
|
55866
|
+
`${path7.join(workspace.baseRepo, ".git", "hooks")}/`,
|
|
55867
|
+
path7.join(workspace.baseRepo, ".git", "config"),
|
|
55868
|
+
path7.join(workspace.worktreeDir, ".git")
|
|
55677
55869
|
],
|
|
55678
55870
|
allowNetwork: ctx.config.sandboxAllowNetwork
|
|
55679
55871
|
});
|
|
@@ -55692,7 +55884,7 @@ async function prepareForgeTurn(ctx, workOrder, execution) {
|
|
|
55692
55884
|
var FORGE_MAX_CHANGED_PATHS = 2e3;
|
|
55693
55885
|
var FORGE_MAX_CHANGED_PATH_LENGTH = 500;
|
|
55694
55886
|
function forgeChangedPathsField(changedPaths) {
|
|
55695
|
-
const withinCaps = changedPaths.length > 0 && changedPaths.length <= FORGE_MAX_CHANGED_PATHS && changedPaths.every((
|
|
55887
|
+
const withinCaps = changedPaths.length > 0 && changedPaths.length <= FORGE_MAX_CHANGED_PATHS && changedPaths.every((path8) => path8.length >= 1 && path8.length <= FORGE_MAX_CHANGED_PATH_LENGTH);
|
|
55696
55888
|
return withinCaps ? { changedPaths: [...changedPaths] } : {};
|
|
55697
55889
|
}
|
|
55698
55890
|
async function finalizeForgeBuildPush(ctx, prep, result) {
|
|
@@ -55833,9 +56025,9 @@ async function spawnRunnerTurn(ctx, workOrder, runtime, kind) {
|
|
|
55833
56025
|
const token = typeof mcp.token === "string" ? mcp.token : "";
|
|
55834
56026
|
const url2 = typeof mcp.url === "string" ? `${ctx.appUrl.replace(/\/+$/, "")}${mcp.url}` : `${ctx.appUrl.replace(/\/+$/, "")}/mcp`;
|
|
55835
56027
|
const mcpConfig = JSON.stringify({ mcpServers: { rost: { type: "http", url: url2, headers: { Authorization: `Bearer ${token}` } } } });
|
|
55836
|
-
const configPath =
|
|
56028
|
+
const configPath = path7.join(tmpdir2(), `rost-runner-mcp-${createHash2("sha256").update(`${url2}:${Date.now()}:${Math.random()}`).digest("hex").slice(0, 16)}.json`);
|
|
55837
56029
|
const prompt = buildTurnPrompt({ kind, workOrder, execution, hasWorkspace: forgePrep !== null });
|
|
55838
|
-
await
|
|
56030
|
+
await writeFile5(configPath, `${mcpConfig}
|
|
55839
56031
|
`, { mode: 384 });
|
|
55840
56032
|
await chmod2(configPath, 384);
|
|
55841
56033
|
const resumeSessionId = runtime === "claude" ? getClaudeResumeSessionId(ctx.state, workOrder) : void 0;
|
|
@@ -55850,11 +56042,11 @@ async function spawnRunnerTurn(ctx, workOrder, runtime, kind) {
|
|
|
55850
56042
|
});
|
|
55851
56043
|
let sandboxProfilePath = null;
|
|
55852
56044
|
if (sandbox.kind === "seatbelt") {
|
|
55853
|
-
sandboxProfilePath =
|
|
56045
|
+
sandboxProfilePath = path7.join(
|
|
55854
56046
|
tmpdir2(),
|
|
55855
56047
|
`rost-runner-sandbox-${createHash2("sha256").update(`${configPath}:${Math.random()}`).digest("hex").slice(0, 16)}.sb`
|
|
55856
56048
|
);
|
|
55857
|
-
await
|
|
56049
|
+
await writeFile5(sandboxProfilePath, sandbox.profile, { mode: 384 });
|
|
55858
56050
|
await chmod2(sandboxProfilePath, 384);
|
|
55859
56051
|
}
|
|
55860
56052
|
const { command, args } = wrapCommandWithSandbox(sandbox, built.command, built.args, sandboxProfilePath);
|
|
@@ -55985,7 +56177,7 @@ async function resolveMergeConflictTurn(ctx, input) {
|
|
|
55985
56177
|
let workspace;
|
|
55986
56178
|
try {
|
|
55987
56179
|
workspace = await prepareMergeWorkspace({
|
|
55988
|
-
baseDir:
|
|
56180
|
+
baseDir: path7.join(ctx.config.homeDir, ".rost", "forge", ctx.state.runner_id),
|
|
55989
56181
|
tenantId,
|
|
55990
56182
|
buildRequestId: input.buildRequestId,
|
|
55991
56183
|
repo: input.repo,
|
|
@@ -56003,12 +56195,12 @@ async function resolveMergeConflictTurn(ctx, input) {
|
|
|
56003
56195
|
tmpDir: tmpdir2(),
|
|
56004
56196
|
homeDir: ctx.config.homeDir,
|
|
56005
56197
|
stateFile: ctx.config.stateFile,
|
|
56006
|
-
runnerBaseDir:
|
|
56198
|
+
runnerBaseDir: path7.join(ctx.config.homeDir, ".rost"),
|
|
56007
56199
|
allowWritePaths: [workspace.baseRepo],
|
|
56008
56200
|
denyWritePaths: [
|
|
56009
|
-
`${
|
|
56010
|
-
|
|
56011
|
-
|
|
56201
|
+
`${path7.join(workspace.baseRepo, ".git", "hooks")}/`,
|
|
56202
|
+
path7.join(workspace.baseRepo, ".git", "config"),
|
|
56203
|
+
path7.join(workspace.worktreeDir, ".git")
|
|
56012
56204
|
],
|
|
56013
56205
|
allowNetwork: ctx.config.sandboxAllowNetwork
|
|
56014
56206
|
});
|
|
@@ -56038,8 +56230,8 @@ async function spawnMergeConflictModel(ctx, input) {
|
|
|
56038
56230
|
const token = typeof mcp.token === "string" ? mcp.token : "";
|
|
56039
56231
|
const url2 = typeof mcp.url === "string" ? `${ctx.appUrl.replace(/\/+$/, "")}${mcp.url}` : `${ctx.appUrl.replace(/\/+$/, "")}/mcp`;
|
|
56040
56232
|
const mcpConfig = JSON.stringify({ mcpServers: { rost: { type: "http", url: url2, headers: { Authorization: `Bearer ${token}` } } } });
|
|
56041
|
-
const configPath =
|
|
56042
|
-
await
|
|
56233
|
+
const configPath = path7.join(tmpdir2(), `rost-runner-mcp-${createHash2("sha256").update(`${url2}:${Date.now()}:${Math.random()}`).digest("hex").slice(0, 16)}.json`);
|
|
56234
|
+
await writeFile5(configPath, `${mcpConfig}
|
|
56043
56235
|
`, { mode: 384 });
|
|
56044
56236
|
await chmod2(configPath, 384);
|
|
56045
56237
|
const plan = resolveTurnPlan({ kind: "work_order", execution: input.execution, repoDir: input.workspace.worktreeDir });
|
|
@@ -56051,8 +56243,8 @@ async function spawnMergeConflictModel(ctx, input) {
|
|
|
56051
56243
|
].join("\n");
|
|
56052
56244
|
let sandboxProfilePath = null;
|
|
56053
56245
|
if (input.sandbox.kind === "seatbelt") {
|
|
56054
|
-
sandboxProfilePath =
|
|
56055
|
-
await
|
|
56246
|
+
sandboxProfilePath = path7.join(tmpdir2(), `rost-runner-sandbox-${createHash2("sha256").update(`${configPath}:${Math.random()}`).digest("hex").slice(0, 16)}.sb`);
|
|
56247
|
+
await writeFile5(sandboxProfilePath, input.sandbox.profile, { mode: 384 });
|
|
56056
56248
|
await chmod2(sandboxProfilePath, 384);
|
|
56057
56249
|
}
|
|
56058
56250
|
const built = buildTurnCommand({
|