@botiverse/raft-daemon 0.69.0 → 0.70.0
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/{chunk-URPIDKXK.js → chunk-QDPBPYD7.js} +116 -40
- package/dist/cli/index.js +667 -352
- package/dist/core.js +1 -1
- package/dist/{dist-P3SAWND7.js → dist-I6ATP6I5.js} +655 -348
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -31,6 +31,9 @@ import fs5 from "fs";
|
|
|
31
31
|
import os4 from "os";
|
|
32
32
|
import path8 from "path";
|
|
33
33
|
import fs6 from "fs";
|
|
34
|
+
import os5 from "os";
|
|
35
|
+
import path9 from "path";
|
|
36
|
+
import fs7 from "fs";
|
|
34
37
|
var require2 = __raftCreateRequire(import.meta.url);
|
|
35
38
|
var __create = Object.create;
|
|
36
39
|
var __defProp = Object.defineProperty;
|
|
@@ -1013,8 +1016,8 @@ var require_command = __commonJS({
|
|
|
1013
1016
|
init_esm_shims();
|
|
1014
1017
|
var EventEmitter = __require("events").EventEmitter;
|
|
1015
1018
|
var childProcess = __require("child_process");
|
|
1016
|
-
var
|
|
1017
|
-
var
|
|
1019
|
+
var path10 = __require("path");
|
|
1020
|
+
var fs8 = __require("fs");
|
|
1018
1021
|
var process3 = __require("process");
|
|
1019
1022
|
var { Argument: Argument2, humanReadableArgName } = require_argument();
|
|
1020
1023
|
var { CommanderError: CommanderError2 } = require_error();
|
|
@@ -1946,11 +1949,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1946
1949
|
let launchWithNode = false;
|
|
1947
1950
|
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
1948
1951
|
function findFile(baseDir, baseName) {
|
|
1949
|
-
const localBin =
|
|
1950
|
-
if (
|
|
1951
|
-
if (sourceExt.includes(
|
|
1952
|
+
const localBin = path10.resolve(baseDir, baseName);
|
|
1953
|
+
if (fs8.existsSync(localBin)) return localBin;
|
|
1954
|
+
if (sourceExt.includes(path10.extname(baseName))) return void 0;
|
|
1952
1955
|
const foundExt = sourceExt.find(
|
|
1953
|
-
(ext) =>
|
|
1956
|
+
(ext) => fs8.existsSync(`${localBin}${ext}`)
|
|
1954
1957
|
);
|
|
1955
1958
|
if (foundExt) return `${localBin}${foundExt}`;
|
|
1956
1959
|
return void 0;
|
|
@@ -1962,21 +1965,21 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1962
1965
|
if (this._scriptPath) {
|
|
1963
1966
|
let resolvedScriptPath;
|
|
1964
1967
|
try {
|
|
1965
|
-
resolvedScriptPath =
|
|
1968
|
+
resolvedScriptPath = fs8.realpathSync(this._scriptPath);
|
|
1966
1969
|
} catch (err) {
|
|
1967
1970
|
resolvedScriptPath = this._scriptPath;
|
|
1968
1971
|
}
|
|
1969
|
-
executableDir =
|
|
1970
|
-
|
|
1972
|
+
executableDir = path10.resolve(
|
|
1973
|
+
path10.dirname(resolvedScriptPath),
|
|
1971
1974
|
executableDir
|
|
1972
1975
|
);
|
|
1973
1976
|
}
|
|
1974
1977
|
if (executableDir) {
|
|
1975
1978
|
let localFile = findFile(executableDir, executableFile);
|
|
1976
1979
|
if (!localFile && !subcommand._executableFile && this._scriptPath) {
|
|
1977
|
-
const legacyName =
|
|
1980
|
+
const legacyName = path10.basename(
|
|
1978
1981
|
this._scriptPath,
|
|
1979
|
-
|
|
1982
|
+
path10.extname(this._scriptPath)
|
|
1980
1983
|
);
|
|
1981
1984
|
if (legacyName !== this._name) {
|
|
1982
1985
|
localFile = findFile(
|
|
@@ -1987,7 +1990,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1987
1990
|
}
|
|
1988
1991
|
executableFile = localFile || executableFile;
|
|
1989
1992
|
}
|
|
1990
|
-
launchWithNode = sourceExt.includes(
|
|
1993
|
+
launchWithNode = sourceExt.includes(path10.extname(executableFile));
|
|
1991
1994
|
let proc;
|
|
1992
1995
|
if (process3.platform !== "win32") {
|
|
1993
1996
|
if (launchWithNode) {
|
|
@@ -2827,7 +2830,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2827
2830
|
* @return {Command}
|
|
2828
2831
|
*/
|
|
2829
2832
|
nameFromFilename(filename) {
|
|
2830
|
-
this._name =
|
|
2833
|
+
this._name = path10.basename(filename, path10.extname(filename));
|
|
2831
2834
|
return this;
|
|
2832
2835
|
}
|
|
2833
2836
|
/**
|
|
@@ -2841,9 +2844,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2841
2844
|
* @param {string} [path]
|
|
2842
2845
|
* @return {(string|null|Command)}
|
|
2843
2846
|
*/
|
|
2844
|
-
executableDir(
|
|
2845
|
-
if (
|
|
2846
|
-
this._executableDir =
|
|
2847
|
+
executableDir(path11) {
|
|
2848
|
+
if (path11 === void 0) return this._executableDir;
|
|
2849
|
+
this._executableDir = path11;
|
|
2847
2850
|
return this;
|
|
2848
2851
|
}
|
|
2849
2852
|
/**
|
|
@@ -4175,14 +4178,14 @@ var require_util = __commonJS({
|
|
|
4175
4178
|
}
|
|
4176
4179
|
const port = url2.port != null ? url2.port : url2.protocol === "https:" ? 443 : 80;
|
|
4177
4180
|
let origin = url2.origin != null ? url2.origin : `${url2.protocol || ""}//${url2.hostname || ""}:${port}`;
|
|
4178
|
-
let
|
|
4181
|
+
let path10 = url2.path != null ? url2.path : `${url2.pathname || ""}${url2.search || ""}`;
|
|
4179
4182
|
if (origin[origin.length - 1] === "/") {
|
|
4180
4183
|
origin = origin.slice(0, origin.length - 1);
|
|
4181
4184
|
}
|
|
4182
|
-
if (
|
|
4183
|
-
|
|
4185
|
+
if (path10 && path10[0] !== "/") {
|
|
4186
|
+
path10 = `/${path10}`;
|
|
4184
4187
|
}
|
|
4185
|
-
return new URL(`${origin}${
|
|
4188
|
+
return new URL(`${origin}${path10}`);
|
|
4186
4189
|
}
|
|
4187
4190
|
if (!isHttpOrHttpsPrefixed(url2.origin || url2.protocol)) {
|
|
4188
4191
|
throw new InvalidArgumentError2("Invalid URL protocol: the URL must start with `http:` or `https:`.");
|
|
@@ -5001,9 +5004,9 @@ var require_diagnostics = __commonJS({
|
|
|
5001
5004
|
"undici:client:sendHeaders",
|
|
5002
5005
|
(evt) => {
|
|
5003
5006
|
const {
|
|
5004
|
-
request: { method, path:
|
|
5007
|
+
request: { method, path: path10, origin }
|
|
5005
5008
|
} = evt;
|
|
5006
|
-
debugLog("sending request to %s %s%s", method, origin,
|
|
5009
|
+
debugLog("sending request to %s %s%s", method, origin, path10);
|
|
5007
5010
|
}
|
|
5008
5011
|
);
|
|
5009
5012
|
}
|
|
@@ -5021,14 +5024,14 @@ var require_diagnostics = __commonJS({
|
|
|
5021
5024
|
"undici:request:headers",
|
|
5022
5025
|
(evt) => {
|
|
5023
5026
|
const {
|
|
5024
|
-
request: { method, path:
|
|
5027
|
+
request: { method, path: path10, origin },
|
|
5025
5028
|
response: { statusCode }
|
|
5026
5029
|
} = evt;
|
|
5027
5030
|
debugLog(
|
|
5028
5031
|
"received response to %s %s%s - HTTP %d",
|
|
5029
5032
|
method,
|
|
5030
5033
|
origin,
|
|
5031
|
-
|
|
5034
|
+
path10,
|
|
5032
5035
|
statusCode
|
|
5033
5036
|
);
|
|
5034
5037
|
}
|
|
@@ -5037,23 +5040,23 @@ var require_diagnostics = __commonJS({
|
|
|
5037
5040
|
"undici:request:trailers",
|
|
5038
5041
|
(evt) => {
|
|
5039
5042
|
const {
|
|
5040
|
-
request: { method, path:
|
|
5043
|
+
request: { method, path: path10, origin }
|
|
5041
5044
|
} = evt;
|
|
5042
|
-
debugLog("trailers received from %s %s%s", method, origin,
|
|
5045
|
+
debugLog("trailers received from %s %s%s", method, origin, path10);
|
|
5043
5046
|
}
|
|
5044
5047
|
);
|
|
5045
5048
|
diagnosticsChannel.subscribe(
|
|
5046
5049
|
"undici:request:error",
|
|
5047
5050
|
(evt) => {
|
|
5048
5051
|
const {
|
|
5049
|
-
request: { method, path:
|
|
5052
|
+
request: { method, path: path10, origin },
|
|
5050
5053
|
error: error48
|
|
5051
5054
|
} = evt;
|
|
5052
5055
|
debugLog(
|
|
5053
5056
|
"request to %s %s%s errored - %s",
|
|
5054
5057
|
method,
|
|
5055
5058
|
origin,
|
|
5056
|
-
|
|
5059
|
+
path10,
|
|
5057
5060
|
error48.message
|
|
5058
5061
|
);
|
|
5059
5062
|
}
|
|
@@ -5155,7 +5158,7 @@ var require_request = __commonJS({
|
|
|
5155
5158
|
var kHandler = /* @__PURE__ */ Symbol("handler");
|
|
5156
5159
|
var Request = class {
|
|
5157
5160
|
constructor(origin, {
|
|
5158
|
-
path:
|
|
5161
|
+
path: path10,
|
|
5159
5162
|
method,
|
|
5160
5163
|
body,
|
|
5161
5164
|
headers,
|
|
@@ -5172,11 +5175,11 @@ var require_request = __commonJS({
|
|
|
5172
5175
|
maxRedirections,
|
|
5173
5176
|
typeOfService
|
|
5174
5177
|
}, handler) {
|
|
5175
|
-
if (typeof
|
|
5178
|
+
if (typeof path10 !== "string") {
|
|
5176
5179
|
throw new InvalidArgumentError2("path must be a string");
|
|
5177
|
-
} else if (
|
|
5180
|
+
} else if (path10[0] !== "/" && !(path10.startsWith("http://") || path10.startsWith("https://")) && method !== "CONNECT") {
|
|
5178
5181
|
throw new InvalidArgumentError2("path must be an absolute URL or start with a slash");
|
|
5179
|
-
} else if (invalidPathRegex.test(
|
|
5182
|
+
} else if (invalidPathRegex.test(path10)) {
|
|
5180
5183
|
throw new InvalidArgumentError2("invalid request path");
|
|
5181
5184
|
}
|
|
5182
5185
|
if (typeof method !== "string") {
|
|
@@ -5251,7 +5254,7 @@ var require_request = __commonJS({
|
|
|
5251
5254
|
this.completed = false;
|
|
5252
5255
|
this.aborted = false;
|
|
5253
5256
|
this.upgrade = upgrade || null;
|
|
5254
|
-
this.path = query ? serializePathWithQuery(
|
|
5257
|
+
this.path = query ? serializePathWithQuery(path10, query) : path10;
|
|
5255
5258
|
this.origin = origin;
|
|
5256
5259
|
this.protocol = getProtocolFromUrlString(origin);
|
|
5257
5260
|
this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" : idempotent;
|
|
@@ -10268,7 +10271,7 @@ var require_client_h1 = __commonJS({
|
|
|
10268
10271
|
return method !== "GET" && method !== "HEAD" && method !== "OPTIONS" && method !== "TRACE" && method !== "CONNECT";
|
|
10269
10272
|
}
|
|
10270
10273
|
function writeH1(client, request) {
|
|
10271
|
-
const { method, path:
|
|
10274
|
+
const { method, path: path10, host, upgrade, blocking, reset } = request;
|
|
10272
10275
|
let { body, headers, contentLength } = request;
|
|
10273
10276
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH" || method === "QUERY" || method === "PROPFIND" || method === "PROPPATCH";
|
|
10274
10277
|
if (util.isFormDataLike(body)) {
|
|
@@ -10337,7 +10340,7 @@ var require_client_h1 = __commonJS({
|
|
|
10337
10340
|
if (socket.setTypeOfService) {
|
|
10338
10341
|
socket.setTypeOfService(request.typeOfService);
|
|
10339
10342
|
}
|
|
10340
|
-
let header = `${method} ${
|
|
10343
|
+
let header = `${method} ${path10} HTTP/1.1\r
|
|
10341
10344
|
`;
|
|
10342
10345
|
if (typeof host === "string") {
|
|
10343
10346
|
header += `host: ${host}\r
|
|
@@ -10989,7 +10992,7 @@ var require_client_h2 = __commonJS({
|
|
|
10989
10992
|
function writeH2(client, request) {
|
|
10990
10993
|
const requestTimeout = request.bodyTimeout ?? client[kBodyTimeout];
|
|
10991
10994
|
const session = client[kHTTP2Session];
|
|
10992
|
-
const { method, path:
|
|
10995
|
+
const { method, path: path10, host, upgrade, expectContinue, signal, protocol, headers: reqHeaders } = request;
|
|
10993
10996
|
let { body } = request;
|
|
10994
10997
|
if (upgrade != null && upgrade !== "websocket") {
|
|
10995
10998
|
util.errorRequest(client, request, new InvalidArgumentError2(`Custom upgrade "${upgrade}" not supported over HTTP/2`));
|
|
@@ -11057,7 +11060,7 @@ var require_client_h2 = __commonJS({
|
|
|
11057
11060
|
}
|
|
11058
11061
|
headers[HTTP2_HEADER_METHOD] = "CONNECT";
|
|
11059
11062
|
headers[HTTP2_HEADER_PROTOCOL] = "websocket";
|
|
11060
|
-
headers[HTTP2_HEADER_PATH] =
|
|
11063
|
+
headers[HTTP2_HEADER_PATH] = path10;
|
|
11061
11064
|
if (protocol === "ws:" || protocol === "wss:") {
|
|
11062
11065
|
headers[HTTP2_HEADER_SCHEME] = protocol === "ws:" ? "http" : "https";
|
|
11063
11066
|
} else {
|
|
@@ -11098,7 +11101,7 @@ var require_client_h2 = __commonJS({
|
|
|
11098
11101
|
stream.setTimeout(requestTimeout);
|
|
11099
11102
|
return true;
|
|
11100
11103
|
}
|
|
11101
|
-
headers[HTTP2_HEADER_PATH] =
|
|
11104
|
+
headers[HTTP2_HEADER_PATH] = path10;
|
|
11102
11105
|
headers[HTTP2_HEADER_SCHEME] = protocol === "http:" ? "http" : "https";
|
|
11103
11106
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
|
|
11104
11107
|
if (body && typeof body.read === "function") {
|
|
@@ -13389,10 +13392,10 @@ var require_proxy_agent = __commonJS({
|
|
|
13389
13392
|
};
|
|
13390
13393
|
const {
|
|
13391
13394
|
origin,
|
|
13392
|
-
path:
|
|
13395
|
+
path: path10 = "/",
|
|
13393
13396
|
headers = {}
|
|
13394
13397
|
} = opts;
|
|
13395
|
-
opts.path = origin +
|
|
13398
|
+
opts.path = origin + path10;
|
|
13396
13399
|
if (!("host" in headers) && !("Host" in headers)) {
|
|
13397
13400
|
const { host } = new URL(origin);
|
|
13398
13401
|
headers.host = host;
|
|
@@ -15440,20 +15443,20 @@ var require_mock_utils = __commonJS({
|
|
|
15440
15443
|
}
|
|
15441
15444
|
return normalizedQp;
|
|
15442
15445
|
}
|
|
15443
|
-
function
|
|
15444
|
-
if (typeof
|
|
15445
|
-
return
|
|
15446
|
+
function safeUrl3(path10) {
|
|
15447
|
+
if (typeof path10 !== "string") {
|
|
15448
|
+
return path10;
|
|
15446
15449
|
}
|
|
15447
|
-
const pathSegments =
|
|
15450
|
+
const pathSegments = path10.split("?", 3);
|
|
15448
15451
|
if (pathSegments.length !== 2) {
|
|
15449
|
-
return
|
|
15452
|
+
return path10;
|
|
15450
15453
|
}
|
|
15451
15454
|
const qp = new URLSearchParams(pathSegments.pop());
|
|
15452
15455
|
qp.sort();
|
|
15453
15456
|
return [...pathSegments, qp.toString()].join("?");
|
|
15454
15457
|
}
|
|
15455
|
-
function matchKey(mockDispatch2, { path:
|
|
15456
|
-
const pathMatch = matchValue(mockDispatch2.path,
|
|
15458
|
+
function matchKey(mockDispatch2, { path: path10, method, body, headers }) {
|
|
15459
|
+
const pathMatch = matchValue(mockDispatch2.path, path10);
|
|
15457
15460
|
const methodMatch = matchValue(mockDispatch2.method, method);
|
|
15458
15461
|
const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body) : true;
|
|
15459
15462
|
const headersMatch = matchHeaders(mockDispatch2, headers);
|
|
@@ -15476,10 +15479,10 @@ var require_mock_utils = __commonJS({
|
|
|
15476
15479
|
}
|
|
15477
15480
|
function getMockDispatch(mockDispatches, key) {
|
|
15478
15481
|
const basePath = key.query ? serializePathWithQuery(key.path, key.query) : key.path;
|
|
15479
|
-
const resolvedPath = typeof basePath === "string" ?
|
|
15482
|
+
const resolvedPath = typeof basePath === "string" ? safeUrl3(basePath) : basePath;
|
|
15480
15483
|
const resolvedPathWithoutTrailingSlash = removeTrailingSlash(resolvedPath);
|
|
15481
|
-
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path:
|
|
15482
|
-
return ignoreTrailingSlash ? matchValue(removeTrailingSlash(
|
|
15484
|
+
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path10, ignoreTrailingSlash }) => {
|
|
15485
|
+
return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl3(path10)), resolvedPathWithoutTrailingSlash) : matchValue(safeUrl3(path10), resolvedPath);
|
|
15483
15486
|
});
|
|
15484
15487
|
if (matchedMockDispatches.length === 0) {
|
|
15485
15488
|
throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
|
|
@@ -15518,19 +15521,19 @@ var require_mock_utils = __commonJS({
|
|
|
15518
15521
|
mockDispatches.splice(index, 1);
|
|
15519
15522
|
}
|
|
15520
15523
|
}
|
|
15521
|
-
function removeTrailingSlash(
|
|
15522
|
-
while (
|
|
15523
|
-
|
|
15524
|
+
function removeTrailingSlash(path10) {
|
|
15525
|
+
while (path10.endsWith("/")) {
|
|
15526
|
+
path10 = path10.slice(0, -1);
|
|
15524
15527
|
}
|
|
15525
|
-
if (
|
|
15526
|
-
|
|
15528
|
+
if (path10.length === 0) {
|
|
15529
|
+
path10 = "/";
|
|
15527
15530
|
}
|
|
15528
|
-
return
|
|
15531
|
+
return path10;
|
|
15529
15532
|
}
|
|
15530
15533
|
function buildKey(opts) {
|
|
15531
|
-
const { path:
|
|
15534
|
+
const { path: path10, method, body, headers, query } = opts;
|
|
15532
15535
|
return {
|
|
15533
|
-
path:
|
|
15536
|
+
path: path10,
|
|
15534
15537
|
method,
|
|
15535
15538
|
body,
|
|
15536
15539
|
headers,
|
|
@@ -16215,10 +16218,10 @@ var require_pending_interceptors_formatter = __commonJS({
|
|
|
16215
16218
|
}
|
|
16216
16219
|
format(pendingInterceptors) {
|
|
16217
16220
|
const withPrettyHeaders = pendingInterceptors.map(
|
|
16218
|
-
({ method, path:
|
|
16221
|
+
({ method, path: path10, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
|
|
16219
16222
|
Method: method,
|
|
16220
16223
|
Origin: origin,
|
|
16221
|
-
Path:
|
|
16224
|
+
Path: path10,
|
|
16222
16225
|
"Status code": statusCode,
|
|
16223
16226
|
Persistent: persist ? PERSISTENT : NOT_PERSISTENT,
|
|
16224
16227
|
Invocations: timesInvoked,
|
|
@@ -16299,9 +16302,9 @@ var require_mock_agent = __commonJS({
|
|
|
16299
16302
|
const acceptNonStandardSearchParameters = this[kMockAgentAcceptsNonStandardSearchParameters];
|
|
16300
16303
|
const dispatchOpts = { ...opts };
|
|
16301
16304
|
if (acceptNonStandardSearchParameters && dispatchOpts.path) {
|
|
16302
|
-
const [
|
|
16305
|
+
const [path10, searchParams] = dispatchOpts.path.split("?");
|
|
16303
16306
|
const normalizedSearchParams = normalizeSearchParams(searchParams, acceptNonStandardSearchParameters);
|
|
16304
|
-
dispatchOpts.path = `${
|
|
16307
|
+
dispatchOpts.path = `${path10}?${normalizedSearchParams}`;
|
|
16305
16308
|
}
|
|
16306
16309
|
return this[kAgent].dispatch(dispatchOpts, handler);
|
|
16307
16310
|
}
|
|
@@ -16700,12 +16703,12 @@ var require_snapshot_recorder = __commonJS({
|
|
|
16700
16703
|
* @return {Promise<void>} - Resolves when snapshots are loaded
|
|
16701
16704
|
*/
|
|
16702
16705
|
async loadSnapshots(filePath) {
|
|
16703
|
-
const
|
|
16704
|
-
if (!
|
|
16706
|
+
const path10 = filePath || this.#snapshotPath;
|
|
16707
|
+
if (!path10) {
|
|
16705
16708
|
throw new InvalidArgumentError2("Snapshot path is required");
|
|
16706
16709
|
}
|
|
16707
16710
|
try {
|
|
16708
|
-
const data = await readFile2(resolve(
|
|
16711
|
+
const data = await readFile2(resolve(path10), "utf8");
|
|
16709
16712
|
const parsed = JSON.parse(data);
|
|
16710
16713
|
if (Array.isArray(parsed)) {
|
|
16711
16714
|
this.#snapshots.clear();
|
|
@@ -16719,7 +16722,7 @@ var require_snapshot_recorder = __commonJS({
|
|
|
16719
16722
|
if (error48.code === "ENOENT") {
|
|
16720
16723
|
this.#snapshots.clear();
|
|
16721
16724
|
} else {
|
|
16722
|
-
throw new UndiciError(`Failed to load snapshots from ${
|
|
16725
|
+
throw new UndiciError(`Failed to load snapshots from ${path10}`, { cause: error48 });
|
|
16723
16726
|
}
|
|
16724
16727
|
}
|
|
16725
16728
|
}
|
|
@@ -16730,11 +16733,11 @@ var require_snapshot_recorder = __commonJS({
|
|
|
16730
16733
|
* @returns {Promise<void>} - Resolves when snapshots are saved
|
|
16731
16734
|
*/
|
|
16732
16735
|
async saveSnapshots(filePath) {
|
|
16733
|
-
const
|
|
16734
|
-
if (!
|
|
16736
|
+
const path10 = filePath || this.#snapshotPath;
|
|
16737
|
+
if (!path10) {
|
|
16735
16738
|
throw new InvalidArgumentError2("Snapshot path is required");
|
|
16736
16739
|
}
|
|
16737
|
-
const resolvedPath = resolve(
|
|
16740
|
+
const resolvedPath = resolve(path10);
|
|
16738
16741
|
await mkdir2(dirname(resolvedPath), { recursive: true });
|
|
16739
16742
|
const data = Array.from(this.#snapshots.entries()).map(([hash2, snapshot]) => ({
|
|
16740
16743
|
hash: hash2,
|
|
@@ -17355,15 +17358,15 @@ var require_redirect_handler = __commonJS({
|
|
|
17355
17358
|
return;
|
|
17356
17359
|
}
|
|
17357
17360
|
const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)));
|
|
17358
|
-
const
|
|
17359
|
-
const redirectUrlString = `${origin}${
|
|
17361
|
+
const path10 = search ? `${pathname}${search}` : pathname;
|
|
17362
|
+
const redirectUrlString = `${origin}${path10}`;
|
|
17360
17363
|
for (const historyUrl of this.history) {
|
|
17361
17364
|
if (historyUrl.toString() === redirectUrlString) {
|
|
17362
17365
|
throw new InvalidArgumentError2(`Redirect loop detected. Cannot redirect to ${origin}. This typically happens when using a Client or Pool with cross-origin redirects. Use an Agent for cross-origin redirects.`);
|
|
17363
17366
|
}
|
|
17364
17367
|
}
|
|
17365
17368
|
this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin);
|
|
17366
|
-
this.opts.path =
|
|
17369
|
+
this.opts.path = path10;
|
|
17367
17370
|
this.opts.origin = origin;
|
|
17368
17371
|
this.opts.query = null;
|
|
17369
17372
|
}
|
|
@@ -23550,11 +23553,11 @@ var require_fetch = __commonJS({
|
|
|
23550
23553
|
function dispatch({ body }) {
|
|
23551
23554
|
const url2 = requestCurrentURL(request);
|
|
23552
23555
|
const agent = fetchParams.controller.dispatcher;
|
|
23553
|
-
const
|
|
23556
|
+
const path10 = url2.pathname + url2.search;
|
|
23554
23557
|
const hasTrailingQuestionMark = url2.search.length === 0 && url2.href[url2.href.length - url2.hash.length - 1] === "?";
|
|
23555
23558
|
return new Promise((resolve, reject) => agent.dispatch(
|
|
23556
23559
|
{
|
|
23557
|
-
path: hasTrailingQuestionMark ? `${
|
|
23560
|
+
path: hasTrailingQuestionMark ? `${path10}?` : path10,
|
|
23558
23561
|
origin: url2.origin,
|
|
23559
23562
|
method: request.method,
|
|
23560
23563
|
body: agent.isMockActive ? request.body && (request.body.source || request.body.stream) : body,
|
|
@@ -24496,9 +24499,9 @@ var require_util4 = __commonJS({
|
|
|
24496
24499
|
}
|
|
24497
24500
|
}
|
|
24498
24501
|
}
|
|
24499
|
-
function validateCookiePath(
|
|
24500
|
-
for (let i = 0; i <
|
|
24501
|
-
const code =
|
|
24502
|
+
function validateCookiePath(path10) {
|
|
24503
|
+
for (let i = 0; i < path10.length; ++i) {
|
|
24504
|
+
const code = path10.charCodeAt(i);
|
|
24502
24505
|
if (code < 32 || // exclude CTLs (0-31)
|
|
24503
24506
|
code === 127 || // DEL
|
|
24504
24507
|
code === 59) {
|
|
@@ -27651,11 +27654,11 @@ var require_undici = __commonJS({
|
|
|
27651
27654
|
if (typeof opts.path !== "string") {
|
|
27652
27655
|
throw new InvalidArgumentError2("invalid opts.path");
|
|
27653
27656
|
}
|
|
27654
|
-
let
|
|
27657
|
+
let path10 = opts.path;
|
|
27655
27658
|
if (!opts.path.startsWith("/")) {
|
|
27656
|
-
|
|
27659
|
+
path10 = `/${path10}`;
|
|
27657
27660
|
}
|
|
27658
|
-
url2 = new URL(util.parseOrigin(url2).origin +
|
|
27661
|
+
url2 = new URL(util.parseOrigin(url2).origin + path10);
|
|
27659
27662
|
} else {
|
|
27660
27663
|
if (!opts) {
|
|
27661
27664
|
opts = typeof url2 === "object" ? url2 : {};
|
|
@@ -29281,10 +29284,10 @@ function mergeDefs(...defs) {
|
|
|
29281
29284
|
function cloneDef(schema) {
|
|
29282
29285
|
return mergeDefs(schema._zod.def);
|
|
29283
29286
|
}
|
|
29284
|
-
function getElementAtPath(obj,
|
|
29285
|
-
if (!
|
|
29287
|
+
function getElementAtPath(obj, path10) {
|
|
29288
|
+
if (!path10)
|
|
29286
29289
|
return obj;
|
|
29287
|
-
return
|
|
29290
|
+
return path10.reduce((acc, key) => acc?.[key], obj);
|
|
29288
29291
|
}
|
|
29289
29292
|
function promiseAllObject(promisesObj) {
|
|
29290
29293
|
const keys = Object.keys(promisesObj);
|
|
@@ -29667,11 +29670,11 @@ function aborted(x, startIndex = 0) {
|
|
|
29667
29670
|
}
|
|
29668
29671
|
return false;
|
|
29669
29672
|
}
|
|
29670
|
-
function prefixIssues(
|
|
29673
|
+
function prefixIssues(path10, issues) {
|
|
29671
29674
|
return issues.map((iss) => {
|
|
29672
29675
|
var _a2;
|
|
29673
29676
|
(_a2 = iss).path ?? (_a2.path = []);
|
|
29674
|
-
iss.path.unshift(
|
|
29677
|
+
iss.path.unshift(path10);
|
|
29675
29678
|
return iss;
|
|
29676
29679
|
});
|
|
29677
29680
|
}
|
|
@@ -29852,7 +29855,7 @@ function formatError(error48, mapper = (issue2) => issue2.message) {
|
|
|
29852
29855
|
}
|
|
29853
29856
|
function treeifyError(error48, mapper = (issue2) => issue2.message) {
|
|
29854
29857
|
const result2 = { errors: [] };
|
|
29855
|
-
const processError = (error49,
|
|
29858
|
+
const processError = (error49, path10 = []) => {
|
|
29856
29859
|
var _a2, _b;
|
|
29857
29860
|
for (const issue2 of error49.issues) {
|
|
29858
29861
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
@@ -29862,7 +29865,7 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
|
|
|
29862
29865
|
} else if (issue2.code === "invalid_element") {
|
|
29863
29866
|
processError({ issues: issue2.issues }, issue2.path);
|
|
29864
29867
|
} else {
|
|
29865
|
-
const fullpath = [...
|
|
29868
|
+
const fullpath = [...path10, ...issue2.path];
|
|
29866
29869
|
if (fullpath.length === 0) {
|
|
29867
29870
|
result2.errors.push(mapper(issue2));
|
|
29868
29871
|
continue;
|
|
@@ -29894,8 +29897,8 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
|
|
|
29894
29897
|
}
|
|
29895
29898
|
function toDotPath(_path) {
|
|
29896
29899
|
const segs = [];
|
|
29897
|
-
const
|
|
29898
|
-
for (const seg of
|
|
29900
|
+
const path10 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
29901
|
+
for (const seg of path10) {
|
|
29899
29902
|
if (typeof seg === "number")
|
|
29900
29903
|
segs.push(`[${seg}]`);
|
|
29901
29904
|
else if (typeof seg === "symbol")
|
|
@@ -41800,13 +41803,13 @@ function resolveRef(ref, ctx) {
|
|
|
41800
41803
|
if (!ref.startsWith("#")) {
|
|
41801
41804
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
41802
41805
|
}
|
|
41803
|
-
const
|
|
41804
|
-
if (
|
|
41806
|
+
const path10 = ref.slice(1).split("/").filter(Boolean);
|
|
41807
|
+
if (path10.length === 0) {
|
|
41805
41808
|
return ctx.rootSchema;
|
|
41806
41809
|
}
|
|
41807
41810
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
41808
|
-
if (
|
|
41809
|
-
const key =
|
|
41811
|
+
if (path10[0] === defsKey) {
|
|
41812
|
+
const key = path10[1];
|
|
41810
41813
|
if (!key || !ctx.defs[key]) {
|
|
41811
41814
|
throw new Error(`Reference not found: ${ref}`);
|
|
41812
41815
|
}
|
|
@@ -42701,7 +42704,12 @@ var agentApiIntegrationLoginResponseSchema = passthroughObject({
|
|
|
42701
42704
|
status: external_exports.enum(["logged_in", "already_logged_in", "approval_required"]),
|
|
42702
42705
|
service: agentApiIntegrationServiceSchema,
|
|
42703
42706
|
scopes: external_exports.array(external_exports.string()),
|
|
42704
|
-
requestId: external_exports.string(),
|
|
42707
|
+
requestId: external_exports.string().optional(),
|
|
42708
|
+
session: passthroughObject({
|
|
42709
|
+
status: external_exports.literal("stored"),
|
|
42710
|
+
source: external_exports.enum(["cache", "fresh"]),
|
|
42711
|
+
path: nullableStringSchema
|
|
42712
|
+
}).optional(),
|
|
42705
42713
|
approval: passthroughObject({
|
|
42706
42714
|
requestId: external_exports.string(),
|
|
42707
42715
|
target: nullableStringSchema,
|
|
@@ -43457,11 +43465,11 @@ function isAgentApiRawFailure(value) {
|
|
|
43457
43465
|
);
|
|
43458
43466
|
}
|
|
43459
43467
|
function buildAgentApiRawRoutePath(routeKey, options = {}) {
|
|
43460
|
-
let
|
|
43468
|
+
let path10;
|
|
43461
43469
|
try {
|
|
43462
43470
|
const encodedPath = encodePathParams(routeKey, options.params);
|
|
43463
43471
|
if (typeof encodedPath !== "string") return encodedPath;
|
|
43464
|
-
|
|
43472
|
+
path10 = encodedPath;
|
|
43465
43473
|
} catch (cause) {
|
|
43466
43474
|
if (cause instanceof MissingPathParamError) {
|
|
43467
43475
|
return failure(routeKey, "missing_path_param", cause.message, { cause });
|
|
@@ -43471,12 +43479,12 @@ function buildAgentApiRawRoutePath(routeKey, options = {}) {
|
|
|
43471
43479
|
const query = encodeQuery(routeKey, options.query);
|
|
43472
43480
|
if (query && !(query instanceof URLSearchParams)) return query;
|
|
43473
43481
|
const suffix = query && query.size > 0 ? `?${query.toString()}` : "";
|
|
43474
|
-
return `${options.pathPrefix ?? AGENT_API_BASE_PATH}${
|
|
43482
|
+
return `${options.pathPrefix ?? AGENT_API_BASE_PATH}${path10}${suffix}`;
|
|
43475
43483
|
}
|
|
43476
43484
|
async function requestAgentApiRawRoute(transport, routeKey, options = {}) {
|
|
43477
43485
|
const route3 = agentApiContract[routeKey];
|
|
43478
|
-
const
|
|
43479
|
-
if (typeof
|
|
43486
|
+
const path10 = buildAgentApiRawRoutePath(routeKey, options);
|
|
43487
|
+
if (typeof path10 !== "string") return path10;
|
|
43480
43488
|
const body = parseBody(routeKey, options.body);
|
|
43481
43489
|
if (isAgentApiRawFailure(body)) return body;
|
|
43482
43490
|
let response;
|
|
@@ -43484,7 +43492,7 @@ async function requestAgentApiRawRoute(transport, routeKey, options = {}) {
|
|
|
43484
43492
|
response = await transport.request({
|
|
43485
43493
|
routeKey,
|
|
43486
43494
|
method: route3.method,
|
|
43487
|
-
path:
|
|
43495
|
+
path: path10,
|
|
43488
43496
|
body
|
|
43489
43497
|
});
|
|
43490
43498
|
} catch (cause) {
|
|
@@ -43870,8 +43878,8 @@ function buildDaemonApiRawRoutePath(routeKey, options = {}) {
|
|
|
43870
43878
|
}
|
|
43871
43879
|
async function requestDaemonApiRawRoute(transport, routeKey, options = {}) {
|
|
43872
43880
|
const route3 = daemonApiContract[routeKey];
|
|
43873
|
-
const
|
|
43874
|
-
if (typeof
|
|
43881
|
+
const path10 = buildDaemonApiRawRoutePath(routeKey, options);
|
|
43882
|
+
if (typeof path10 !== "string") return path10;
|
|
43875
43883
|
const body = parseBody2(routeKey, options.body);
|
|
43876
43884
|
if (isDaemonApiRawFailure(body)) return body;
|
|
43877
43885
|
let response;
|
|
@@ -43879,7 +43887,7 @@ async function requestDaemonApiRawRoute(transport, routeKey, options = {}) {
|
|
|
43879
43887
|
response = await transport.request({
|
|
43880
43888
|
routeKey,
|
|
43881
43889
|
method: route3.method,
|
|
43882
|
-
path:
|
|
43890
|
+
path: path10,
|
|
43883
43891
|
body
|
|
43884
43892
|
});
|
|
43885
43893
|
} catch (cause) {
|
|
@@ -44615,13 +44623,15 @@ var DISPLAY_PLAN_CONFIG = {
|
|
|
44615
44623
|
}
|
|
44616
44624
|
};
|
|
44617
44625
|
var FREE_MONTHLY_FILE_UPLOAD_LIMIT_BYTES = 100 * 1024 * 1024;
|
|
44626
|
+
var FREE_SINGLE_FILE_UPLOAD_LIMIT_BYTES = 50 * 1024 * 1024;
|
|
44627
|
+
var PRO_SINGLE_FILE_UPLOAD_LIMIT_BYTES = 200 * 1024 * 1024;
|
|
44618
44628
|
var TRIAL_START_DATE = /* @__PURE__ */ new Date("2026-04-18T00:00:00Z");
|
|
44619
44629
|
var TRIAL_END_DATE = /* @__PURE__ */ new Date("2026-06-23T12:00:00Z");
|
|
44620
44630
|
var TRIAL_DURATION_DAYS = (TRIAL_END_DATE.getTime() - TRIAL_START_DATE.getTime()) / (24 * 60 * 60 * 1e3);
|
|
44621
44631
|
function buildAgentApiRoutePath(routeKey, pathParams, query) {
|
|
44622
|
-
const
|
|
44623
|
-
if (typeof
|
|
44624
|
-
throw cliErrorFromRawFailure(
|
|
44632
|
+
const path10 = buildAgentApiRawRoutePath(routeKey, { params: pathParams, query });
|
|
44633
|
+
if (typeof path10 === "string") return path10;
|
|
44634
|
+
throw cliErrorFromRawFailure(path10);
|
|
44625
44635
|
}
|
|
44626
44636
|
function buildAgentApiEventsPath(query) {
|
|
44627
44637
|
return buildAgentApiRoutePath("events", void 0, query);
|
|
@@ -45386,7 +45396,7 @@ function loadAgentContext(env = process.env) {
|
|
|
45386
45396
|
const shadowed = RAW_AGENT_ENV_KEYS.filter((k) => env[k]);
|
|
45387
45397
|
if (shadowed.length > 0) {
|
|
45388
45398
|
process.stderr.write(
|
|
45389
|
-
`
|
|
45399
|
+
`raft: RAFT_PROFILE=${profileSlug} active; ignoring ${shadowed.join(", ")} from env.
|
|
45390
45400
|
`
|
|
45391
45401
|
);
|
|
45392
45402
|
}
|
|
@@ -45464,17 +45474,17 @@ function bootstrapSuggestedNextAction(code) {
|
|
|
45464
45474
|
case "MISSING_AGENT_ID":
|
|
45465
45475
|
case "MISSING_SERVER_URL":
|
|
45466
45476
|
case "MISSING_TOKEN":
|
|
45467
|
-
return "Use a
|
|
45477
|
+
return "Use a Raft profile with `raft --profile <slug> ...`; create one with `raft agent login --server <server-url> --agent <agent-id> --profile-slug <slug>`.";
|
|
45468
45478
|
case "PROFILE_FILE_UNREADABLE":
|
|
45469
45479
|
case "PROFILE_FILE_INVALID":
|
|
45470
|
-
return "Check the selected
|
|
45480
|
+
return "Check the selected Raft profile, or recreate it with `raft agent login --server <server-url> --agent <agent-id> --profile-slug <slug>`.";
|
|
45471
45481
|
case "TOKEN_FILE_UNREADABLE":
|
|
45472
45482
|
case "TOKEN_FILE_EMPTY":
|
|
45473
|
-
return "Check the daemon-injected token file, or restart the
|
|
45483
|
+
return "Check the daemon-injected token file, or restart the Raft daemon so it can inject a fresh credential.";
|
|
45474
45484
|
case "MISSING_AGENT_PROXY_URL":
|
|
45475
45485
|
case "MISSING_AGENT_PROXY_TOKEN":
|
|
45476
45486
|
case "MULTIPLE_AGENT_PROXY_TOKENS":
|
|
45477
|
-
return "Restart the
|
|
45487
|
+
return "Restart the Raft daemon so it can inject a complete local proxy environment, or remove the partial proxy env vars before retrying.";
|
|
45478
45488
|
default:
|
|
45479
45489
|
return void 0;
|
|
45480
45490
|
}
|
|
@@ -45588,7 +45598,7 @@ var DeviceCodeLoginError = class extends Error {
|
|
|
45588
45598
|
}
|
|
45589
45599
|
};
|
|
45590
45600
|
var ACTIONABLE_ERROR_MESSAGES = {
|
|
45591
|
-
device_login_disabled: "Device login is not enabled on this
|
|
45601
|
+
device_login_disabled: "Device login is not enabled on this Raft server. Ask an admin to set SLOCK_DEVICE_LOGIN_ENABLED=true.",
|
|
45592
45602
|
device_code_required: "Internal CLI bug: device_code was missing from the poll request.",
|
|
45593
45603
|
user_code_required: "Internal CLI bug: user_code was missing from the approve request.",
|
|
45594
45604
|
authorization_pending: "Still waiting for you to approve the login on the web page.",
|
|
@@ -45772,9 +45782,9 @@ function describeListResult(reason, serverUrl) {
|
|
|
45772
45782
|
var agentListCommand = defineCommand(
|
|
45773
45783
|
{
|
|
45774
45784
|
name: "list",
|
|
45775
|
-
description: "List
|
|
45785
|
+
description: "List Raft agents the user can mint credentials for (after a device-code login).",
|
|
45776
45786
|
options: [
|
|
45777
|
-
{ flags: "--server <url>", description: "
|
|
45787
|
+
{ flags: "--server <url>", description: "Raft server base URL, e.g. https://app.raft.build" },
|
|
45778
45788
|
{ flags: "--client-name <label>", description: "Human-readable label shown on the web approval page" }
|
|
45779
45789
|
]
|
|
45780
45790
|
},
|
|
@@ -45856,7 +45866,7 @@ var import_undici4 = __toESM(require_undici(), 1);
|
|
|
45856
45866
|
var WAIT_MAX_POLL_MS = 15 * 60 * 1e3;
|
|
45857
45867
|
var SERVER_OPTION = {
|
|
45858
45868
|
flags: "--server <url>",
|
|
45859
|
-
description: "
|
|
45869
|
+
description: "Raft server base URL, e.g. https://app.raft.build"
|
|
45860
45870
|
};
|
|
45861
45871
|
var AGENT_OPTION = {
|
|
45862
45872
|
flags: "--agent <agentId>",
|
|
@@ -45872,7 +45882,7 @@ var PROFILE_SLUG_OPTION = {
|
|
|
45872
45882
|
};
|
|
45873
45883
|
var PROFILE_DIR_OPTION = {
|
|
45874
45884
|
flags: "--profile-dir <path>",
|
|
45875
|
-
description: "Override the profile directory root (default resolution
|
|
45885
|
+
description: "Override the profile directory root (default resolution uses the managed Raft home when present, otherwise the local profile store)"
|
|
45876
45886
|
};
|
|
45877
45887
|
var DEVICE_CODE_OPTION = {
|
|
45878
45888
|
flags: "--device-code <code>",
|
|
@@ -45887,7 +45897,7 @@ function mergeParentLoginOpts(options, command) {
|
|
|
45887
45897
|
var agentLoginCommand = defineCommand(
|
|
45888
45898
|
{
|
|
45889
45899
|
name: "login",
|
|
45890
|
-
description: "Sign this CLI in as a specific
|
|
45900
|
+
description: "Sign this CLI in as a specific Raft agent via the device-code login grant.",
|
|
45891
45901
|
options: [
|
|
45892
45902
|
SERVER_OPTION,
|
|
45893
45903
|
AGENT_OPTION,
|
|
@@ -47098,7 +47108,7 @@ function createRaftChannelWakeAdapter(options = {}) {
|
|
|
47098
47108
|
if (!options.endpointUrl) {
|
|
47099
47109
|
return buildRaftChannelWakeFailedEvent(input, {
|
|
47100
47110
|
failureClass: "no_session",
|
|
47101
|
-
reason: "Claude Code
|
|
47111
|
+
reason: "Claude Code Raft channel plugin endpoint is not configured; start Claude Code with the Raft channel plugin and pass its localhost wake endpoint to the bridge."
|
|
47102
47112
|
});
|
|
47103
47113
|
}
|
|
47104
47114
|
const request = options.fetchImpl ?? fetch;
|
|
@@ -47125,14 +47135,14 @@ function createRaftChannelWakeAdapter(options = {}) {
|
|
|
47125
47135
|
} catch (err) {
|
|
47126
47136
|
return buildRaftChannelWakeFailedEvent(input, {
|
|
47127
47137
|
failureClass: "no_session",
|
|
47128
|
-
reason: err instanceof Error && err.message ? `Claude Code
|
|
47138
|
+
reason: err instanceof Error && err.message ? `Claude Code Raft channel plugin endpoint is unreachable: ${err.message}` : "Claude Code Raft channel plugin endpoint is unreachable"
|
|
47129
47139
|
});
|
|
47130
47140
|
}
|
|
47131
47141
|
const body = await parseWakeResponse(response);
|
|
47132
47142
|
if (!response.ok || body.ok === false) {
|
|
47133
47143
|
return buildRaftChannelWakeFailedEvent(input, {
|
|
47134
47144
|
failureClass: body.failureClass ?? statusFailureClass(response.status),
|
|
47135
|
-
reason: body.reason ?? `Claude Code
|
|
47145
|
+
reason: body.reason ?? `Claude Code Raft channel plugin rejected wake attempt with HTTP ${response.status}`,
|
|
47136
47146
|
...typeof body.retryAfterMs === "number" ? { retryAfterMs: body.retryAfterMs } : {}
|
|
47137
47147
|
});
|
|
47138
47148
|
}
|
|
@@ -47140,7 +47150,7 @@ function createRaftChannelWakeAdapter(options = {}) {
|
|
|
47140
47150
|
if (!runtimeSession) {
|
|
47141
47151
|
return buildRaftChannelWakeFailedEvent(input, {
|
|
47142
47152
|
failureClass: "protocol_mismatch",
|
|
47143
|
-
reason: "Claude Code
|
|
47153
|
+
reason: "Claude Code Raft channel plugin accepted wake but did not return runtimeSession"
|
|
47144
47154
|
});
|
|
47145
47155
|
}
|
|
47146
47156
|
return buildRaftChannelWakeInjectedEvent({
|
|
@@ -47648,7 +47658,7 @@ function sleep(ms) {
|
|
|
47648
47658
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
47649
47659
|
}
|
|
47650
47660
|
init_esm_shims();
|
|
47651
|
-
var ACTION_HEREDOC_DELIMITER = "
|
|
47661
|
+
var ACTION_HEREDOC_DELIMITER = "RAFTACTION";
|
|
47652
47662
|
var PrepareActionInputError = class extends Error {
|
|
47653
47663
|
constructor(code, message) {
|
|
47654
47664
|
super(message);
|
|
@@ -47667,8 +47677,8 @@ async function readStream(stream) {
|
|
|
47667
47677
|
function missingActionMessage() {
|
|
47668
47678
|
return [
|
|
47669
47679
|
"No action JSON received on stdin.",
|
|
47670
|
-
"Pipe a JSON ActionCardAction object (channel:create / agent:create / channel:add_member) into
|
|
47671
|
-
`
|
|
47680
|
+
"Pipe a JSON ActionCardAction object (channel:create / agent:create / channel:add_member) into raft action prepare:",
|
|
47681
|
+
` raft action prepare --target "#channel" <<'${ACTION_HEREDOC_DELIMITER}'`,
|
|
47672
47682
|
' {"type":"channel:create","name":"demo","visibility":"public"}',
|
|
47673
47683
|
` ${ACTION_HEREDOC_DELIMITER}`
|
|
47674
47684
|
].join("\n");
|
|
@@ -47823,7 +47833,7 @@ function formatServerInfo(data) {
|
|
|
47823
47833
|
text += " (none)\n";
|
|
47824
47834
|
}
|
|
47825
47835
|
text += "\n### Humans\n";
|
|
47826
|
-
text += `To start a new DM: raft message send --target "dm:@name" <<'
|
|
47836
|
+
text += `To start a new DM: raft message send --target "dm:@name" <<'RAFTMSG' followed by the message body and RAFTMSG. To reply in an existing DM: reuse the target from received messages.
|
|
47827
47837
|
`;
|
|
47828
47838
|
text += "Role labels show server-level owner/admin authority; no role label means ordinary member.\n";
|
|
47829
47839
|
if (humans.length > 0) {
|
|
@@ -48388,10 +48398,24 @@ function makeChannelMuteCommand(action) {
|
|
|
48388
48398
|
{
|
|
48389
48399
|
name: action,
|
|
48390
48400
|
description: action === "mute" ? "Mute ordinary Activity delivery for a regular channel" : "Unmute ordinary Activity delivery for a regular channel",
|
|
48391
|
-
arguments: ["
|
|
48401
|
+
arguments: ["[target]"],
|
|
48402
|
+
options: [
|
|
48403
|
+
{
|
|
48404
|
+
flags: "--target <target>",
|
|
48405
|
+
description: `Regular channel to ${action}, e.g. '#engineering'`
|
|
48406
|
+
}
|
|
48407
|
+
]
|
|
48392
48408
|
},
|
|
48393
|
-
async (ctx, targetArg) => {
|
|
48394
|
-
const
|
|
48409
|
+
async (ctx, targetArg, opts = {}) => {
|
|
48410
|
+
const positionalTarget = targetArg?.trim();
|
|
48411
|
+
const flagTarget = opts.target?.trim();
|
|
48412
|
+
if (positionalTarget && flagTarget && positionalTarget !== flagTarget) {
|
|
48413
|
+
throw new CliError({
|
|
48414
|
+
code: "INVALID_ARG",
|
|
48415
|
+
message: "Positional target and --target must refer to the same channel when both are provided"
|
|
48416
|
+
});
|
|
48417
|
+
}
|
|
48418
|
+
const target = flagTarget || positionalTarget || "";
|
|
48395
48419
|
const channelName = parseRegularChannelTarget(target);
|
|
48396
48420
|
if (!channelName) {
|
|
48397
48421
|
throw new CliError({
|
|
@@ -48813,7 +48837,7 @@ function toKnowledgeErrorCode(errorCode2, status) {
|
|
|
48813
48837
|
var knowledgeGetCommand = defineCommand(
|
|
48814
48838
|
{
|
|
48815
48839
|
name: "get",
|
|
48816
|
-
description: "Fetch a
|
|
48840
|
+
description: "Fetch a Raft Manual for Agents topic from the current server",
|
|
48817
48841
|
arguments: ["<topic>"],
|
|
48818
48842
|
options: [
|
|
48819
48843
|
{
|
|
@@ -48872,7 +48896,7 @@ var inboxCheckCommand = defineCommand(
|
|
|
48872
48896
|
if (agentContext.clientMode !== "managed-runner") {
|
|
48873
48897
|
throw new CliError({
|
|
48874
48898
|
code: "INBOX_CHECK_FAILED",
|
|
48875
|
-
message: "`
|
|
48899
|
+
message: "`raft inbox check` is only available inside managed daemon runners.",
|
|
48876
48900
|
suggestedNextAction: "Use `raft message check` to drain messages."
|
|
48877
48901
|
});
|
|
48878
48902
|
}
|
|
@@ -49103,7 +49127,7 @@ function formatHistory(channel, data, opts) {
|
|
|
49103
49127
|
let header = `## Message History for ${channel}${opts?.around ? ` around ${opts.around}` : ""} (${data.messages.length} messages)`;
|
|
49104
49128
|
if ((data.last_read_seq ?? 0) > 0 && !opts?.after && !opts?.before && !opts?.around) {
|
|
49105
49129
|
header += `
|
|
49106
|
-
Your last read position: seq ${data.last_read_seq}. Use raft message read --
|
|
49130
|
+
Your last read position: seq ${data.last_read_seq}. Use raft message read --target "${channel}" --after ${data.last_read_seq} to see only unread messages.`;
|
|
49107
49131
|
}
|
|
49108
49132
|
return `${header}
|
|
49109
49133
|
|
|
@@ -49287,7 +49311,7 @@ function normalizeAction(action) {
|
|
|
49287
49311
|
}
|
|
49288
49312
|
function formatActionCommands(action) {
|
|
49289
49313
|
const verbs = action.availableActions.map(normalizeAction).filter((verb) => verb !== null);
|
|
49290
|
-
return Array.from(new Set(verbs)).map((verb) => ` ${verb}:
|
|
49314
|
+
return Array.from(new Set(verbs)).map((verb) => ` ${verb}: raft mention ${verb} ${action.resolutionId}`);
|
|
49291
49315
|
}
|
|
49292
49316
|
function normalizePendingMentionActions(data) {
|
|
49293
49317
|
const value = data;
|
|
@@ -49417,7 +49441,7 @@ function clearSavedDraft(agentId, target) {
|
|
|
49417
49441
|
delete state.targets[target];
|
|
49418
49442
|
writeState(agentId, state);
|
|
49419
49443
|
}
|
|
49420
|
-
var MESSAGE_HEREDOC_DELIMITER = "
|
|
49444
|
+
var MESSAGE_HEREDOC_DELIMITER = "RAFTMSG";
|
|
49421
49445
|
var SendContentError = class extends Error {
|
|
49422
49446
|
constructor(code, message) {
|
|
49423
49447
|
super(message);
|
|
@@ -49746,6 +49770,28 @@ function registerCheckCommand(parent, runtimeOptions) {
|
|
|
49746
49770
|
registerCliCommand(parent, messageCheckCommand, runtimeOptions);
|
|
49747
49771
|
}
|
|
49748
49772
|
init_esm_shims();
|
|
49773
|
+
init_esm_shims();
|
|
49774
|
+
function resolveTargetAlias(opts) {
|
|
49775
|
+
const target = opts.target?.trim();
|
|
49776
|
+
const legacyChannel = opts.channel?.trim();
|
|
49777
|
+
if (target && legacyChannel && target !== legacyChannel) {
|
|
49778
|
+
throw new CliError({
|
|
49779
|
+
code: "INVALID_ARG",
|
|
49780
|
+
message: "--target and legacy --channel must refer to the same target when both are provided"
|
|
49781
|
+
});
|
|
49782
|
+
}
|
|
49783
|
+
return target || legacyChannel || void 0;
|
|
49784
|
+
}
|
|
49785
|
+
function requireTargetAlias(opts) {
|
|
49786
|
+
const target = resolveTargetAlias(opts);
|
|
49787
|
+
if (!target) {
|
|
49788
|
+
throw new CliError({
|
|
49789
|
+
code: "INVALID_ARG",
|
|
49790
|
+
message: "--target is required (legacy --channel is accepted during the transition)"
|
|
49791
|
+
});
|
|
49792
|
+
}
|
|
49793
|
+
return target;
|
|
49794
|
+
}
|
|
49749
49795
|
function parsePositiveInt2(name, raw) {
|
|
49750
49796
|
if (raw === void 0) return void 0;
|
|
49751
49797
|
const n = Number(raw);
|
|
@@ -49784,13 +49830,7 @@ function mapReadFailure(res) {
|
|
|
49784
49830
|
});
|
|
49785
49831
|
}
|
|
49786
49832
|
function validateReadOpts(opts) {
|
|
49787
|
-
const channel = opts
|
|
49788
|
-
if (!channel) {
|
|
49789
|
-
throw new CliError({
|
|
49790
|
-
code: "INVALID_ARG",
|
|
49791
|
-
message: "--channel is required"
|
|
49792
|
-
});
|
|
49793
|
-
}
|
|
49833
|
+
const channel = requireTargetAlias(opts);
|
|
49794
49834
|
const limit = parsePositiveInt2("limit", opts.limit);
|
|
49795
49835
|
const before = opts.before?.trim();
|
|
49796
49836
|
const after = opts.after?.trim();
|
|
@@ -49807,10 +49847,11 @@ var messageReadCommand = defineCommand(
|
|
|
49807
49847
|
name: "read",
|
|
49808
49848
|
description: "Read message history for a channel, DM, or thread",
|
|
49809
49849
|
options: [
|
|
49810
|
-
{ flags: "--
|
|
49811
|
-
{ flags: "--
|
|
49812
|
-
{ flags: "--
|
|
49813
|
-
{ flags: "--
|
|
49850
|
+
{ flags: "--target <target>", description: "Target: '#channel', 'dm:@peer', '#channel:threadId', 'dm:@peer:threadId'" },
|
|
49851
|
+
{ flags: "--channel <target>", description: "Legacy alias for --target (accepted during transition)" },
|
|
49852
|
+
{ flags: "--before <idOrSeq>", description: "Return messages strictly before this full/short message id or seq anchor" },
|
|
49853
|
+
{ flags: "--after <idOrSeq>", description: "Return messages strictly after this full/short message id or seq anchor" },
|
|
49854
|
+
{ flags: "--around <idOrSeq>", description: "Center the window on this full/short message id or seq anchor" },
|
|
49814
49855
|
{ flags: "--limit <n>", description: "Max messages to return (server default applies if omitted)" }
|
|
49815
49856
|
]
|
|
49816
49857
|
},
|
|
@@ -49910,13 +49951,13 @@ function normalizeSearchOpts(opts) {
|
|
|
49910
49951
|
message: `--sort must be "relevance" or "recent"; got ${opts.sort}`
|
|
49911
49952
|
});
|
|
49912
49953
|
}
|
|
49913
|
-
const channel = opts
|
|
49954
|
+
const channel = resolveTargetAlias(opts);
|
|
49914
49955
|
const sender = opts.sender ? normalizeMemberHandleRef(opts.sender) : void 0;
|
|
49915
49956
|
const hasFilter = Boolean(channel || sender || opts.before || opts.after);
|
|
49916
49957
|
if (!query && !hasFilter) {
|
|
49917
49958
|
throw new CliError({
|
|
49918
49959
|
code: "INVALID_ARG",
|
|
49919
|
-
message: "--query is required unless --sender, --
|
|
49960
|
+
message: "--query is required unless --sender, --target, --before, or --after is provided"
|
|
49920
49961
|
});
|
|
49921
49962
|
}
|
|
49922
49963
|
if (!query && opts.sort === "relevance") {
|
|
@@ -49955,7 +49996,8 @@ var messageSearchCommand = defineCommand(
|
|
|
49955
49996
|
description: "Search messages across channels the agent can see",
|
|
49956
49997
|
options: [
|
|
49957
49998
|
{ flags: "--query <q>", description: "Search query string (optional when filters are provided)" },
|
|
49958
|
-
{ flags: "--
|
|
49999
|
+
{ flags: "--target <target>", description: "Restrict to a single channel/DM/thread" },
|
|
50000
|
+
{ flags: "--channel <target>", description: "Legacy alias for --target (accepted during transition)" },
|
|
49959
50001
|
{ flags: "--sender <handle>", description: "Restrict to messages by sender handle, e.g. @alice" },
|
|
49960
50002
|
{ flags: "--sort <mode>", description: "Sort results by relevance or recent (default: relevance; filter-only searches use recent)" },
|
|
49961
50003
|
{ flags: "--before <iso>", description: "Only messages before this ISO datetime" },
|
|
@@ -50196,9 +50238,10 @@ var attachmentUploadCommand = defineCommand(
|
|
|
50196
50238
|
options: [
|
|
50197
50239
|
{ flags: "--path <filepath>", description: "Absolute path to the local file to upload" },
|
|
50198
50240
|
{
|
|
50199
|
-
flags: "--
|
|
50241
|
+
flags: "--target <target>",
|
|
50200
50242
|
description: "Target where the attachment will be used: '#channel', 'dm:@peer', or thread variants. Required by the v0 server until channel-less uploads land."
|
|
50201
50243
|
},
|
|
50244
|
+
{ flags: "--channel <target>", description: "Legacy alias for --target (accepted during transition)" },
|
|
50202
50245
|
{ flags: "--mime-type <type>", description: "Explicit MIME type override, e.g. image/png" }
|
|
50203
50246
|
]
|
|
50204
50247
|
},
|
|
@@ -50219,10 +50262,11 @@ var attachmentUploadCommand = defineCommand(
|
|
|
50219
50262
|
if (err instanceof AttachmentUploadArgError) throw cliError(err.code, err.message, { cause: err });
|
|
50220
50263
|
throw err;
|
|
50221
50264
|
}
|
|
50222
|
-
|
|
50265
|
+
const target = resolveTargetAlias(opts);
|
|
50266
|
+
if (!target) {
|
|
50223
50267
|
throw cliError(
|
|
50224
50268
|
"MISSING_CHANNEL",
|
|
50225
|
-
"v0 server requires a
|
|
50269
|
+
"v0 server requires a target to attach the upload to. Pass --target '#name', 'dm:@peer', or a thread target."
|
|
50226
50270
|
);
|
|
50227
50271
|
}
|
|
50228
50272
|
const buffer = readFileSync3(opts.path);
|
|
@@ -50238,10 +50282,10 @@ var attachmentUploadCommand = defineCommand(
|
|
|
50238
50282
|
const agentContext = ctx.loadAgentContext();
|
|
50239
50283
|
const client = ctx.createApiClient(agentContext);
|
|
50240
50284
|
const agentApi = createAgentApiSurfaceClient(client);
|
|
50241
|
-
const resolved = await agentApi.channels.resolve({ target
|
|
50285
|
+
const resolved = await agentApi.channels.resolve({ target });
|
|
50242
50286
|
if (!resolved.ok || !resolved.data?.channelId) {
|
|
50243
50287
|
const code = resolved.status >= 500 ? "SERVER_5XX" : "RESOLVE_FAILED";
|
|
50244
|
-
throw cliError(code, resolved.error ?? `Could not resolve
|
|
50288
|
+
throw cliError(code, resolved.error ?? `Could not resolve target: ${target}`);
|
|
50245
50289
|
}
|
|
50246
50290
|
const channelId = resolved.data.channelId;
|
|
50247
50291
|
const blob = new Blob([buffer], { type: uploadMimeType });
|
|
@@ -50270,13 +50314,21 @@ function registerAttachmentUploadCommand(parent, runtimeOptions = {}) {
|
|
|
50270
50314
|
registerCliCommand(parent, attachmentUploadCommand, runtimeOptions);
|
|
50271
50315
|
}
|
|
50272
50316
|
init_esm_shims();
|
|
50273
|
-
function validateViewOpts(opts) {
|
|
50274
|
-
const
|
|
50317
|
+
function validateViewOpts(positionalId, opts) {
|
|
50318
|
+
const positional = positionalId?.trim();
|
|
50319
|
+
const optionId = opts.id?.trim();
|
|
50320
|
+
if (positional && optionId) {
|
|
50321
|
+
throw new CliError({
|
|
50322
|
+
code: "INVALID_ARG",
|
|
50323
|
+
message: "pass the attachment id either positionally or with --id, not both"
|
|
50324
|
+
});
|
|
50325
|
+
}
|
|
50326
|
+
const id = positional || optionId;
|
|
50275
50327
|
const output = opts.output;
|
|
50276
50328
|
if (!id) {
|
|
50277
50329
|
throw new CliError({
|
|
50278
50330
|
code: "INVALID_ARG",
|
|
50279
|
-
message: "
|
|
50331
|
+
message: "attachment id is required (pass <attachmentId> or --id)"
|
|
50280
50332
|
});
|
|
50281
50333
|
}
|
|
50282
50334
|
if (!output) {
|
|
@@ -50291,13 +50343,16 @@ var attachmentViewCommand = defineCommand(
|
|
|
50291
50343
|
{
|
|
50292
50344
|
name: "view",
|
|
50293
50345
|
description: "Download an attachment by id and save it to a local path",
|
|
50346
|
+
arguments: ["[attachmentId]"],
|
|
50294
50347
|
options: [
|
|
50295
|
-
{ flags: "--id <attachmentId>", description: "Attachment UUID" },
|
|
50348
|
+
{ flags: "--id <attachmentId>", description: "Attachment UUID (transition alias; prefer positional <attachmentId>)" },
|
|
50296
50349
|
{ flags: "--output <path>", description: "Local path to write the file to" }
|
|
50297
50350
|
]
|
|
50298
50351
|
},
|
|
50299
|
-
async (ctx,
|
|
50300
|
-
const
|
|
50352
|
+
async (ctx, attachmentIdOrOpts, maybeOpts) => {
|
|
50353
|
+
const positionalId = typeof attachmentIdOrOpts === "string" ? attachmentIdOrOpts : void 0;
|
|
50354
|
+
const opts = typeof attachmentIdOrOpts === "object" && attachmentIdOrOpts !== null ? attachmentIdOrOpts : maybeOpts ?? {};
|
|
50355
|
+
const { id, output } = validateViewOpts(positionalId, opts);
|
|
50301
50356
|
const agentContext = ctx.loadAgentContext();
|
|
50302
50357
|
const client = ctx.createApiClient(agentContext);
|
|
50303
50358
|
const res = await createAgentApiSurfaceClient(client).attachments.view({ attachmentId: id });
|
|
@@ -50447,13 +50502,7 @@ function formatTaskStatusUpdated(taskNumber, status) {
|
|
|
50447
50502
|
}
|
|
50448
50503
|
var VALID_STATUSES = ["all", "todo", "in_progress", "in_review", "done", "closed"];
|
|
50449
50504
|
function validateListOpts(opts) {
|
|
50450
|
-
const channel = opts
|
|
50451
|
-
if (!channel) {
|
|
50452
|
-
throw new CliError({
|
|
50453
|
-
code: "INVALID_ARG",
|
|
50454
|
-
message: "--channel is required"
|
|
50455
|
-
});
|
|
50456
|
-
}
|
|
50505
|
+
const channel = requireTargetAlias(opts);
|
|
50457
50506
|
if (opts.status && !VALID_STATUSES.includes(opts.status)) {
|
|
50458
50507
|
throw new CliError({
|
|
50459
50508
|
code: "INVALID_ARG",
|
|
@@ -50470,7 +50519,8 @@ var taskListCommand = defineCommand(
|
|
|
50470
50519
|
name: "list",
|
|
50471
50520
|
description: "List tasks in a channel",
|
|
50472
50521
|
options: [
|
|
50473
|
-
{ flags: "--
|
|
50522
|
+
{ flags: "--target <target>", description: "Channel target: '#channel'" },
|
|
50523
|
+
{ flags: "--channel <target>", description: "Legacy alias for --target (accepted during transition)" },
|
|
50474
50524
|
{ flags: "--status <s>", description: "Filter: all|todo|in_progress|in_review|done (default: server-side)" }
|
|
50475
50525
|
]
|
|
50476
50526
|
},
|
|
@@ -50509,7 +50559,8 @@ var taskCreateCommand = defineCommand(
|
|
|
50509
50559
|
name: "create",
|
|
50510
50560
|
description: "Create one or more tasks in a channel",
|
|
50511
50561
|
options: [
|
|
50512
|
-
{ flags: "--
|
|
50562
|
+
{ flags: "--target <target>", description: "Channel target: '#channel'" },
|
|
50563
|
+
{ flags: "--channel <target>", description: "Legacy alias for --target (accepted during transition)" },
|
|
50513
50564
|
{
|
|
50514
50565
|
flags: "--title <title>",
|
|
50515
50566
|
description: "Task title (repeatable for batch create)",
|
|
@@ -50518,10 +50569,7 @@ var taskCreateCommand = defineCommand(
|
|
|
50518
50569
|
]
|
|
50519
50570
|
},
|
|
50520
50571
|
async (ctx, opts) => {
|
|
50521
|
-
const channel = opts
|
|
50522
|
-
if (!channel) {
|
|
50523
|
-
throw cliError("INVALID_ARG", "--channel is required");
|
|
50524
|
-
}
|
|
50572
|
+
const channel = requireTargetAlias(opts);
|
|
50525
50573
|
const titles = opts.title ?? [];
|
|
50526
50574
|
if (titles.length === 0) throw cliError("INVALID_ARG", "--title is required (at least one)");
|
|
50527
50575
|
const body = { channel, tasks: titles.map((title) => ({ title })) };
|
|
@@ -50551,7 +50599,8 @@ var taskClaimCommand = defineCommand(
|
|
|
50551
50599
|
name: "claim",
|
|
50552
50600
|
description: "Claim one or more tasks (by task number or message id)",
|
|
50553
50601
|
options: [
|
|
50554
|
-
{ flags: "--
|
|
50602
|
+
{ flags: "--target <target>", description: "Channel target: '#channel'" },
|
|
50603
|
+
{ flags: "--channel <target>", description: "Legacy alias for --target (accepted during transition)" },
|
|
50555
50604
|
{
|
|
50556
50605
|
flags: "--number <n>",
|
|
50557
50606
|
description: "Task number to claim (repeatable)",
|
|
@@ -50565,9 +50614,7 @@ var taskClaimCommand = defineCommand(
|
|
|
50565
50614
|
]
|
|
50566
50615
|
},
|
|
50567
50616
|
async (ctx, opts) => {
|
|
50568
|
-
|
|
50569
|
-
throw cliError("INVALID_ARG", "--channel is required");
|
|
50570
|
-
}
|
|
50617
|
+
const channel = requireTargetAlias(opts);
|
|
50571
50618
|
const numbers = (opts.number ?? []).map((raw) => {
|
|
50572
50619
|
const n = Number(raw);
|
|
50573
50620
|
if (!Number.isFinite(n) || !Number.isInteger(n) || n <= 0) {
|
|
@@ -50579,7 +50626,7 @@ var taskClaimCommand = defineCommand(
|
|
|
50579
50626
|
if (numbers.length === 0 && messageIds.length === 0) {
|
|
50580
50627
|
throw cliError("INVALID_ARG", "Provide at least one --number or --message-id");
|
|
50581
50628
|
}
|
|
50582
|
-
const body = { channel
|
|
50629
|
+
const body = { channel };
|
|
50583
50630
|
if (numbers.length > 0) body.task_numbers = numbers;
|
|
50584
50631
|
if (messageIds.length > 0) body.message_ids = messageIds;
|
|
50585
50632
|
const agentContext = ctx.loadAgentContext();
|
|
@@ -50594,7 +50641,7 @@ var taskClaimCommand = defineCommand(
|
|
|
50594
50641
|
throw cliError("INVALID_JSON_RESPONSE", "Agent API taskClaim returned an empty response body");
|
|
50595
50642
|
}
|
|
50596
50643
|
if (isFreshnessHeldResponse(res.data)) {
|
|
50597
|
-
writeText(ctx.io, formatFreshnessHoldOutput(
|
|
50644
|
+
writeText(ctx.io, formatFreshnessHoldOutput(channel, res.data, {
|
|
50598
50645
|
heldAction: "Your task claim was not applied.",
|
|
50599
50646
|
draftInstructions: "After reviewing the newer context, rerun the task claim command if it is still correct.\n"
|
|
50600
50647
|
}));
|
|
@@ -50603,7 +50650,7 @@ var taskClaimCommand = defineCommand(
|
|
|
50603
50650
|
if (!isTaskClaimSuccessResponse(res.data)) {
|
|
50604
50651
|
throw cliError("INVALID_JSON_RESPONSE", "Agent API taskClaim returned an unexpected response body");
|
|
50605
50652
|
}
|
|
50606
|
-
writeText(ctx.io, formatClaimResults(
|
|
50653
|
+
writeText(ctx.io, formatClaimResults(channel, res.data) + "\n");
|
|
50607
50654
|
}
|
|
50608
50655
|
);
|
|
50609
50656
|
function registerTaskClaimCommand(parent, runtimeOptions = {}) {
|
|
@@ -50621,13 +50668,7 @@ function parseTaskNumber(raw) {
|
|
|
50621
50668
|
return n;
|
|
50622
50669
|
}
|
|
50623
50670
|
function validateUnclaimOpts(opts) {
|
|
50624
|
-
const channel = opts
|
|
50625
|
-
if (!channel) {
|
|
50626
|
-
throw new CliError({
|
|
50627
|
-
code: "INVALID_ARG",
|
|
50628
|
-
message: "--channel is required"
|
|
50629
|
-
});
|
|
50630
|
-
}
|
|
50671
|
+
const channel = requireTargetAlias(opts);
|
|
50631
50672
|
return { channel, taskNumber: parseTaskNumber(opts.number) };
|
|
50632
50673
|
}
|
|
50633
50674
|
var taskUnclaimCommand = defineCommand(
|
|
@@ -50635,7 +50676,8 @@ var taskUnclaimCommand = defineCommand(
|
|
|
50635
50676
|
name: "unclaim",
|
|
50636
50677
|
description: "Release a previously-claimed task",
|
|
50637
50678
|
options: [
|
|
50638
|
-
{ flags: "--
|
|
50679
|
+
{ flags: "--target <target>", description: "Channel target: '#channel'" },
|
|
50680
|
+
{ flags: "--channel <target>", description: "Legacy alias for --target (accepted during transition)" },
|
|
50639
50681
|
{ flags: "--number <n>", description: "Task number to unclaim" }
|
|
50640
50682
|
]
|
|
50641
50683
|
},
|
|
@@ -50687,13 +50729,7 @@ function parseStatus(raw) {
|
|
|
50687
50729
|
return raw;
|
|
50688
50730
|
}
|
|
50689
50731
|
function validateUpdateOpts(opts) {
|
|
50690
|
-
const channel = opts
|
|
50691
|
-
if (!channel) {
|
|
50692
|
-
throw new CliError({
|
|
50693
|
-
code: "INVALID_ARG",
|
|
50694
|
-
message: "--channel is required"
|
|
50695
|
-
});
|
|
50696
|
-
}
|
|
50732
|
+
const channel = requireTargetAlias(opts);
|
|
50697
50733
|
return {
|
|
50698
50734
|
channel,
|
|
50699
50735
|
taskNumber: parseTaskNumber2(opts.number),
|
|
@@ -50705,7 +50741,8 @@ var taskUpdateCommand = defineCommand(
|
|
|
50705
50741
|
name: "update",
|
|
50706
50742
|
description: "Update task status",
|
|
50707
50743
|
options: [
|
|
50708
|
-
{ flags: "--
|
|
50744
|
+
{ flags: "--target <target>", description: "Channel target: '#channel'" },
|
|
50745
|
+
{ flags: "--channel <target>", description: "Legacy alias for --target (accepted during transition)" },
|
|
50709
50746
|
{ flags: "--number <n>", description: "Task number to update" },
|
|
50710
50747
|
{ flags: "--status <status>", description: `New status. One of: ${STATUSES.join(", ")}` }
|
|
50711
50748
|
]
|
|
@@ -50881,13 +50918,13 @@ function pushServiceBlock(lines, service, active) {
|
|
|
50881
50918
|
lines.push(`- ${service.name}`);
|
|
50882
50919
|
lines.push(` service: ${service.clientId}`);
|
|
50883
50920
|
lines.push(` id: ${service.id}`);
|
|
50884
|
-
if (service.appType === "slock_builtin") lines.push(" type: built-in
|
|
50921
|
+
if (service.appType === "slock_builtin") lines.push(" type: built-in Raft app");
|
|
50885
50922
|
lines.push(` status: ${active ? "active login" : "not logged in"}`);
|
|
50886
50923
|
lines.push(` return URL: ${formatMaybe(service.returnUrl)}`);
|
|
50887
50924
|
if (service.agentManifestUrl) {
|
|
50888
50925
|
lines.push(` agent behavior manifest: ${service.agentManifestUrl}`);
|
|
50889
50926
|
lines.push(` local CLI env: raft integration env --service ${JSON.stringify(service.clientId)}`);
|
|
50890
|
-
lines.push(`
|
|
50927
|
+
lines.push(` for login_with_raft HTTP API action manifests: raft integration invoke --service ${JSON.stringify(service.clientId)} --list-actions`);
|
|
50891
50928
|
}
|
|
50892
50929
|
if (service.homepageUrl) lines.push(` homepage: ${service.homepageUrl}`);
|
|
50893
50930
|
if (service.description) lines.push(` description: ${service.description}`);
|
|
@@ -50899,7 +50936,7 @@ function formatIntegrationList(data) {
|
|
|
50899
50936
|
const registeredServices = data.services.filter((service) => service.appType !== "slock_builtin");
|
|
50900
50937
|
const lines = [];
|
|
50901
50938
|
if (builtInServices.length > 0) {
|
|
50902
|
-
lines.push("Built-in
|
|
50939
|
+
lines.push("Built-in Raft apps:");
|
|
50903
50940
|
for (const service of builtInServices) {
|
|
50904
50941
|
pushServiceBlock(lines, service, activeByServiceId.get(service.id));
|
|
50905
50942
|
}
|
|
@@ -50927,7 +50964,7 @@ function formatIntegrationList(data) {
|
|
|
50927
50964
|
if (login.agentManifestUrl) {
|
|
50928
50965
|
lines.push(` agent behavior manifest: ${login.agentManifestUrl}`);
|
|
50929
50966
|
lines.push(` local CLI env: raft integration env --service ${JSON.stringify(login.clientId)}`);
|
|
50930
|
-
lines.push(`
|
|
50967
|
+
lines.push(` for login_with_raft HTTP API action manifests: raft integration invoke --service ${JSON.stringify(login.clientId)} --list-actions`);
|
|
50931
50968
|
}
|
|
50932
50969
|
lines.push(` created: ${login.createdAt}`);
|
|
50933
50970
|
}
|
|
@@ -50964,16 +51001,16 @@ function formatIntegrationLogin(data) {
|
|
|
50964
51001
|
if (data.service.agentManifestUrl) {
|
|
50965
51002
|
lines.push(`agent behavior manifest: ${data.service.agentManifestUrl}`);
|
|
50966
51003
|
lines.push(`local CLI env: raft integration env --service ${JSON.stringify(data.service.clientId)}`);
|
|
50967
|
-
lines.push(`
|
|
50968
|
-
}
|
|
50969
|
-
lines.push("complete: this agent login is configured in
|
|
50970
|
-
lines.push("identity: run `raft profile show` if the service or human asks for your
|
|
50971
|
-
|
|
50972
|
-
|
|
50973
|
-
lines.push(`
|
|
50974
|
-
lines.push(
|
|
50975
|
-
lines.push(`next: prefer \`raft integration invoke --service ${JSON.stringify(data.service.clientId)} --list-actions\` when the service manifest exposes actions`);
|
|
51004
|
+
lines.push(`for login_with_raft HTTP API action manifests: raft integration invoke --service ${JSON.stringify(data.service.clientId)} --list-actions`);
|
|
51005
|
+
}
|
|
51006
|
+
lines.push("complete: this agent login is configured in Raft; no human OAuth is required");
|
|
51007
|
+
lines.push("identity: run `raft profile show` if the service or human asks for your Raft Agent identity card");
|
|
51008
|
+
if (data.session) {
|
|
51009
|
+
lines.push(`session: service session ${data.session.source === "fresh" ? "created" : "reused"} and stored for this agent`);
|
|
51010
|
+
if (data.session.path) lines.push(`session store: ${data.session.path}`);
|
|
51011
|
+
lines.push(`next: use \`raft integration invoke --service ${JSON.stringify(data.service.clientId)} --list-actions\` only for login_with_raft HTTP API action manifests; for session-cookie services, use the established service session per service docs`);
|
|
50976
51012
|
} else {
|
|
51013
|
+
lines.push("session: no service callback session was established; Raft grant is active");
|
|
50977
51014
|
lines.push("next: use the service, or run `raft integration list` to confirm active login");
|
|
50978
51015
|
}
|
|
50979
51016
|
return lines.join("\n");
|
|
@@ -50981,7 +51018,7 @@ function formatIntegrationLogin(data) {
|
|
|
50981
51018
|
var integrationListCommand = defineCommand(
|
|
50982
51019
|
{
|
|
50983
51020
|
name: "list",
|
|
50984
|
-
description: "List built-in
|
|
51021
|
+
description: "List built-in Raft apps, registered services, and this agent's active logins",
|
|
50985
51022
|
options: [{ flags: "--json", description: "Emit machine-readable JSON" }]
|
|
50986
51023
|
},
|
|
50987
51024
|
async (ctx, opts) => {
|
|
@@ -51004,6 +51041,195 @@ function registerIntegrationListCommand(parent, runtimeOptions = {}) {
|
|
|
51004
51041
|
registerCliCommand(parent, integrationListCommand, runtimeOptions);
|
|
51005
51042
|
}
|
|
51006
51043
|
init_esm_shims();
|
|
51044
|
+
init_esm_shims();
|
|
51045
|
+
function safeUrl(value, label) {
|
|
51046
|
+
let url2;
|
|
51047
|
+
try {
|
|
51048
|
+
url2 = new URL(value);
|
|
51049
|
+
} catch {
|
|
51050
|
+
throw cliError("INVALID_ARG", `${label} must be a valid URL`);
|
|
51051
|
+
}
|
|
51052
|
+
if (url2.protocol !== "https:" && url2.protocol !== "http:") {
|
|
51053
|
+
throw cliError("INVALID_ARG", `${label} must use http or https`);
|
|
51054
|
+
}
|
|
51055
|
+
if (url2.username || url2.password) {
|
|
51056
|
+
throw cliError("INVALID_ARG", `${label} must not include credentials`);
|
|
51057
|
+
}
|
|
51058
|
+
return url2;
|
|
51059
|
+
}
|
|
51060
|
+
function resolveStateRoot(env) {
|
|
51061
|
+
const configured = env.RAFT_HOME?.trim() || env.SLOCK_HOME?.trim();
|
|
51062
|
+
if (configured) return configured;
|
|
51063
|
+
const home = env.HOME ?? os4.homedir();
|
|
51064
|
+
return path8.join(home, ".slock");
|
|
51065
|
+
}
|
|
51066
|
+
function integrationSessionFilePath(input) {
|
|
51067
|
+
const root = input.agentContext.profileCredentialPath ? path8.dirname(input.agentContext.profileCredentialPath) : path8.join(resolveStateRoot(input.env), "integration-sessions", input.agentContext.agentId);
|
|
51068
|
+
const safeClientId = encodeURIComponent(input.service.clientId).replace(/%/g, "_");
|
|
51069
|
+
return path8.join(root, "integrations", `${safeClientId}.json`);
|
|
51070
|
+
}
|
|
51071
|
+
function setCookieHeaderValues(headers) {
|
|
51072
|
+
const getSetCookie = headers.getSetCookie;
|
|
51073
|
+
return typeof getSetCookie === "function" ? getSetCookie.call(headers) : [headers.get("set-cookie")].filter((value) => Boolean(value));
|
|
51074
|
+
}
|
|
51075
|
+
function defaultCookiePath(pathname) {
|
|
51076
|
+
if (!pathname.startsWith("/") || pathname === "/") return "/";
|
|
51077
|
+
const lastSlash = pathname.lastIndexOf("/");
|
|
51078
|
+
if (lastSlash <= 0) return "/";
|
|
51079
|
+
return pathname.slice(0, lastSlash);
|
|
51080
|
+
}
|
|
51081
|
+
function parseCookieExpiry(parts) {
|
|
51082
|
+
const now = Date.now();
|
|
51083
|
+
for (const part of parts) {
|
|
51084
|
+
const separator = part.indexOf("=");
|
|
51085
|
+
const rawName = separator >= 0 ? part.slice(0, separator) : part;
|
|
51086
|
+
const rawValue = separator >= 0 ? part.slice(separator + 1) : "";
|
|
51087
|
+
const name = rawName.trim().toLowerCase();
|
|
51088
|
+
if (name === "max-age") {
|
|
51089
|
+
const seconds = Number(rawValue.trim());
|
|
51090
|
+
if (Number.isFinite(seconds)) return new Date(now + Math.max(0, seconds) * 1e3).toISOString();
|
|
51091
|
+
}
|
|
51092
|
+
if (name === "expires") {
|
|
51093
|
+
const time3 = Date.parse(rawValue.trim());
|
|
51094
|
+
if (Number.isFinite(time3)) return new Date(time3).toISOString();
|
|
51095
|
+
}
|
|
51096
|
+
}
|
|
51097
|
+
return void 0;
|
|
51098
|
+
}
|
|
51099
|
+
function parseSessionCookie(value, sourceUrl) {
|
|
51100
|
+
const parts = value.split(";").map((part) => part.trim()).filter(Boolean);
|
|
51101
|
+
const pair = parts.shift();
|
|
51102
|
+
if (!pair || !pair.includes("=") || pair.startsWith("=")) return null;
|
|
51103
|
+
const sourceHost = sourceUrl.hostname.toLowerCase();
|
|
51104
|
+
let host = sourceHost;
|
|
51105
|
+
let cookiePath = defaultCookiePath(sourceUrl.pathname);
|
|
51106
|
+
let secure = false;
|
|
51107
|
+
for (const part of parts) {
|
|
51108
|
+
const separator = part.indexOf("=");
|
|
51109
|
+
const rawName = separator >= 0 ? part.slice(0, separator) : part;
|
|
51110
|
+
const rawValue = separator >= 0 ? part.slice(separator + 1) : "";
|
|
51111
|
+
const name = rawName.trim().toLowerCase();
|
|
51112
|
+
if (name === "secure") {
|
|
51113
|
+
secure = true;
|
|
51114
|
+
} else if (name === "path" && rawValue.trim().startsWith("/")) {
|
|
51115
|
+
cookiePath = rawValue.trim();
|
|
51116
|
+
} else if (name === "domain") {
|
|
51117
|
+
const domain2 = rawValue.trim().replace(/^\./, "").toLowerCase();
|
|
51118
|
+
if (domain2 !== sourceHost) return null;
|
|
51119
|
+
host = domain2;
|
|
51120
|
+
}
|
|
51121
|
+
}
|
|
51122
|
+
return { pair, host, path: cookiePath, secure, expiresAt: parseCookieExpiry(parts) };
|
|
51123
|
+
}
|
|
51124
|
+
function cookiePathMatches(requestPath, cookiePath) {
|
|
51125
|
+
if (requestPath === cookiePath) return true;
|
|
51126
|
+
if (cookiePath.endsWith("/")) return requestPath.startsWith(cookiePath);
|
|
51127
|
+
return requestPath.startsWith(`${cookiePath}/`);
|
|
51128
|
+
}
|
|
51129
|
+
function cookieHeaderForUrl(cookies, url2) {
|
|
51130
|
+
const host = url2.hostname.toLowerCase();
|
|
51131
|
+
const valid = cookies.filter((cookie) => cookie.host === host).filter((cookie) => !cookie.secure || url2.protocol === "https:").filter((cookie) => cookiePathMatches(url2.pathname || "/", cookie.path)).map((cookie) => cookie.pair);
|
|
51132
|
+
return valid.length > 0 ? valid.join("; ") : null;
|
|
51133
|
+
}
|
|
51134
|
+
function sessionCookiesFromSetCookie(headers, sourceUrl) {
|
|
51135
|
+
return setCookieHeaderValues(headers).map((value) => parseSessionCookie(value, sourceUrl)).filter((value) => Boolean(value));
|
|
51136
|
+
}
|
|
51137
|
+
function isCookieFresh(cookie) {
|
|
51138
|
+
if (!cookie.expiresAt) return true;
|
|
51139
|
+
return Date.parse(cookie.expiresAt) > Date.now() + 3e4;
|
|
51140
|
+
}
|
|
51141
|
+
function freshCookies(cookies) {
|
|
51142
|
+
return cookies.filter(isCookieFresh);
|
|
51143
|
+
}
|
|
51144
|
+
function loadStoredIntegrationSession(input) {
|
|
51145
|
+
const filePath = integrationSessionFilePath(input);
|
|
51146
|
+
if (!filePath) return null;
|
|
51147
|
+
let raw;
|
|
51148
|
+
try {
|
|
51149
|
+
raw = fs5.readFileSync(filePath, "utf8");
|
|
51150
|
+
} catch {
|
|
51151
|
+
return null;
|
|
51152
|
+
}
|
|
51153
|
+
let parsed;
|
|
51154
|
+
try {
|
|
51155
|
+
parsed = JSON.parse(raw);
|
|
51156
|
+
} catch {
|
|
51157
|
+
return null;
|
|
51158
|
+
}
|
|
51159
|
+
if (!parsed || typeof parsed !== "object") return null;
|
|
51160
|
+
const session = parsed;
|
|
51161
|
+
if (session.serviceId !== input.service.id || session.clientId !== input.service.clientId || session.returnUrl !== input.service.returnUrl || !Array.isArray(session.cookies)) {
|
|
51162
|
+
return null;
|
|
51163
|
+
}
|
|
51164
|
+
const cookies = freshCookies(session.cookies);
|
|
51165
|
+
if (cookies.length === 0) return null;
|
|
51166
|
+
return { ...session, cookies };
|
|
51167
|
+
}
|
|
51168
|
+
function storeIntegrationSession(input) {
|
|
51169
|
+
const filePath = integrationSessionFilePath(input);
|
|
51170
|
+
if (!filePath) return null;
|
|
51171
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
51172
|
+
const previous = loadStoredIntegrationSession(input);
|
|
51173
|
+
const body = {
|
|
51174
|
+
serviceId: input.service.id,
|
|
51175
|
+
clientId: input.service.clientId,
|
|
51176
|
+
returnUrl: input.service.returnUrl ?? "",
|
|
51177
|
+
cookies: freshCookies(input.cookies),
|
|
51178
|
+
createdAt: previous?.createdAt ?? now,
|
|
51179
|
+
updatedAt: now
|
|
51180
|
+
};
|
|
51181
|
+
fs5.mkdirSync(path8.dirname(filePath), { recursive: true, mode: 448 });
|
|
51182
|
+
fs5.writeFileSync(filePath, `${JSON.stringify(body, null, 2)}
|
|
51183
|
+
`, { mode: 384 });
|
|
51184
|
+
return filePath;
|
|
51185
|
+
}
|
|
51186
|
+
async function consumeAgentLoginHandoff(input) {
|
|
51187
|
+
if (!input.login.requestId) {
|
|
51188
|
+
throw cliError("INTEGRATION_LOGIN_FAILED", "agent login response did not include an internal one-time handoff request");
|
|
51189
|
+
}
|
|
51190
|
+
const callbackUrl = buildAgentCallbackHandoffUrl(input.service.returnUrl, input.login.requestId);
|
|
51191
|
+
if (!callbackUrl) {
|
|
51192
|
+
throw cliError("INTEGRATION_LOGIN_FAILED", "service return URL cannot be used for Agent Login callback handoff");
|
|
51193
|
+
}
|
|
51194
|
+
const parsedCallbackUrl = safeUrl(callbackUrl, "service callback URL");
|
|
51195
|
+
const response = await fetch(callbackUrl, {
|
|
51196
|
+
method: "GET",
|
|
51197
|
+
redirect: "manual",
|
|
51198
|
+
headers: { accept: "text/html,application/json" }
|
|
51199
|
+
});
|
|
51200
|
+
if (response.status < 200 || response.status >= 400) {
|
|
51201
|
+
if (response.status === 409) {
|
|
51202
|
+
throw cliError(
|
|
51203
|
+
"INTEGRATION_LOGIN_FAILED",
|
|
51204
|
+
"service callback handoff was rejected as expired or already used; rerun `raft integration login` to obtain a fresh handoff"
|
|
51205
|
+
);
|
|
51206
|
+
}
|
|
51207
|
+
throw cliError("INTEGRATION_LOGIN_FAILED", `service callback handoff failed with HTTP ${response.status}`);
|
|
51208
|
+
}
|
|
51209
|
+
const cookies = sessionCookiesFromSetCookie(response.headers, parsedCallbackUrl);
|
|
51210
|
+
if (cookies.length === 0) {
|
|
51211
|
+
throw cliError(
|
|
51212
|
+
"INTEGRATION_LOGIN_FAILED",
|
|
51213
|
+
"service callback handoff did not set a session cookie; the service may not support stateless Agent Login sessions yet"
|
|
51214
|
+
);
|
|
51215
|
+
}
|
|
51216
|
+
return cookies;
|
|
51217
|
+
}
|
|
51218
|
+
async function ensureIntegrationServiceSession(input) {
|
|
51219
|
+
if (!input.refresh) {
|
|
51220
|
+
const stored = loadStoredIntegrationSession(input);
|
|
51221
|
+
if (stored) {
|
|
51222
|
+
return {
|
|
51223
|
+
cookies: stored.cookies,
|
|
51224
|
+
source: "cache",
|
|
51225
|
+
sessionPath: integrationSessionFilePath(input)
|
|
51226
|
+
};
|
|
51227
|
+
}
|
|
51228
|
+
}
|
|
51229
|
+
const cookies = await consumeAgentLoginHandoff(input);
|
|
51230
|
+
const sessionPath = storeIntegrationSession({ ...input, cookies });
|
|
51231
|
+
return { cookies, source: "fresh", sessionPath };
|
|
51232
|
+
}
|
|
51007
51233
|
function normalizeScopes(raw) {
|
|
51008
51234
|
if (!raw || raw.length === 0) return void 0;
|
|
51009
51235
|
const scopes = Array.from(new Set(
|
|
@@ -51014,10 +51240,15 @@ function normalizeScopes(raw) {
|
|
|
51014
51240
|
}
|
|
51015
51241
|
return scopes;
|
|
51016
51242
|
}
|
|
51243
|
+
function redactSuccessfulRequestId(data) {
|
|
51244
|
+
if (data.status === "approval_required") return data;
|
|
51245
|
+
const { requestId: _requestId, ...rest } = data;
|
|
51246
|
+
return rest;
|
|
51247
|
+
}
|
|
51017
51248
|
var integrationLoginCommand = defineCommand(
|
|
51018
51249
|
{
|
|
51019
51250
|
name: "login",
|
|
51020
|
-
description: "Provision or reuse this agent's login for a built-in
|
|
51251
|
+
description: "Provision or reuse this agent's login for a built-in Raft app or registered service",
|
|
51021
51252
|
options: [
|
|
51022
51253
|
{ flags: "--service <id>", description: "Registered service id, client id, or exact service name" },
|
|
51023
51254
|
{
|
|
@@ -51049,11 +51280,30 @@ var integrationLoginCommand = defineCommand(
|
|
|
51049
51280
|
const code = res.status >= 500 ? "SERVER_5XX" : "INTEGRATION_LOGIN_FAILED";
|
|
51050
51281
|
throw cliError(code, res.error ?? `HTTP ${res.status}`);
|
|
51051
51282
|
}
|
|
51283
|
+
let data = res.data;
|
|
51284
|
+
if (data.status !== "approval_required" && data.service.returnUrl) {
|
|
51285
|
+
const session = await ensureIntegrationServiceSession({
|
|
51286
|
+
login: data,
|
|
51287
|
+
service: data.service,
|
|
51288
|
+
agentContext,
|
|
51289
|
+
env: ctx.env,
|
|
51290
|
+
refresh: true
|
|
51291
|
+
});
|
|
51292
|
+
data = {
|
|
51293
|
+
...data,
|
|
51294
|
+
session: {
|
|
51295
|
+
status: "stored",
|
|
51296
|
+
source: session.source,
|
|
51297
|
+
path: session.sessionPath
|
|
51298
|
+
}
|
|
51299
|
+
};
|
|
51300
|
+
}
|
|
51301
|
+
const outputData = redactSuccessfulRequestId(data);
|
|
51052
51302
|
if (opts.json) {
|
|
51053
|
-
writeJson(ctx.io, { ok: true, data:
|
|
51303
|
+
writeJson(ctx.io, { ok: true, data: outputData });
|
|
51054
51304
|
return;
|
|
51055
51305
|
}
|
|
51056
|
-
writeText(ctx.io, `${formatIntegrationLogin(
|
|
51306
|
+
writeText(ctx.io, `${formatIntegrationLogin(outputData)}
|
|
51057
51307
|
`);
|
|
51058
51308
|
}
|
|
51059
51309
|
);
|
|
@@ -51129,22 +51379,22 @@ function requireEndpointPath(value, field) {
|
|
|
51129
51379
|
if (typeof value !== "string" || !value.trim()) {
|
|
51130
51380
|
throw new Error(`${field} must be a non-empty path string`);
|
|
51131
51381
|
}
|
|
51132
|
-
const
|
|
51133
|
-
if (!
|
|
51382
|
+
const path10 = value.trim();
|
|
51383
|
+
if (!path10.startsWith("/")) {
|
|
51134
51384
|
throw new Error(`${field} must start with /`);
|
|
51135
51385
|
}
|
|
51136
|
-
if (
|
|
51386
|
+
if (path10.startsWith("//")) {
|
|
51137
51387
|
throw new Error(`${field} must be a relative service path`);
|
|
51138
51388
|
}
|
|
51139
51389
|
try {
|
|
51140
|
-
const parsed = new URL(
|
|
51390
|
+
const parsed = new URL(path10, "https://manifest.local");
|
|
51141
51391
|
if (parsed.origin !== "https://manifest.local" || parsed.username || parsed.password || parsed.hash) {
|
|
51142
51392
|
throw new Error();
|
|
51143
51393
|
}
|
|
51144
51394
|
} catch {
|
|
51145
51395
|
throw new Error(`${field} must be a relative service path`);
|
|
51146
51396
|
}
|
|
51147
|
-
return
|
|
51397
|
+
return path10;
|
|
51148
51398
|
}
|
|
51149
51399
|
function normalizeActionMethod(value) {
|
|
51150
51400
|
if (typeof value !== "string") {
|
|
@@ -51340,14 +51590,14 @@ function sanitizePathSegment(value) {
|
|
|
51340
51590
|
const segment = value.trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
51341
51591
|
return segment || "service";
|
|
51342
51592
|
}
|
|
51343
|
-
function resolveSlockHome(env, homeDir =
|
|
51593
|
+
function resolveSlockHome(env, homeDir = os5.homedir()) {
|
|
51344
51594
|
const configured = env.SLOCK_HOME?.trim() || env.RAFT_HOME?.trim();
|
|
51345
|
-
const raw = configured && configured.length > 0 ? configured :
|
|
51346
|
-
return
|
|
51595
|
+
const raw = configured && configured.length > 0 ? configured : path9.join(homeDir, ".slock");
|
|
51596
|
+
return path9.resolve(expandHome(raw, homeDir));
|
|
51347
51597
|
}
|
|
51348
51598
|
function expandHome(input, homeDir) {
|
|
51349
51599
|
if (input === "~") return homeDir;
|
|
51350
|
-
if (input.startsWith("~/")) return
|
|
51600
|
+
if (input.startsWith("~/")) return path9.join(homeDir, input.slice(2));
|
|
51351
51601
|
return input;
|
|
51352
51602
|
}
|
|
51353
51603
|
function buildLocalCliProfileEnv(input) {
|
|
@@ -51361,15 +51611,15 @@ function buildLocalCliProfileEnv(input) {
|
|
|
51361
51611
|
throw new Error("manifest must set credential_boundary.forbid_user_home=true for local_cli isolation");
|
|
51362
51612
|
}
|
|
51363
51613
|
const root = resolveSlockHome(input.env ?? process.env, input.homeDir);
|
|
51364
|
-
const profileHome =
|
|
51614
|
+
const profileHome = path9.join(
|
|
51365
51615
|
root,
|
|
51366
51616
|
"integration-profiles",
|
|
51367
51617
|
sanitizePathSegment(input.ctx.serverId ?? "server"),
|
|
51368
51618
|
sanitizePathSegment(input.ctx.agentId),
|
|
51369
51619
|
sanitizePathSegment(input.serviceId)
|
|
51370
51620
|
);
|
|
51371
|
-
|
|
51372
|
-
|
|
51621
|
+
fs6.mkdirSync(profileHome, { recursive: true, mode: 448 });
|
|
51622
|
+
fs6.chmodSync(profileHome, 448);
|
|
51373
51623
|
return {
|
|
51374
51624
|
serviceId: input.serviceId,
|
|
51375
51625
|
command: input.manifest.execution.command,
|
|
@@ -51378,10 +51628,10 @@ function buildLocalCliProfileEnv(input) {
|
|
|
51378
51628
|
SLOCK_INTEGRATION_SERVICE: input.serviceId,
|
|
51379
51629
|
SLOCK_INTEGRATION_PROFILE_HOME: profileHome,
|
|
51380
51630
|
HOME: profileHome,
|
|
51381
|
-
XDG_CONFIG_HOME:
|
|
51382
|
-
XDG_CACHE_HOME:
|
|
51383
|
-
XDG_DATA_HOME:
|
|
51384
|
-
XDG_STATE_HOME:
|
|
51631
|
+
XDG_CONFIG_HOME: path9.join(profileHome, ".config"),
|
|
51632
|
+
XDG_CACHE_HOME: path9.join(profileHome, ".cache"),
|
|
51633
|
+
XDG_DATA_HOME: path9.join(profileHome, ".local", "share"),
|
|
51634
|
+
XDG_STATE_HOME: path9.join(profileHome, ".local", "state")
|
|
51385
51635
|
}
|
|
51386
51636
|
};
|
|
51387
51637
|
}
|
|
@@ -51390,9 +51640,9 @@ function shellQuote(value) {
|
|
|
51390
51640
|
}
|
|
51391
51641
|
function formatShellExports(profile) {
|
|
51392
51642
|
const lines = [
|
|
51393
|
-
`#
|
|
51643
|
+
`# Raft integration profile for ${profile.serviceId}`,
|
|
51394
51644
|
`# command: ${profile.command}`,
|
|
51395
|
-
"# This only exports env;
|
|
51645
|
+
"# This only exports env; Raft does not execute manifest commands.",
|
|
51396
51646
|
"# Apply these exports before invoking the local CLI yourself."
|
|
51397
51647
|
];
|
|
51398
51648
|
for (const [key, value] of Object.entries(profile.env)) {
|
|
@@ -51418,10 +51668,10 @@ function describeNoLocalEnv(manifest) {
|
|
|
51418
51668
|
return "manifest execution mode is http_api; no local CLI env is required";
|
|
51419
51669
|
}
|
|
51420
51670
|
if (!manifest.credential_boundary) {
|
|
51421
|
-
return "manifest does not request a
|
|
51671
|
+
return "manifest does not request a Raft-managed local environment";
|
|
51422
51672
|
}
|
|
51423
51673
|
if (manifest.credential_boundary.storage === "slock_managed_token") {
|
|
51424
|
-
return "manifest uses
|
|
51674
|
+
return "manifest uses Raft-managed token storage; no local HOME/XDG exports are required";
|
|
51425
51675
|
}
|
|
51426
51676
|
return "manifest does not request local CLI env exports";
|
|
51427
51677
|
}
|
|
@@ -51500,7 +51750,7 @@ async function resolveIntegrationEnv(input) {
|
|
|
51500
51750
|
}
|
|
51501
51751
|
function formatNoLocalEnv(input) {
|
|
51502
51752
|
const lines = [
|
|
51503
|
-
`#
|
|
51753
|
+
`# Raft integration profile for ${input.service}`,
|
|
51504
51754
|
input.manifestUrl ? `# manifest: ${input.manifestUrl}` : "# manifest: none declared",
|
|
51505
51755
|
"# No local CLI environment exports are required for this service.",
|
|
51506
51756
|
`# ${input.message}`
|
|
@@ -51510,7 +51760,7 @@ function formatNoLocalEnv(input) {
|
|
|
51510
51760
|
lines.push(`# list actions: raft integration invoke --service ${JSON.stringify(input.service)} --list-actions`);
|
|
51511
51761
|
lines.push(`# invoke action: raft integration invoke --service ${JSON.stringify(input.service)} --action <name>`);
|
|
51512
51762
|
}
|
|
51513
|
-
lines.push("#
|
|
51763
|
+
lines.push("# Raft did not set HOME/XDG exports and did not execute manifest commands.");
|
|
51514
51764
|
return lines.join("\n");
|
|
51515
51765
|
}
|
|
51516
51766
|
var integrationEnvCommand = defineCommand(
|
|
@@ -51624,10 +51874,10 @@ function parseHandlerArgs(serviceArgOrOpts, actionArgOrOpts, maybeOpts) {
|
|
|
51624
51874
|
}
|
|
51625
51875
|
function readTextReference(value) {
|
|
51626
51876
|
if (!value.startsWith("@")) return value;
|
|
51627
|
-
const
|
|
51628
|
-
if (!
|
|
51629
|
-
if (
|
|
51630
|
-
return
|
|
51877
|
+
const path10 = value.slice(1);
|
|
51878
|
+
if (!path10) throw cliError("INVALID_ARG", "@ file references must include a path");
|
|
51879
|
+
if (path10 === "-") return fs7.readFileSync(0, "utf8");
|
|
51880
|
+
return fs7.readFileSync(path10, "utf8");
|
|
51631
51881
|
}
|
|
51632
51882
|
function parseJsonObject(raw, label) {
|
|
51633
51883
|
let parsed;
|
|
@@ -51650,7 +51900,7 @@ function parseActionPayload(opts) {
|
|
|
51650
51900
|
Object.assign(payload, parseJsonObject(opts.dataJson, "--data-json"));
|
|
51651
51901
|
}
|
|
51652
51902
|
if (opts.dataFile) {
|
|
51653
|
-
const raw = opts.dataFile === "-" ?
|
|
51903
|
+
const raw = opts.dataFile === "-" ? fs7.readFileSync(0, "utf8") : fs7.readFileSync(opts.dataFile, "utf8");
|
|
51654
51904
|
Object.assign(payload, parseJsonObject(raw, "--data-file"));
|
|
51655
51905
|
}
|
|
51656
51906
|
for (const rawParam of opts.param ?? []) {
|
|
@@ -51672,7 +51922,7 @@ function validateRequiredParams(action, payload) {
|
|
|
51672
51922
|
}
|
|
51673
51923
|
}
|
|
51674
51924
|
}
|
|
51675
|
-
function
|
|
51925
|
+
function safeUrl2(value, label) {
|
|
51676
51926
|
let url2;
|
|
51677
51927
|
try {
|
|
51678
51928
|
url2 = new URL(value);
|
|
@@ -51688,87 +51938,16 @@ function safeUrl(value, label) {
|
|
|
51688
51938
|
return url2;
|
|
51689
51939
|
}
|
|
51690
51940
|
function resolveActionUrl(input) {
|
|
51691
|
-
const base = input.manifest.execution.base_url ?? input.manifest.app_origin ?? input.service.homepageUrl ?? (input.service.returnUrl ?
|
|
51941
|
+
const base = input.manifest.execution.base_url ?? input.manifest.app_origin ?? input.service.homepageUrl ?? (input.service.returnUrl ? safeUrl2(input.service.returnUrl, "service return URL").origin : null);
|
|
51692
51942
|
if (!base) {
|
|
51693
51943
|
throw cliError(
|
|
51694
51944
|
"INVALID_ARG",
|
|
51695
51945
|
"manifest must provide execution.base_url or app_origin, or the service must provide a homepage/return URL"
|
|
51696
51946
|
);
|
|
51697
51947
|
}
|
|
51698
|
-
const baseUrl =
|
|
51948
|
+
const baseUrl = safeUrl2(base, "action base URL");
|
|
51699
51949
|
return new URL(input.action.endpoint.path, baseUrl);
|
|
51700
51950
|
}
|
|
51701
|
-
function setCookieHeaderValues(headers) {
|
|
51702
|
-
const getSetCookie = headers.getSetCookie;
|
|
51703
|
-
return typeof getSetCookie === "function" ? getSetCookie.call(headers) : [headers.get("set-cookie")].filter((value) => Boolean(value));
|
|
51704
|
-
}
|
|
51705
|
-
function defaultCookiePath(pathname) {
|
|
51706
|
-
if (!pathname.startsWith("/") || pathname === "/") return "/";
|
|
51707
|
-
const lastSlash = pathname.lastIndexOf("/");
|
|
51708
|
-
if (lastSlash <= 0) return "/";
|
|
51709
|
-
return pathname.slice(0, lastSlash);
|
|
51710
|
-
}
|
|
51711
|
-
function parseSessionCookie(value, sourceUrl) {
|
|
51712
|
-
const parts = value.split(";").map((part) => part.trim()).filter(Boolean);
|
|
51713
|
-
const pair = parts.shift();
|
|
51714
|
-
if (!pair || !pair.includes("=") || pair.startsWith("=")) return null;
|
|
51715
|
-
const sourceHost = sourceUrl.hostname.toLowerCase();
|
|
51716
|
-
let host = sourceHost;
|
|
51717
|
-
let path9 = defaultCookiePath(sourceUrl.pathname);
|
|
51718
|
-
let secure = false;
|
|
51719
|
-
for (const part of parts) {
|
|
51720
|
-
const separator = part.indexOf("=");
|
|
51721
|
-
const rawName = separator >= 0 ? part.slice(0, separator) : part;
|
|
51722
|
-
const rawValue = separator >= 0 ? part.slice(separator + 1) : "";
|
|
51723
|
-
const name = rawName.trim().toLowerCase();
|
|
51724
|
-
if (name === "secure") {
|
|
51725
|
-
secure = true;
|
|
51726
|
-
} else if (name === "path" && rawValue.trim().startsWith("/")) {
|
|
51727
|
-
path9 = rawValue.trim();
|
|
51728
|
-
} else if (name === "domain") {
|
|
51729
|
-
const domain2 = rawValue.trim().replace(/^\./, "").toLowerCase();
|
|
51730
|
-
if (domain2 !== sourceHost) return null;
|
|
51731
|
-
host = domain2;
|
|
51732
|
-
}
|
|
51733
|
-
}
|
|
51734
|
-
return { pair, host, path: path9, secure };
|
|
51735
|
-
}
|
|
51736
|
-
function cookiePathMatches(requestPath, cookiePath) {
|
|
51737
|
-
if (requestPath === cookiePath) return true;
|
|
51738
|
-
if (cookiePath.endsWith("/")) return requestPath.startsWith(cookiePath);
|
|
51739
|
-
return requestPath.startsWith(`${cookiePath}/`);
|
|
51740
|
-
}
|
|
51741
|
-
function cookieHeaderForUrl(cookies, url2) {
|
|
51742
|
-
const host = url2.hostname.toLowerCase();
|
|
51743
|
-
const valid = cookies.filter((cookie) => cookie.host === host).filter((cookie) => !cookie.secure || url2.protocol === "https:").filter((cookie) => cookiePathMatches(url2.pathname || "/", cookie.path)).map((cookie) => cookie.pair);
|
|
51744
|
-
return valid.length > 0 ? valid.join("; ") : null;
|
|
51745
|
-
}
|
|
51746
|
-
function sessionCookiesFromSetCookie(headers, sourceUrl) {
|
|
51747
|
-
return setCookieHeaderValues(headers).map((value) => parseSessionCookie(value, sourceUrl)).filter((value) => Boolean(value));
|
|
51748
|
-
}
|
|
51749
|
-
async function establishServiceSession(input) {
|
|
51750
|
-
const callbackUrl = buildAgentCallbackHandoffUrl(input.service.returnUrl, input.login.requestId);
|
|
51751
|
-
if (!callbackUrl) {
|
|
51752
|
-
throw cliError("INTEGRATION_INVOKE_FAILED", "service return URL cannot be used for Agent Login callback handoff");
|
|
51753
|
-
}
|
|
51754
|
-
const parsedCallbackUrl = safeUrl(callbackUrl, "service callback URL");
|
|
51755
|
-
const response = await fetch(callbackUrl, {
|
|
51756
|
-
method: "GET",
|
|
51757
|
-
redirect: "manual",
|
|
51758
|
-
headers: { accept: "text/html,application/json" }
|
|
51759
|
-
});
|
|
51760
|
-
if (response.status < 200 || response.status >= 400) {
|
|
51761
|
-
throw cliError("INTEGRATION_INVOKE_FAILED", `service callback handoff failed with HTTP ${response.status}`);
|
|
51762
|
-
}
|
|
51763
|
-
const cookies = sessionCookiesFromSetCookie(response.headers, parsedCallbackUrl);
|
|
51764
|
-
if (cookies.length === 0) {
|
|
51765
|
-
throw cliError(
|
|
51766
|
-
"INTEGRATION_INVOKE_FAILED",
|
|
51767
|
-
"service callback handoff did not set a session cookie; the service may not support stateless Agent Login API actions yet"
|
|
51768
|
-
);
|
|
51769
|
-
}
|
|
51770
|
-
return cookies;
|
|
51771
|
-
}
|
|
51772
51951
|
function appendPayloadAsQuery(url2, payload) {
|
|
51773
51952
|
for (const [key, value] of Object.entries(payload)) {
|
|
51774
51953
|
if (value === void 0 || value === null) continue;
|
|
@@ -51806,6 +51985,15 @@ async function invokeHttpAction(input) {
|
|
|
51806
51985
|
throw cliError("INVALID_JSON_RESPONSE", `service action returned invalid JSON (HTTP ${response.status})`);
|
|
51807
51986
|
});
|
|
51808
51987
|
if (!response.ok) {
|
|
51988
|
+
if (response.status === 401 || response.status === 403) {
|
|
51989
|
+
throw cliError(
|
|
51990
|
+
"INTEGRATION_INVOKE_FAILED",
|
|
51991
|
+
`service session was rejected or expired (HTTP ${response.status})`,
|
|
51992
|
+
{
|
|
51993
|
+
suggestedNextAction: `Run \`raft integration login --service ${input.service.clientId}\` and retry the action.`
|
|
51994
|
+
}
|
|
51995
|
+
);
|
|
51996
|
+
}
|
|
51809
51997
|
const message = value2 && typeof value2 === "object" && "error" in value2 ? String(value2.error) : `service action failed with HTTP ${response.status}`;
|
|
51810
51998
|
throw cliError("INTEGRATION_INVOKE_FAILED", message);
|
|
51811
51999
|
}
|
|
@@ -51813,6 +52001,15 @@ async function invokeHttpAction(input) {
|
|
|
51813
52001
|
}
|
|
51814
52002
|
const value = await response.text();
|
|
51815
52003
|
if (!response.ok) {
|
|
52004
|
+
if (response.status === 401 || response.status === 403) {
|
|
52005
|
+
throw cliError(
|
|
52006
|
+
"INTEGRATION_INVOKE_FAILED",
|
|
52007
|
+
`service session was rejected or expired (HTTP ${response.status})`,
|
|
52008
|
+
{
|
|
52009
|
+
suggestedNextAction: `Run \`raft integration login --service ${input.service.clientId}\` and retry the action.`
|
|
52010
|
+
}
|
|
52011
|
+
);
|
|
52012
|
+
}
|
|
51816
52013
|
throw cliError("INTEGRATION_INVOKE_FAILED", value || `service action failed with HTTP ${response.status}`);
|
|
51817
52014
|
}
|
|
51818
52015
|
return { kind: "text", status: response.status, value };
|
|
@@ -51858,7 +52055,53 @@ function formatActionResult(input) {
|
|
|
51858
52055
|
}
|
|
51859
52056
|
return lines.join("\n");
|
|
51860
52057
|
}
|
|
51861
|
-
|
|
52058
|
+
function unsupportedAuthNextAction(service, handoff2) {
|
|
52059
|
+
const loginCommand = `raft integration login --service ${JSON.stringify(service.clientId)}`;
|
|
52060
|
+
const manifestGuidance = [
|
|
52061
|
+
"or ask the service owner to publish a current login_with_raft HTTP API action manifest for integration invoke.",
|
|
52062
|
+
"`oauth_session_cookie` manifests are session-cookie services and are not directly invokable through this command yet."
|
|
52063
|
+
];
|
|
52064
|
+
if (handoff2?.kind === "handoff_url") {
|
|
52065
|
+
return [
|
|
52066
|
+
"A login request was created or reused for this agent.",
|
|
52067
|
+
`Use the service callback handoff URL to establish the service session: ${handoff2.url}`,
|
|
52068
|
+
...manifestGuidance
|
|
52069
|
+
].join(" ");
|
|
52070
|
+
}
|
|
52071
|
+
if (handoff2?.kind === "approval_required") {
|
|
52072
|
+
const card = handoff2.actionCardMessageId ? `Approval request ${handoff2.requestId} was posted to ${handoff2.target ?? "-"} as card ${handoff2.actionCardMessageId}.` : `Approval request ${handoff2.requestId} was created but no approval card was posted.`;
|
|
52073
|
+
return [
|
|
52074
|
+
"Human approval is required before a service callback handoff URL can be generated.",
|
|
52075
|
+
card,
|
|
52076
|
+
"Ask a server owner/admin to approve it, then rerun this command to receive the callback handoff URL.",
|
|
52077
|
+
`To post an approval card, rerun with --target <channel-or-thread>, or run \`${loginCommand} --target <channel-or-thread>\`.`,
|
|
52078
|
+
...manifestGuidance
|
|
52079
|
+
].join(" ");
|
|
52080
|
+
}
|
|
52081
|
+
if (service.returnUrl) {
|
|
52082
|
+
const lines = [
|
|
52083
|
+
`Run \`${loginCommand}\` and use the printed service callback handoff URL to establish the service session,`,
|
|
52084
|
+
...manifestGuidance
|
|
52085
|
+
];
|
|
52086
|
+
if (handoff2?.kind === "unavailable") {
|
|
52087
|
+
lines.unshift(`Could not prepare a callback handoff URL automatically: ${handoff2.reason}.`);
|
|
52088
|
+
}
|
|
52089
|
+
return lines.join(" ");
|
|
52090
|
+
}
|
|
52091
|
+
return [
|
|
52092
|
+
"Ask the service owner to publish a current login_with_raft HTTP API action manifest for integration invoke.",
|
|
52093
|
+
"`oauth_session_cookie` manifests are session-cookie services and are not directly invokable through this command yet."
|
|
52094
|
+
].join(" ");
|
|
52095
|
+
}
|
|
52096
|
+
async function manifestInvalidNextAction(service, err, prepareHandoff) {
|
|
52097
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
52098
|
+
if (/auth\.type must be login_with_raft/.test(message)) {
|
|
52099
|
+
return unsupportedAuthNextAction(service, await prepareHandoff?.());
|
|
52100
|
+
}
|
|
52101
|
+
return void 0;
|
|
52102
|
+
}
|
|
52103
|
+
async function fetchManifestForInvoke(input) {
|
|
52104
|
+
const service = input.service;
|
|
51862
52105
|
if (!service.agentManifestUrl) {
|
|
51863
52106
|
throw cliError("INTEGRATION_MANIFEST_MISSING", `${service.name} does not expose an agent behavior manifest`);
|
|
51864
52107
|
}
|
|
@@ -51872,9 +52115,20 @@ async function fetchManifestForInvoke(service) {
|
|
|
51872
52115
|
if (err instanceof AgentManifestResponseFormatError) {
|
|
51873
52116
|
throw cliError("INTEGRATION_MANIFEST_INVALID", err.message, { cause: err });
|
|
51874
52117
|
}
|
|
51875
|
-
|
|
52118
|
+
const suggestedNextAction = await manifestInvalidNextAction(
|
|
52119
|
+
service,
|
|
52120
|
+
err,
|
|
52121
|
+
input.prepareUnsupportedAuthHandoff
|
|
52122
|
+
);
|
|
52123
|
+
throw cliError("INTEGRATION_MANIFEST_INVALID", err.message, {
|
|
52124
|
+
cause: err,
|
|
52125
|
+
suggestedNextAction
|
|
52126
|
+
});
|
|
51876
52127
|
}
|
|
51877
52128
|
}
|
|
52129
|
+
function loginFailureReason(res) {
|
|
52130
|
+
return res.error ?? `HTTP ${res.status}`;
|
|
52131
|
+
}
|
|
51878
52132
|
var integrationInvokeCommand = defineCommand(
|
|
51879
52133
|
{
|
|
51880
52134
|
name: "invoke",
|
|
@@ -51924,7 +52178,44 @@ var integrationInvokeCommand = defineCommand(
|
|
|
51924
52178
|
if (!service) {
|
|
51925
52179
|
throw cliError("INTEGRATION_NOT_FOUND", `No registered integration matched ${serviceQuery}`);
|
|
51926
52180
|
}
|
|
51927
|
-
const
|
|
52181
|
+
const prepareUnsupportedAuthHandoff = async () => {
|
|
52182
|
+
if (!service.returnUrl) return void 0;
|
|
52183
|
+
let scopes2;
|
|
52184
|
+
try {
|
|
52185
|
+
scopes2 = normalizeScopes2(opts.scope);
|
|
52186
|
+
} catch (err) {
|
|
52187
|
+
return { kind: "unavailable", reason: err instanceof Error ? err.message : String(err) };
|
|
52188
|
+
}
|
|
52189
|
+
const loginRes = await api.integrations.login({
|
|
52190
|
+
service: service.clientId,
|
|
52191
|
+
scopes: scopes2,
|
|
52192
|
+
target: opts.target?.trim() || void 0
|
|
52193
|
+
});
|
|
52194
|
+
if (!loginRes.ok || !loginRes.data) {
|
|
52195
|
+
return { kind: "unavailable", reason: loginFailureReason(loginRes) };
|
|
52196
|
+
}
|
|
52197
|
+
if (loginRes.data.status === "approval_required") {
|
|
52198
|
+
const requestId = loginRes.data.approval?.requestId ?? loginRes.data.requestId;
|
|
52199
|
+
if (!requestId) {
|
|
52200
|
+
return { kind: "unavailable", reason: "approval-required login response did not include a request id" };
|
|
52201
|
+
}
|
|
52202
|
+
return {
|
|
52203
|
+
kind: "approval_required",
|
|
52204
|
+
requestId,
|
|
52205
|
+
target: loginRes.data.approval?.target ?? null,
|
|
52206
|
+
actionCardMessageId: loginRes.data.approval?.actionCardMessageId ?? null
|
|
52207
|
+
};
|
|
52208
|
+
}
|
|
52209
|
+
if (!loginRes.data.requestId) {
|
|
52210
|
+
return { kind: "unavailable", reason: "agent login response did not include an internal one-time handoff request" };
|
|
52211
|
+
}
|
|
52212
|
+
const callbackHandoffUrl = buildAgentCallbackHandoffUrl(
|
|
52213
|
+
loginRes.data.service.returnUrl ?? service.returnUrl,
|
|
52214
|
+
loginRes.data.requestId
|
|
52215
|
+
);
|
|
52216
|
+
return callbackHandoffUrl ? { kind: "handoff_url", url: callbackHandoffUrl } : { kind: "unavailable", reason: "service return URL cannot be used for Agent Login callback handoff" };
|
|
52217
|
+
};
|
|
52218
|
+
const manifest = await fetchManifestForInvoke({ service, prepareUnsupportedAuthHandoff });
|
|
51928
52219
|
if (manifest.execution.mode !== "http_api") {
|
|
51929
52220
|
throw cliError("INTEGRATION_MANIFEST_UNSUPPORTED", "manifest execution mode is not http_api");
|
|
51930
52221
|
}
|
|
@@ -51949,25 +52240,36 @@ var integrationInvokeCommand = defineCommand(
|
|
|
51949
52240
|
const payload = parseActionPayload(opts);
|
|
51950
52241
|
validateRequiredParams(action, payload);
|
|
51951
52242
|
const scopes = normalizeScopes2(opts.scope);
|
|
51952
|
-
const
|
|
51953
|
-
|
|
51954
|
-
|
|
51955
|
-
|
|
51956
|
-
|
|
51957
|
-
|
|
51958
|
-
|
|
51959
|
-
|
|
51960
|
-
|
|
51961
|
-
|
|
51962
|
-
|
|
51963
|
-
|
|
51964
|
-
|
|
51965
|
-
|
|
51966
|
-
|
|
52243
|
+
const storedSession = scopes || opts.target ? null : loadStoredIntegrationSession({ service, agentContext, env: cmdCtx.env });
|
|
52244
|
+
let cookies = storedSession?.cookies ?? null;
|
|
52245
|
+
if (!cookies) {
|
|
52246
|
+
const loginRes = await api.integrations.login({
|
|
52247
|
+
service: service.clientId,
|
|
52248
|
+
scopes,
|
|
52249
|
+
target: opts.target?.trim() || void 0
|
|
52250
|
+
});
|
|
52251
|
+
if (!loginRes.ok || !loginRes.data) {
|
|
52252
|
+
const code = loginRes.status >= 500 ? "SERVER_5XX" : "INTEGRATION_LOGIN_FAILED";
|
|
52253
|
+
throw cliError(code, loginRes.error ?? `HTTP ${loginRes.status}`);
|
|
52254
|
+
}
|
|
52255
|
+
if (loginRes.data.status === "approval_required") {
|
|
52256
|
+
throw cliError(
|
|
52257
|
+
"INTEGRATION_APPROVAL_REQUIRED",
|
|
52258
|
+
"human approval is required before invoking this integration action",
|
|
52259
|
+
{ suggestedNextAction: "Ask a server owner/admin to approve the integration login request, then rerun the command." }
|
|
52260
|
+
);
|
|
52261
|
+
}
|
|
52262
|
+
const session = await ensureIntegrationServiceSession({
|
|
52263
|
+
login: loginRes.data,
|
|
52264
|
+
service,
|
|
52265
|
+
agentContext,
|
|
52266
|
+
env: cmdCtx.env,
|
|
52267
|
+
refresh: true
|
|
52268
|
+
});
|
|
52269
|
+
cookies = session.cookies;
|
|
51967
52270
|
}
|
|
51968
|
-
const cookies = await establishServiceSession({ login: loginRes.data, service });
|
|
51969
52271
|
const url2 = resolveActionUrl({ service, manifest, action });
|
|
51970
|
-
const result2 = await invokeHttpAction({ url: url2, action, payload, cookies });
|
|
52272
|
+
const result2 = await invokeHttpAction({ url: url2, action, payload, cookies, service });
|
|
51971
52273
|
if (opts.json) {
|
|
51972
52274
|
writeJson(cmdCtx.io, {
|
|
51973
52275
|
ok: true,
|
|
@@ -52194,6 +52496,18 @@ function formatReminderType(r) {
|
|
|
52194
52496
|
return `(recurring \xB7 ${r.recurrence.description})`;
|
|
52195
52497
|
}
|
|
52196
52498
|
function buildScheduleBody(opts, now = () => Intl.DateTimeFormat().resolvedOptions().timeZone) {
|
|
52499
|
+
const canonicalMessageId = opts.messageId?.trim();
|
|
52500
|
+
const legacyMsgId = opts.msgId?.trim();
|
|
52501
|
+
if (canonicalMessageId && legacyMsgId && canonicalMessageId !== legacyMsgId) {
|
|
52502
|
+
return {
|
|
52503
|
+
body: {},
|
|
52504
|
+
error: {
|
|
52505
|
+
code: "INVALID_ARG",
|
|
52506
|
+
message: "Pass only one message anchor; --msg-id is a deprecated alias for --message-id"
|
|
52507
|
+
}
|
|
52508
|
+
};
|
|
52509
|
+
}
|
|
52510
|
+
const msgId = canonicalMessageId || legacyMsgId || void 0;
|
|
52197
52511
|
if (!opts.delaySeconds && !opts.fireAt && !opts.repeat) {
|
|
52198
52512
|
return {
|
|
52199
52513
|
body: {},
|
|
@@ -52209,7 +52523,7 @@ function buildScheduleBody(opts, now = () => Intl.DateTimeFormat().resolvedOptio
|
|
|
52209
52523
|
}
|
|
52210
52524
|
};
|
|
52211
52525
|
}
|
|
52212
|
-
const body = { title: opts.title, msgId:
|
|
52526
|
+
const body = { title: opts.title, msgId: msgId ?? null };
|
|
52213
52527
|
if (opts.delaySeconds !== void 0) {
|
|
52214
52528
|
const n = Number(opts.delaySeconds);
|
|
52215
52529
|
if (!Number.isFinite(n) || !Number.isInteger(n) || n <= 0) {
|
|
@@ -52234,7 +52548,7 @@ function buildScheduleBody(opts, now = () => Intl.DateTimeFormat().resolvedOptio
|
|
|
52234
52548
|
body: {},
|
|
52235
52549
|
error: {
|
|
52236
52550
|
code: "INVALID_ARG",
|
|
52237
|
-
message: "Reminder create requires an anchor msgId; resolve a message first and pass --
|
|
52551
|
+
message: "Reminder create requires an anchor msgId; resolve a message first and pass --message-id"
|
|
52238
52552
|
}
|
|
52239
52553
|
};
|
|
52240
52554
|
}
|
|
@@ -52250,7 +52564,8 @@ var reminderScheduleCommand = defineCommand(
|
|
|
52250
52564
|
{ flags: "--fire-at <iso>", description: "ISO-8601 UTC timestamp, e.g. 2026-04-21T09:00:00Z. Use only for absolute calendar times" },
|
|
52251
52565
|
{ flags: "--repeat <rule>", description: "Recurrence rule: every:15m | every:2h | every:1d | daily@09:00 | weekly:mon,fri@09:00" },
|
|
52252
52566
|
{ flags: "--channel <ref>", description: "Optional channel to post a receipt message in (e.g. #general, dm:@alice)." },
|
|
52253
|
-
{ flags: "--
|
|
52567
|
+
{ flags: "--message-id <id>", description: "Message id (full or short) this reminder is anchored to. Required for agent-created reminders." },
|
|
52568
|
+
{ flags: "--msg-id <id>", description: "Deprecated alias for --message-id." }
|
|
52254
52569
|
]
|
|
52255
52570
|
},
|
|
52256
52571
|
async (ctx, opts) => {
|
|
@@ -52504,20 +52819,12 @@ var reminderLogCommand = defineCommand(
|
|
|
52504
52819
|
function registerReminderLogCommand(parent, runtimeOptions = {}) {
|
|
52505
52820
|
registerCliCommand(parent, reminderLogCommand, runtimeOptions);
|
|
52506
52821
|
}
|
|
52507
|
-
function resolveCliInvocationName(argv1) {
|
|
52508
|
-
if (process.env.SLOCK_CLI_INVOCATION_NAME === "raft") {
|
|
52509
|
-
return "raft";
|
|
52510
|
-
}
|
|
52511
|
-
const basename3 = argv1?.split(/[\\/]/).pop() ?? "";
|
|
52512
|
-
return basename3 === "raft" ? "raft" : "slock";
|
|
52513
|
-
}
|
|
52514
52822
|
var program2 = new Command();
|
|
52515
|
-
|
|
52516
|
-
|
|
52517
|
-
"Agent-facing CLI for Slock. Two entry shapes: (A) external agent via `raft agent login --profile-slug <slug>` to create a profile, then `raft --profile <slug>` (or RAFT_PROFILE=<slug>) to use it; (B) daemon-injected runner, where the local `slock` wrapper sets the SLOCK_AGENT_* env vars for you."
|
|
52823
|
+
program2.name("raft").description(
|
|
52824
|
+
"Agent-facing CLI for Raft. Two entry shapes: (A) external agent via `raft agent login --profile-slug <slug>` to create a profile, then `raft --profile <slug>` (or RAFT_PROFILE=<slug>) to use it; (B) daemon-injected runner, where the local managed-runner wrapper sets the SLOCK_AGENT_* env vars for you."
|
|
52518
52825
|
).option(
|
|
52519
52826
|
"-p, --profile <slug>",
|
|
52520
|
-
"Use
|
|
52827
|
+
"Use an existing local profile credential. Equivalent to setting RAFT_PROFILE=<slug>. To create a new profile, use `raft agent login --profile-slug <slug>`."
|
|
52521
52828
|
).version(readCliVersion());
|
|
52522
52829
|
program2.hook("preAction", () => {
|
|
52523
52830
|
const opts = program2.opts();
|
|
@@ -52527,7 +52834,7 @@ program2.hook("preAction", () => {
|
|
|
52527
52834
|
});
|
|
52528
52835
|
var authCmd = program2.command("auth").description("Auth introspection");
|
|
52529
52836
|
registerWhoamiCommand(authCmd);
|
|
52530
|
-
var agentCmd = program2.command("agent").description("External agent onboarding (device-code login \u2192 sk_agent_* mint \u2192
|
|
52837
|
+
var agentCmd = program2.command("agent").description("External agent onboarding (device-code login \u2192 sk_agent_* mint \u2192 local profile credential)");
|
|
52531
52838
|
registerAgentLoginCommand(agentCmd);
|
|
52532
52839
|
registerAgentListCommand(agentCmd);
|
|
52533
52840
|
registerAgentBridgeCommand(agentCmd);
|
|
@@ -52546,7 +52853,7 @@ registerThreadUnfollowCommand(threadCmd);
|
|
|
52546
52853
|
var serverCmd = program2.command("server").description("Server / workspace introspection");
|
|
52547
52854
|
registerServerInfoCommand(serverCmd);
|
|
52548
52855
|
registerServerUpdateCommand(serverCmd);
|
|
52549
|
-
var manualCmd = program2.command("manual").description("
|
|
52856
|
+
var manualCmd = program2.command("manual").description("Raft Manual for Agents retrieval (canonical operating topics)");
|
|
52550
52857
|
registerKnowledgeGetCommand(manualCmd);
|
|
52551
52858
|
var knowledgeCmd = program2.command("knowledge").description("Legacy alias for `raft manual`");
|
|
52552
52859
|
registerKnowledgeGetCommand(knowledgeCmd);
|