@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
package/dist/cli/index.js
CHANGED
|
@@ -997,8 +997,8 @@ var require_command = __commonJS({
|
|
|
997
997
|
init_esm_shims();
|
|
998
998
|
var EventEmitter = __require("events").EventEmitter;
|
|
999
999
|
var childProcess = __require("child_process");
|
|
1000
|
-
var
|
|
1001
|
-
var
|
|
1000
|
+
var path10 = __require("path");
|
|
1001
|
+
var fs8 = __require("fs");
|
|
1002
1002
|
var process3 = __require("process");
|
|
1003
1003
|
var { Argument: Argument2, humanReadableArgName } = require_argument();
|
|
1004
1004
|
var { CommanderError: CommanderError2 } = require_error();
|
|
@@ -1930,11 +1930,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1930
1930
|
let launchWithNode = false;
|
|
1931
1931
|
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
1932
1932
|
function findFile(baseDir, baseName) {
|
|
1933
|
-
const localBin =
|
|
1934
|
-
if (
|
|
1935
|
-
if (sourceExt.includes(
|
|
1933
|
+
const localBin = path10.resolve(baseDir, baseName);
|
|
1934
|
+
if (fs8.existsSync(localBin)) return localBin;
|
|
1935
|
+
if (sourceExt.includes(path10.extname(baseName))) return void 0;
|
|
1936
1936
|
const foundExt = sourceExt.find(
|
|
1937
|
-
(ext) =>
|
|
1937
|
+
(ext) => fs8.existsSync(`${localBin}${ext}`)
|
|
1938
1938
|
);
|
|
1939
1939
|
if (foundExt) return `${localBin}${foundExt}`;
|
|
1940
1940
|
return void 0;
|
|
@@ -1946,21 +1946,21 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1946
1946
|
if (this._scriptPath) {
|
|
1947
1947
|
let resolvedScriptPath;
|
|
1948
1948
|
try {
|
|
1949
|
-
resolvedScriptPath =
|
|
1949
|
+
resolvedScriptPath = fs8.realpathSync(this._scriptPath);
|
|
1950
1950
|
} catch (err) {
|
|
1951
1951
|
resolvedScriptPath = this._scriptPath;
|
|
1952
1952
|
}
|
|
1953
|
-
executableDir =
|
|
1954
|
-
|
|
1953
|
+
executableDir = path10.resolve(
|
|
1954
|
+
path10.dirname(resolvedScriptPath),
|
|
1955
1955
|
executableDir
|
|
1956
1956
|
);
|
|
1957
1957
|
}
|
|
1958
1958
|
if (executableDir) {
|
|
1959
1959
|
let localFile = findFile(executableDir, executableFile);
|
|
1960
1960
|
if (!localFile && !subcommand._executableFile && this._scriptPath) {
|
|
1961
|
-
const legacyName =
|
|
1961
|
+
const legacyName = path10.basename(
|
|
1962
1962
|
this._scriptPath,
|
|
1963
|
-
|
|
1963
|
+
path10.extname(this._scriptPath)
|
|
1964
1964
|
);
|
|
1965
1965
|
if (legacyName !== this._name) {
|
|
1966
1966
|
localFile = findFile(
|
|
@@ -1971,7 +1971,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1971
1971
|
}
|
|
1972
1972
|
executableFile = localFile || executableFile;
|
|
1973
1973
|
}
|
|
1974
|
-
launchWithNode = sourceExt.includes(
|
|
1974
|
+
launchWithNode = sourceExt.includes(path10.extname(executableFile));
|
|
1975
1975
|
let proc;
|
|
1976
1976
|
if (process3.platform !== "win32") {
|
|
1977
1977
|
if (launchWithNode) {
|
|
@@ -2811,7 +2811,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2811
2811
|
* @return {Command}
|
|
2812
2812
|
*/
|
|
2813
2813
|
nameFromFilename(filename) {
|
|
2814
|
-
this._name =
|
|
2814
|
+
this._name = path10.basename(filename, path10.extname(filename));
|
|
2815
2815
|
return this;
|
|
2816
2816
|
}
|
|
2817
2817
|
/**
|
|
@@ -2825,9 +2825,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2825
2825
|
* @param {string} [path]
|
|
2826
2826
|
* @return {(string|null|Command)}
|
|
2827
2827
|
*/
|
|
2828
|
-
executableDir(
|
|
2829
|
-
if (
|
|
2830
|
-
this._executableDir =
|
|
2828
|
+
executableDir(path11) {
|
|
2829
|
+
if (path11 === void 0) return this._executableDir;
|
|
2830
|
+
this._executableDir = path11;
|
|
2831
2831
|
return this;
|
|
2832
2832
|
}
|
|
2833
2833
|
/**
|
|
@@ -4173,14 +4173,14 @@ var require_util = __commonJS({
|
|
|
4173
4173
|
}
|
|
4174
4174
|
const port = url2.port != null ? url2.port : url2.protocol === "https:" ? 443 : 80;
|
|
4175
4175
|
let origin = url2.origin != null ? url2.origin : `${url2.protocol || ""}//${url2.hostname || ""}:${port}`;
|
|
4176
|
-
let
|
|
4176
|
+
let path10 = url2.path != null ? url2.path : `${url2.pathname || ""}${url2.search || ""}`;
|
|
4177
4177
|
if (origin[origin.length - 1] === "/") {
|
|
4178
4178
|
origin = origin.slice(0, origin.length - 1);
|
|
4179
4179
|
}
|
|
4180
|
-
if (
|
|
4181
|
-
|
|
4180
|
+
if (path10 && path10[0] !== "/") {
|
|
4181
|
+
path10 = `/${path10}`;
|
|
4182
4182
|
}
|
|
4183
|
-
return new URL(`${origin}${
|
|
4183
|
+
return new URL(`${origin}${path10}`);
|
|
4184
4184
|
}
|
|
4185
4185
|
if (!isHttpOrHttpsPrefixed(url2.origin || url2.protocol)) {
|
|
4186
4186
|
throw new InvalidArgumentError2("Invalid URL protocol: the URL must start with `http:` or `https:`.");
|
|
@@ -5003,9 +5003,9 @@ var require_diagnostics = __commonJS({
|
|
|
5003
5003
|
"undici:client:sendHeaders",
|
|
5004
5004
|
(evt) => {
|
|
5005
5005
|
const {
|
|
5006
|
-
request: { method, path:
|
|
5006
|
+
request: { method, path: path10, origin }
|
|
5007
5007
|
} = evt;
|
|
5008
|
-
debugLog("sending request to %s %s%s", method, origin,
|
|
5008
|
+
debugLog("sending request to %s %s%s", method, origin, path10);
|
|
5009
5009
|
}
|
|
5010
5010
|
);
|
|
5011
5011
|
}
|
|
@@ -5023,14 +5023,14 @@ var require_diagnostics = __commonJS({
|
|
|
5023
5023
|
"undici:request:headers",
|
|
5024
5024
|
(evt) => {
|
|
5025
5025
|
const {
|
|
5026
|
-
request: { method, path:
|
|
5026
|
+
request: { method, path: path10, origin },
|
|
5027
5027
|
response: { statusCode }
|
|
5028
5028
|
} = evt;
|
|
5029
5029
|
debugLog(
|
|
5030
5030
|
"received response to %s %s%s - HTTP %d",
|
|
5031
5031
|
method,
|
|
5032
5032
|
origin,
|
|
5033
|
-
|
|
5033
|
+
path10,
|
|
5034
5034
|
statusCode
|
|
5035
5035
|
);
|
|
5036
5036
|
}
|
|
@@ -5039,23 +5039,23 @@ var require_diagnostics = __commonJS({
|
|
|
5039
5039
|
"undici:request:trailers",
|
|
5040
5040
|
(evt) => {
|
|
5041
5041
|
const {
|
|
5042
|
-
request: { method, path:
|
|
5042
|
+
request: { method, path: path10, origin }
|
|
5043
5043
|
} = evt;
|
|
5044
|
-
debugLog("trailers received from %s %s%s", method, origin,
|
|
5044
|
+
debugLog("trailers received from %s %s%s", method, origin, path10);
|
|
5045
5045
|
}
|
|
5046
5046
|
);
|
|
5047
5047
|
diagnosticsChannel.subscribe(
|
|
5048
5048
|
"undici:request:error",
|
|
5049
5049
|
(evt) => {
|
|
5050
5050
|
const {
|
|
5051
|
-
request: { method, path:
|
|
5051
|
+
request: { method, path: path10, origin },
|
|
5052
5052
|
error: error48
|
|
5053
5053
|
} = evt;
|
|
5054
5054
|
debugLog(
|
|
5055
5055
|
"request to %s %s%s errored - %s",
|
|
5056
5056
|
method,
|
|
5057
5057
|
origin,
|
|
5058
|
-
|
|
5058
|
+
path10,
|
|
5059
5059
|
error48.message
|
|
5060
5060
|
);
|
|
5061
5061
|
}
|
|
@@ -5159,7 +5159,7 @@ var require_request = __commonJS({
|
|
|
5159
5159
|
var kHandler = /* @__PURE__ */ Symbol("handler");
|
|
5160
5160
|
var Request = class {
|
|
5161
5161
|
constructor(origin, {
|
|
5162
|
-
path:
|
|
5162
|
+
path: path10,
|
|
5163
5163
|
method,
|
|
5164
5164
|
body,
|
|
5165
5165
|
headers,
|
|
@@ -5176,11 +5176,11 @@ var require_request = __commonJS({
|
|
|
5176
5176
|
maxRedirections,
|
|
5177
5177
|
typeOfService
|
|
5178
5178
|
}, handler) {
|
|
5179
|
-
if (typeof
|
|
5179
|
+
if (typeof path10 !== "string") {
|
|
5180
5180
|
throw new InvalidArgumentError2("path must be a string");
|
|
5181
|
-
} else if (
|
|
5181
|
+
} else if (path10[0] !== "/" && !(path10.startsWith("http://") || path10.startsWith("https://")) && method !== "CONNECT") {
|
|
5182
5182
|
throw new InvalidArgumentError2("path must be an absolute URL or start with a slash");
|
|
5183
|
-
} else if (invalidPathRegex.test(
|
|
5183
|
+
} else if (invalidPathRegex.test(path10)) {
|
|
5184
5184
|
throw new InvalidArgumentError2("invalid request path");
|
|
5185
5185
|
}
|
|
5186
5186
|
if (typeof method !== "string") {
|
|
@@ -5255,7 +5255,7 @@ var require_request = __commonJS({
|
|
|
5255
5255
|
this.completed = false;
|
|
5256
5256
|
this.aborted = false;
|
|
5257
5257
|
this.upgrade = upgrade || null;
|
|
5258
|
-
this.path = query ? serializePathWithQuery(
|
|
5258
|
+
this.path = query ? serializePathWithQuery(path10, query) : path10;
|
|
5259
5259
|
this.origin = origin;
|
|
5260
5260
|
this.protocol = getProtocolFromUrlString(origin);
|
|
5261
5261
|
this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" : idempotent;
|
|
@@ -10316,7 +10316,7 @@ var require_client_h1 = __commonJS({
|
|
|
10316
10316
|
return method !== "GET" && method !== "HEAD" && method !== "OPTIONS" && method !== "TRACE" && method !== "CONNECT";
|
|
10317
10317
|
}
|
|
10318
10318
|
function writeH1(client, request) {
|
|
10319
|
-
const { method, path:
|
|
10319
|
+
const { method, path: path10, host, upgrade, blocking, reset } = request;
|
|
10320
10320
|
let { body, headers, contentLength } = request;
|
|
10321
10321
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH" || method === "QUERY" || method === "PROPFIND" || method === "PROPPATCH";
|
|
10322
10322
|
if (util.isFormDataLike(body)) {
|
|
@@ -10385,7 +10385,7 @@ var require_client_h1 = __commonJS({
|
|
|
10385
10385
|
if (socket.setTypeOfService) {
|
|
10386
10386
|
socket.setTypeOfService(request.typeOfService);
|
|
10387
10387
|
}
|
|
10388
|
-
let header = `${method} ${
|
|
10388
|
+
let header = `${method} ${path10} HTTP/1.1\r
|
|
10389
10389
|
`;
|
|
10390
10390
|
if (typeof host === "string") {
|
|
10391
10391
|
header += `host: ${host}\r
|
|
@@ -11039,7 +11039,7 @@ var require_client_h2 = __commonJS({
|
|
|
11039
11039
|
function writeH2(client, request) {
|
|
11040
11040
|
const requestTimeout = request.bodyTimeout ?? client[kBodyTimeout];
|
|
11041
11041
|
const session = client[kHTTP2Session];
|
|
11042
|
-
const { method, path:
|
|
11042
|
+
const { method, path: path10, host, upgrade, expectContinue, signal, protocol, headers: reqHeaders } = request;
|
|
11043
11043
|
let { body } = request;
|
|
11044
11044
|
if (upgrade != null && upgrade !== "websocket") {
|
|
11045
11045
|
util.errorRequest(client, request, new InvalidArgumentError2(`Custom upgrade "${upgrade}" not supported over HTTP/2`));
|
|
@@ -11107,7 +11107,7 @@ var require_client_h2 = __commonJS({
|
|
|
11107
11107
|
}
|
|
11108
11108
|
headers[HTTP2_HEADER_METHOD] = "CONNECT";
|
|
11109
11109
|
headers[HTTP2_HEADER_PROTOCOL] = "websocket";
|
|
11110
|
-
headers[HTTP2_HEADER_PATH] =
|
|
11110
|
+
headers[HTTP2_HEADER_PATH] = path10;
|
|
11111
11111
|
if (protocol === "ws:" || protocol === "wss:") {
|
|
11112
11112
|
headers[HTTP2_HEADER_SCHEME] = protocol === "ws:" ? "http" : "https";
|
|
11113
11113
|
} else {
|
|
@@ -11148,7 +11148,7 @@ var require_client_h2 = __commonJS({
|
|
|
11148
11148
|
stream.setTimeout(requestTimeout);
|
|
11149
11149
|
return true;
|
|
11150
11150
|
}
|
|
11151
|
-
headers[HTTP2_HEADER_PATH] =
|
|
11151
|
+
headers[HTTP2_HEADER_PATH] = path10;
|
|
11152
11152
|
headers[HTTP2_HEADER_SCHEME] = protocol === "http:" ? "http" : "https";
|
|
11153
11153
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
|
|
11154
11154
|
if (body && typeof body.read === "function") {
|
|
@@ -13461,10 +13461,10 @@ var require_proxy_agent = __commonJS({
|
|
|
13461
13461
|
};
|
|
13462
13462
|
const {
|
|
13463
13463
|
origin,
|
|
13464
|
-
path:
|
|
13464
|
+
path: path10 = "/",
|
|
13465
13465
|
headers = {}
|
|
13466
13466
|
} = opts;
|
|
13467
|
-
opts.path = origin +
|
|
13467
|
+
opts.path = origin + path10;
|
|
13468
13468
|
if (!("host" in headers) && !("Host" in headers)) {
|
|
13469
13469
|
const { host } = new URL(origin);
|
|
13470
13470
|
headers.host = host;
|
|
@@ -15542,20 +15542,20 @@ var require_mock_utils = __commonJS({
|
|
|
15542
15542
|
}
|
|
15543
15543
|
return normalizedQp;
|
|
15544
15544
|
}
|
|
15545
|
-
function
|
|
15546
|
-
if (typeof
|
|
15547
|
-
return
|
|
15545
|
+
function safeUrl3(path10) {
|
|
15546
|
+
if (typeof path10 !== "string") {
|
|
15547
|
+
return path10;
|
|
15548
15548
|
}
|
|
15549
|
-
const pathSegments =
|
|
15549
|
+
const pathSegments = path10.split("?", 3);
|
|
15550
15550
|
if (pathSegments.length !== 2) {
|
|
15551
|
-
return
|
|
15551
|
+
return path10;
|
|
15552
15552
|
}
|
|
15553
15553
|
const qp = new URLSearchParams(pathSegments.pop());
|
|
15554
15554
|
qp.sort();
|
|
15555
15555
|
return [...pathSegments, qp.toString()].join("?");
|
|
15556
15556
|
}
|
|
15557
|
-
function matchKey(mockDispatch2, { path:
|
|
15558
|
-
const pathMatch = matchValue(mockDispatch2.path,
|
|
15557
|
+
function matchKey(mockDispatch2, { path: path10, method, body, headers }) {
|
|
15558
|
+
const pathMatch = matchValue(mockDispatch2.path, path10);
|
|
15559
15559
|
const methodMatch = matchValue(mockDispatch2.method, method);
|
|
15560
15560
|
const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body) : true;
|
|
15561
15561
|
const headersMatch = matchHeaders(mockDispatch2, headers);
|
|
@@ -15578,10 +15578,10 @@ var require_mock_utils = __commonJS({
|
|
|
15578
15578
|
}
|
|
15579
15579
|
function getMockDispatch(mockDispatches, key) {
|
|
15580
15580
|
const basePath = key.query ? serializePathWithQuery(key.path, key.query) : key.path;
|
|
15581
|
-
const resolvedPath = typeof basePath === "string" ?
|
|
15581
|
+
const resolvedPath = typeof basePath === "string" ? safeUrl3(basePath) : basePath;
|
|
15582
15582
|
const resolvedPathWithoutTrailingSlash = removeTrailingSlash(resolvedPath);
|
|
15583
|
-
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path:
|
|
15584
|
-
return ignoreTrailingSlash ? matchValue(removeTrailingSlash(
|
|
15583
|
+
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path10, ignoreTrailingSlash }) => {
|
|
15584
|
+
return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl3(path10)), resolvedPathWithoutTrailingSlash) : matchValue(safeUrl3(path10), resolvedPath);
|
|
15585
15585
|
});
|
|
15586
15586
|
if (matchedMockDispatches.length === 0) {
|
|
15587
15587
|
throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
|
|
@@ -15620,19 +15620,19 @@ var require_mock_utils = __commonJS({
|
|
|
15620
15620
|
mockDispatches.splice(index, 1);
|
|
15621
15621
|
}
|
|
15622
15622
|
}
|
|
15623
|
-
function removeTrailingSlash(
|
|
15624
|
-
while (
|
|
15625
|
-
|
|
15623
|
+
function removeTrailingSlash(path10) {
|
|
15624
|
+
while (path10.endsWith("/")) {
|
|
15625
|
+
path10 = path10.slice(0, -1);
|
|
15626
15626
|
}
|
|
15627
|
-
if (
|
|
15628
|
-
|
|
15627
|
+
if (path10.length === 0) {
|
|
15628
|
+
path10 = "/";
|
|
15629
15629
|
}
|
|
15630
|
-
return
|
|
15630
|
+
return path10;
|
|
15631
15631
|
}
|
|
15632
15632
|
function buildKey(opts) {
|
|
15633
|
-
const { path:
|
|
15633
|
+
const { path: path10, method, body, headers, query } = opts;
|
|
15634
15634
|
return {
|
|
15635
|
-
path:
|
|
15635
|
+
path: path10,
|
|
15636
15636
|
method,
|
|
15637
15637
|
body,
|
|
15638
15638
|
headers,
|
|
@@ -16327,10 +16327,10 @@ var require_pending_interceptors_formatter = __commonJS({
|
|
|
16327
16327
|
}
|
|
16328
16328
|
format(pendingInterceptors) {
|
|
16329
16329
|
const withPrettyHeaders = pendingInterceptors.map(
|
|
16330
|
-
({ method, path:
|
|
16330
|
+
({ method, path: path10, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
|
|
16331
16331
|
Method: method,
|
|
16332
16332
|
Origin: origin,
|
|
16333
|
-
Path:
|
|
16333
|
+
Path: path10,
|
|
16334
16334
|
"Status code": statusCode,
|
|
16335
16335
|
Persistent: persist ? PERSISTENT : NOT_PERSISTENT,
|
|
16336
16336
|
Invocations: timesInvoked,
|
|
@@ -16413,9 +16413,9 @@ var require_mock_agent = __commonJS({
|
|
|
16413
16413
|
const acceptNonStandardSearchParameters = this[kMockAgentAcceptsNonStandardSearchParameters];
|
|
16414
16414
|
const dispatchOpts = { ...opts };
|
|
16415
16415
|
if (acceptNonStandardSearchParameters && dispatchOpts.path) {
|
|
16416
|
-
const [
|
|
16416
|
+
const [path10, searchParams] = dispatchOpts.path.split("?");
|
|
16417
16417
|
const normalizedSearchParams = normalizeSearchParams(searchParams, acceptNonStandardSearchParameters);
|
|
16418
|
-
dispatchOpts.path = `${
|
|
16418
|
+
dispatchOpts.path = `${path10}?${normalizedSearchParams}`;
|
|
16419
16419
|
}
|
|
16420
16420
|
return this[kAgent].dispatch(dispatchOpts, handler);
|
|
16421
16421
|
}
|
|
@@ -16818,12 +16818,12 @@ var require_snapshot_recorder = __commonJS({
|
|
|
16818
16818
|
* @return {Promise<void>} - Resolves when snapshots are loaded
|
|
16819
16819
|
*/
|
|
16820
16820
|
async loadSnapshots(filePath) {
|
|
16821
|
-
const
|
|
16822
|
-
if (!
|
|
16821
|
+
const path10 = filePath || this.#snapshotPath;
|
|
16822
|
+
if (!path10) {
|
|
16823
16823
|
throw new InvalidArgumentError2("Snapshot path is required");
|
|
16824
16824
|
}
|
|
16825
16825
|
try {
|
|
16826
|
-
const data = await readFile2(resolve(
|
|
16826
|
+
const data = await readFile2(resolve(path10), "utf8");
|
|
16827
16827
|
const parsed = JSON.parse(data);
|
|
16828
16828
|
if (Array.isArray(parsed)) {
|
|
16829
16829
|
this.#snapshots.clear();
|
|
@@ -16837,7 +16837,7 @@ var require_snapshot_recorder = __commonJS({
|
|
|
16837
16837
|
if (error48.code === "ENOENT") {
|
|
16838
16838
|
this.#snapshots.clear();
|
|
16839
16839
|
} else {
|
|
16840
|
-
throw new UndiciError(`Failed to load snapshots from ${
|
|
16840
|
+
throw new UndiciError(`Failed to load snapshots from ${path10}`, { cause: error48 });
|
|
16841
16841
|
}
|
|
16842
16842
|
}
|
|
16843
16843
|
}
|
|
@@ -16848,11 +16848,11 @@ var require_snapshot_recorder = __commonJS({
|
|
|
16848
16848
|
* @returns {Promise<void>} - Resolves when snapshots are saved
|
|
16849
16849
|
*/
|
|
16850
16850
|
async saveSnapshots(filePath) {
|
|
16851
|
-
const
|
|
16852
|
-
if (!
|
|
16851
|
+
const path10 = filePath || this.#snapshotPath;
|
|
16852
|
+
if (!path10) {
|
|
16853
16853
|
throw new InvalidArgumentError2("Snapshot path is required");
|
|
16854
16854
|
}
|
|
16855
|
-
const resolvedPath = resolve(
|
|
16855
|
+
const resolvedPath = resolve(path10);
|
|
16856
16856
|
await mkdir2(dirname(resolvedPath), { recursive: true });
|
|
16857
16857
|
const data = Array.from(this.#snapshots.entries()).map(([hash2, snapshot]) => ({
|
|
16858
16858
|
hash: hash2,
|
|
@@ -17481,15 +17481,15 @@ var require_redirect_handler = __commonJS({
|
|
|
17481
17481
|
return;
|
|
17482
17482
|
}
|
|
17483
17483
|
const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)));
|
|
17484
|
-
const
|
|
17485
|
-
const redirectUrlString = `${origin}${
|
|
17484
|
+
const path10 = search ? `${pathname}${search}` : pathname;
|
|
17485
|
+
const redirectUrlString = `${origin}${path10}`;
|
|
17486
17486
|
for (const historyUrl of this.history) {
|
|
17487
17487
|
if (historyUrl.toString() === redirectUrlString) {
|
|
17488
17488
|
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.`);
|
|
17489
17489
|
}
|
|
17490
17490
|
}
|
|
17491
17491
|
this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin);
|
|
17492
|
-
this.opts.path =
|
|
17492
|
+
this.opts.path = path10;
|
|
17493
17493
|
this.opts.origin = origin;
|
|
17494
17494
|
this.opts.query = null;
|
|
17495
17495
|
}
|
|
@@ -23716,11 +23716,11 @@ var require_fetch = __commonJS({
|
|
|
23716
23716
|
function dispatch({ body }) {
|
|
23717
23717
|
const url2 = requestCurrentURL(request);
|
|
23718
23718
|
const agent = fetchParams.controller.dispatcher;
|
|
23719
|
-
const
|
|
23719
|
+
const path10 = url2.pathname + url2.search;
|
|
23720
23720
|
const hasTrailingQuestionMark = url2.search.length === 0 && url2.href[url2.href.length - url2.hash.length - 1] === "?";
|
|
23721
23721
|
return new Promise((resolve, reject) => agent.dispatch(
|
|
23722
23722
|
{
|
|
23723
|
-
path: hasTrailingQuestionMark ? `${
|
|
23723
|
+
path: hasTrailingQuestionMark ? `${path10}?` : path10,
|
|
23724
23724
|
origin: url2.origin,
|
|
23725
23725
|
method: request.method,
|
|
23726
23726
|
body: agent.isMockActive ? request.body && (request.body.source || request.body.stream) : body,
|
|
@@ -24672,9 +24672,9 @@ var require_util4 = __commonJS({
|
|
|
24672
24672
|
}
|
|
24673
24673
|
}
|
|
24674
24674
|
}
|
|
24675
|
-
function validateCookiePath(
|
|
24676
|
-
for (let i = 0; i <
|
|
24677
|
-
const code =
|
|
24675
|
+
function validateCookiePath(path10) {
|
|
24676
|
+
for (let i = 0; i < path10.length; ++i) {
|
|
24677
|
+
const code = path10.charCodeAt(i);
|
|
24678
24678
|
if (code < 32 || // exclude CTLs (0-31)
|
|
24679
24679
|
code === 127 || // DEL
|
|
24680
24680
|
code === 59) {
|
|
@@ -27861,11 +27861,11 @@ var require_undici = __commonJS({
|
|
|
27861
27861
|
if (typeof opts.path !== "string") {
|
|
27862
27862
|
throw new InvalidArgumentError2("invalid opts.path");
|
|
27863
27863
|
}
|
|
27864
|
-
let
|
|
27864
|
+
let path10 = opts.path;
|
|
27865
27865
|
if (!opts.path.startsWith("/")) {
|
|
27866
|
-
|
|
27866
|
+
path10 = `/${path10}`;
|
|
27867
27867
|
}
|
|
27868
|
-
url2 = new URL(util.parseOrigin(url2).origin +
|
|
27868
|
+
url2 = new URL(util.parseOrigin(url2).origin + path10);
|
|
27869
27869
|
} else {
|
|
27870
27870
|
if (!opts) {
|
|
27871
27871
|
opts = typeof url2 === "object" ? url2 : {};
|
|
@@ -29564,10 +29564,10 @@ function mergeDefs(...defs) {
|
|
|
29564
29564
|
function cloneDef(schema) {
|
|
29565
29565
|
return mergeDefs(schema._zod.def);
|
|
29566
29566
|
}
|
|
29567
|
-
function getElementAtPath(obj,
|
|
29568
|
-
if (!
|
|
29567
|
+
function getElementAtPath(obj, path10) {
|
|
29568
|
+
if (!path10)
|
|
29569
29569
|
return obj;
|
|
29570
|
-
return
|
|
29570
|
+
return path10.reduce((acc, key) => acc?.[key], obj);
|
|
29571
29571
|
}
|
|
29572
29572
|
function promiseAllObject(promisesObj) {
|
|
29573
29573
|
const keys = Object.keys(promisesObj);
|
|
@@ -29950,11 +29950,11 @@ function aborted(x, startIndex = 0) {
|
|
|
29950
29950
|
}
|
|
29951
29951
|
return false;
|
|
29952
29952
|
}
|
|
29953
|
-
function prefixIssues(
|
|
29953
|
+
function prefixIssues(path10, issues) {
|
|
29954
29954
|
return issues.map((iss) => {
|
|
29955
29955
|
var _a2;
|
|
29956
29956
|
(_a2 = iss).path ?? (_a2.path = []);
|
|
29957
|
-
iss.path.unshift(
|
|
29957
|
+
iss.path.unshift(path10);
|
|
29958
29958
|
return iss;
|
|
29959
29959
|
});
|
|
29960
29960
|
}
|
|
@@ -30137,7 +30137,7 @@ function formatError(error48, mapper = (issue2) => issue2.message) {
|
|
|
30137
30137
|
}
|
|
30138
30138
|
function treeifyError(error48, mapper = (issue2) => issue2.message) {
|
|
30139
30139
|
const result2 = { errors: [] };
|
|
30140
|
-
const processError = (error49,
|
|
30140
|
+
const processError = (error49, path10 = []) => {
|
|
30141
30141
|
var _a2, _b;
|
|
30142
30142
|
for (const issue2 of error49.issues) {
|
|
30143
30143
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
@@ -30147,7 +30147,7 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
|
|
|
30147
30147
|
} else if (issue2.code === "invalid_element") {
|
|
30148
30148
|
processError({ issues: issue2.issues }, issue2.path);
|
|
30149
30149
|
} else {
|
|
30150
|
-
const fullpath = [...
|
|
30150
|
+
const fullpath = [...path10, ...issue2.path];
|
|
30151
30151
|
if (fullpath.length === 0) {
|
|
30152
30152
|
result2.errors.push(mapper(issue2));
|
|
30153
30153
|
continue;
|
|
@@ -30179,8 +30179,8 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
|
|
|
30179
30179
|
}
|
|
30180
30180
|
function toDotPath(_path) {
|
|
30181
30181
|
const segs = [];
|
|
30182
|
-
const
|
|
30183
|
-
for (const seg of
|
|
30182
|
+
const path10 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
30183
|
+
for (const seg of path10) {
|
|
30184
30184
|
if (typeof seg === "number")
|
|
30185
30185
|
segs.push(`[${seg}]`);
|
|
30186
30186
|
else if (typeof seg === "symbol")
|
|
@@ -42235,13 +42235,13 @@ function resolveRef(ref, ctx) {
|
|
|
42235
42235
|
if (!ref.startsWith("#")) {
|
|
42236
42236
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
42237
42237
|
}
|
|
42238
|
-
const
|
|
42239
|
-
if (
|
|
42238
|
+
const path10 = ref.slice(1).split("/").filter(Boolean);
|
|
42239
|
+
if (path10.length === 0) {
|
|
42240
42240
|
return ctx.rootSchema;
|
|
42241
42241
|
}
|
|
42242
42242
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
42243
|
-
if (
|
|
42244
|
-
const key =
|
|
42243
|
+
if (path10[0] === defsKey) {
|
|
42244
|
+
const key = path10[1];
|
|
42245
42245
|
if (!key || !ctx.defs[key]) {
|
|
42246
42246
|
throw new Error(`Reference not found: ${ref}`);
|
|
42247
42247
|
}
|
|
@@ -43144,7 +43144,12 @@ var agentApiIntegrationLoginResponseSchema = passthroughObject({
|
|
|
43144
43144
|
status: external_exports.enum(["logged_in", "already_logged_in", "approval_required"]),
|
|
43145
43145
|
service: agentApiIntegrationServiceSchema,
|
|
43146
43146
|
scopes: external_exports.array(external_exports.string()),
|
|
43147
|
-
requestId: external_exports.string(),
|
|
43147
|
+
requestId: external_exports.string().optional(),
|
|
43148
|
+
session: passthroughObject({
|
|
43149
|
+
status: external_exports.literal("stored"),
|
|
43150
|
+
source: external_exports.enum(["cache", "fresh"]),
|
|
43151
|
+
path: nullableStringSchema
|
|
43152
|
+
}).optional(),
|
|
43148
43153
|
approval: passthroughObject({
|
|
43149
43154
|
requestId: external_exports.string(),
|
|
43150
43155
|
target: nullableStringSchema,
|
|
@@ -43902,11 +43907,11 @@ function isAgentApiRawFailure(value) {
|
|
|
43902
43907
|
);
|
|
43903
43908
|
}
|
|
43904
43909
|
function buildAgentApiRawRoutePath(routeKey, options = {}) {
|
|
43905
|
-
let
|
|
43910
|
+
let path10;
|
|
43906
43911
|
try {
|
|
43907
43912
|
const encodedPath = encodePathParams(routeKey, options.params);
|
|
43908
43913
|
if (typeof encodedPath !== "string") return encodedPath;
|
|
43909
|
-
|
|
43914
|
+
path10 = encodedPath;
|
|
43910
43915
|
} catch (cause) {
|
|
43911
43916
|
if (cause instanceof MissingPathParamError) {
|
|
43912
43917
|
return failure(routeKey, "missing_path_param", cause.message, { cause });
|
|
@@ -43916,12 +43921,12 @@ function buildAgentApiRawRoutePath(routeKey, options = {}) {
|
|
|
43916
43921
|
const query = encodeQuery(routeKey, options.query);
|
|
43917
43922
|
if (query && !(query instanceof URLSearchParams)) return query;
|
|
43918
43923
|
const suffix = query && query.size > 0 ? `?${query.toString()}` : "";
|
|
43919
|
-
return `${options.pathPrefix ?? AGENT_API_BASE_PATH}${
|
|
43924
|
+
return `${options.pathPrefix ?? AGENT_API_BASE_PATH}${path10}${suffix}`;
|
|
43920
43925
|
}
|
|
43921
43926
|
async function requestAgentApiRawRoute(transport, routeKey, options = {}) {
|
|
43922
43927
|
const route3 = agentApiContract[routeKey];
|
|
43923
|
-
const
|
|
43924
|
-
if (typeof
|
|
43928
|
+
const path10 = buildAgentApiRawRoutePath(routeKey, options);
|
|
43929
|
+
if (typeof path10 !== "string") return path10;
|
|
43925
43930
|
const body = parseBody(routeKey, options.body);
|
|
43926
43931
|
if (isAgentApiRawFailure(body)) return body;
|
|
43927
43932
|
let response;
|
|
@@ -43929,7 +43934,7 @@ async function requestAgentApiRawRoute(transport, routeKey, options = {}) {
|
|
|
43929
43934
|
response = await transport.request({
|
|
43930
43935
|
routeKey,
|
|
43931
43936
|
method: route3.method,
|
|
43932
|
-
path:
|
|
43937
|
+
path: path10,
|
|
43933
43938
|
body
|
|
43934
43939
|
});
|
|
43935
43940
|
} catch (cause) {
|
|
@@ -44321,8 +44326,8 @@ function buildDaemonApiRawRoutePath(routeKey, options = {}) {
|
|
|
44321
44326
|
}
|
|
44322
44327
|
async function requestDaemonApiRawRoute(transport, routeKey, options = {}) {
|
|
44323
44328
|
const route3 = daemonApiContract[routeKey];
|
|
44324
|
-
const
|
|
44325
|
-
if (typeof
|
|
44329
|
+
const path10 = buildDaemonApiRawRoutePath(routeKey, options);
|
|
44330
|
+
if (typeof path10 !== "string") return path10;
|
|
44326
44331
|
const body = parseBody2(routeKey, options.body);
|
|
44327
44332
|
if (isDaemonApiRawFailure(body)) return body;
|
|
44328
44333
|
let response;
|
|
@@ -44330,7 +44335,7 @@ async function requestDaemonApiRawRoute(transport, routeKey, options = {}) {
|
|
|
44330
44335
|
response = await transport.request({
|
|
44331
44336
|
routeKey,
|
|
44332
44337
|
method: route3.method,
|
|
44333
|
-
path:
|
|
44338
|
+
path: path10,
|
|
44334
44339
|
body
|
|
44335
44340
|
});
|
|
44336
44341
|
} catch (cause) {
|
|
@@ -45086,15 +45091,17 @@ var DISPLAY_PLAN_CONFIG = {
|
|
|
45086
45091
|
}
|
|
45087
45092
|
};
|
|
45088
45093
|
var FREE_MONTHLY_FILE_UPLOAD_LIMIT_BYTES = 100 * 1024 * 1024;
|
|
45094
|
+
var FREE_SINGLE_FILE_UPLOAD_LIMIT_BYTES = 50 * 1024 * 1024;
|
|
45095
|
+
var PRO_SINGLE_FILE_UPLOAD_LIMIT_BYTES = 200 * 1024 * 1024;
|
|
45089
45096
|
var TRIAL_START_DATE = /* @__PURE__ */ new Date("2026-04-18T00:00:00Z");
|
|
45090
45097
|
var TRIAL_END_DATE = /* @__PURE__ */ new Date("2026-06-23T12:00:00Z");
|
|
45091
45098
|
var TRIAL_DURATION_DAYS = (TRIAL_END_DATE.getTime() - TRIAL_START_DATE.getTime()) / (24 * 60 * 60 * 1e3);
|
|
45092
45099
|
|
|
45093
45100
|
// src/agentApiPath.ts
|
|
45094
45101
|
function buildAgentApiRoutePath(routeKey, pathParams, query) {
|
|
45095
|
-
const
|
|
45096
|
-
if (typeof
|
|
45097
|
-
throw cliErrorFromRawFailure(
|
|
45102
|
+
const path10 = buildAgentApiRawRoutePath(routeKey, { params: pathParams, query });
|
|
45103
|
+
if (typeof path10 === "string") return path10;
|
|
45104
|
+
throw cliErrorFromRawFailure(path10);
|
|
45098
45105
|
}
|
|
45099
45106
|
function buildAgentApiEventsPath(query) {
|
|
45100
45107
|
return buildAgentApiRoutePath("events", void 0, query);
|
|
@@ -45873,7 +45880,7 @@ function loadAgentContext(env = process.env) {
|
|
|
45873
45880
|
const shadowed = RAW_AGENT_ENV_KEYS.filter((k) => env[k]);
|
|
45874
45881
|
if (shadowed.length > 0) {
|
|
45875
45882
|
process.stderr.write(
|
|
45876
|
-
`
|
|
45883
|
+
`raft: RAFT_PROFILE=${profileSlug} active; ignoring ${shadowed.join(", ")} from env.
|
|
45877
45884
|
`
|
|
45878
45885
|
);
|
|
45879
45886
|
}
|
|
@@ -45955,17 +45962,17 @@ function bootstrapSuggestedNextAction(code) {
|
|
|
45955
45962
|
case "MISSING_AGENT_ID":
|
|
45956
45963
|
case "MISSING_SERVER_URL":
|
|
45957
45964
|
case "MISSING_TOKEN":
|
|
45958
|
-
return "Use a
|
|
45965
|
+
return "Use a Raft profile with `raft --profile <slug> ...`; create one with `raft agent login --server <server-url> --agent <agent-id> --profile-slug <slug>`.";
|
|
45959
45966
|
case "PROFILE_FILE_UNREADABLE":
|
|
45960
45967
|
case "PROFILE_FILE_INVALID":
|
|
45961
|
-
return "Check the selected
|
|
45968
|
+
return "Check the selected Raft profile, or recreate it with `raft agent login --server <server-url> --agent <agent-id> --profile-slug <slug>`.";
|
|
45962
45969
|
case "TOKEN_FILE_UNREADABLE":
|
|
45963
45970
|
case "TOKEN_FILE_EMPTY":
|
|
45964
|
-
return "Check the daemon-injected token file, or restart the
|
|
45971
|
+
return "Check the daemon-injected token file, or restart the Raft daemon so it can inject a fresh credential.";
|
|
45965
45972
|
case "MISSING_AGENT_PROXY_URL":
|
|
45966
45973
|
case "MISSING_AGENT_PROXY_TOKEN":
|
|
45967
45974
|
case "MULTIPLE_AGENT_PROXY_TOKENS":
|
|
45968
|
-
return "Restart the
|
|
45975
|
+
return "Restart the Raft daemon so it can inject a complete local proxy environment, or remove the partial proxy env vars before retrying.";
|
|
45969
45976
|
default:
|
|
45970
45977
|
return void 0;
|
|
45971
45978
|
}
|
|
@@ -46089,7 +46096,7 @@ var DeviceCodeLoginError = class extends Error {
|
|
|
46089
46096
|
}
|
|
46090
46097
|
};
|
|
46091
46098
|
var ACTIONABLE_ERROR_MESSAGES = {
|
|
46092
|
-
device_login_disabled: "Device login is not enabled on this
|
|
46099
|
+
device_login_disabled: "Device login is not enabled on this Raft server. Ask an admin to set SLOCK_DEVICE_LOGIN_ENABLED=true.",
|
|
46093
46100
|
device_code_required: "Internal CLI bug: device_code was missing from the poll request.",
|
|
46094
46101
|
user_code_required: "Internal CLI bug: user_code was missing from the approve request.",
|
|
46095
46102
|
authorization_pending: "Still waiting for you to approve the login on the web page.",
|
|
@@ -46278,9 +46285,9 @@ function describeListResult(reason, serverUrl) {
|
|
|
46278
46285
|
var agentListCommand = defineCommand(
|
|
46279
46286
|
{
|
|
46280
46287
|
name: "list",
|
|
46281
|
-
description: "List
|
|
46288
|
+
description: "List Raft agents the user can mint credentials for (after a device-code login).",
|
|
46282
46289
|
options: [
|
|
46283
|
-
{ flags: "--server <url>", description: "
|
|
46290
|
+
{ flags: "--server <url>", description: "Raft server base URL, e.g. https://app.raft.build" },
|
|
46284
46291
|
{ flags: "--client-name <label>", description: "Human-readable label shown on the web approval page" }
|
|
46285
46292
|
]
|
|
46286
46293
|
},
|
|
@@ -46366,7 +46373,7 @@ import path4 from "path";
|
|
|
46366
46373
|
var WAIT_MAX_POLL_MS = 15 * 60 * 1e3;
|
|
46367
46374
|
var SERVER_OPTION = {
|
|
46368
46375
|
flags: "--server <url>",
|
|
46369
|
-
description: "
|
|
46376
|
+
description: "Raft server base URL, e.g. https://app.raft.build"
|
|
46370
46377
|
};
|
|
46371
46378
|
var AGENT_OPTION = {
|
|
46372
46379
|
flags: "--agent <agentId>",
|
|
@@ -46382,7 +46389,7 @@ var PROFILE_SLUG_OPTION = {
|
|
|
46382
46389
|
};
|
|
46383
46390
|
var PROFILE_DIR_OPTION = {
|
|
46384
46391
|
flags: "--profile-dir <path>",
|
|
46385
|
-
description: "Override the profile directory root (default resolution
|
|
46392
|
+
description: "Override the profile directory root (default resolution uses the managed Raft home when present, otherwise the local profile store)"
|
|
46386
46393
|
};
|
|
46387
46394
|
var DEVICE_CODE_OPTION = {
|
|
46388
46395
|
flags: "--device-code <code>",
|
|
@@ -46397,7 +46404,7 @@ function mergeParentLoginOpts(options, command) {
|
|
|
46397
46404
|
var agentLoginCommand = defineCommand(
|
|
46398
46405
|
{
|
|
46399
46406
|
name: "login",
|
|
46400
|
-
description: "Sign this CLI in as a specific
|
|
46407
|
+
description: "Sign this CLI in as a specific Raft agent via the device-code login grant.",
|
|
46401
46408
|
options: [
|
|
46402
46409
|
SERVER_OPTION,
|
|
46403
46410
|
AGENT_OPTION,
|
|
@@ -47619,7 +47626,7 @@ function createRaftChannelWakeAdapter(options = {}) {
|
|
|
47619
47626
|
if (!options.endpointUrl) {
|
|
47620
47627
|
return buildRaftChannelWakeFailedEvent(input, {
|
|
47621
47628
|
failureClass: "no_session",
|
|
47622
|
-
reason: "Claude Code
|
|
47629
|
+
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."
|
|
47623
47630
|
});
|
|
47624
47631
|
}
|
|
47625
47632
|
const request = options.fetchImpl ?? fetch;
|
|
@@ -47646,14 +47653,14 @@ function createRaftChannelWakeAdapter(options = {}) {
|
|
|
47646
47653
|
} catch (err) {
|
|
47647
47654
|
return buildRaftChannelWakeFailedEvent(input, {
|
|
47648
47655
|
failureClass: "no_session",
|
|
47649
|
-
reason: err instanceof Error && err.message ? `Claude Code
|
|
47656
|
+
reason: err instanceof Error && err.message ? `Claude Code Raft channel plugin endpoint is unreachable: ${err.message}` : "Claude Code Raft channel plugin endpoint is unreachable"
|
|
47650
47657
|
});
|
|
47651
47658
|
}
|
|
47652
47659
|
const body = await parseWakeResponse(response);
|
|
47653
47660
|
if (!response.ok || body.ok === false) {
|
|
47654
47661
|
return buildRaftChannelWakeFailedEvent(input, {
|
|
47655
47662
|
failureClass: body.failureClass ?? statusFailureClass(response.status),
|
|
47656
|
-
reason: body.reason ?? `Claude Code
|
|
47663
|
+
reason: body.reason ?? `Claude Code Raft channel plugin rejected wake attempt with HTTP ${response.status}`,
|
|
47657
47664
|
...typeof body.retryAfterMs === "number" ? { retryAfterMs: body.retryAfterMs } : {}
|
|
47658
47665
|
});
|
|
47659
47666
|
}
|
|
@@ -47661,7 +47668,7 @@ function createRaftChannelWakeAdapter(options = {}) {
|
|
|
47661
47668
|
if (!runtimeSession) {
|
|
47662
47669
|
return buildRaftChannelWakeFailedEvent(input, {
|
|
47663
47670
|
failureClass: "protocol_mismatch",
|
|
47664
|
-
reason: "Claude Code
|
|
47671
|
+
reason: "Claude Code Raft channel plugin accepted wake but did not return runtimeSession"
|
|
47665
47672
|
});
|
|
47666
47673
|
}
|
|
47667
47674
|
return buildRaftChannelWakeInjectedEvent({
|
|
@@ -48173,7 +48180,7 @@ function sleep(ms) {
|
|
|
48173
48180
|
|
|
48174
48181
|
// src/commands/action/prepare.ts
|
|
48175
48182
|
init_esm_shims();
|
|
48176
|
-
var ACTION_HEREDOC_DELIMITER = "
|
|
48183
|
+
var ACTION_HEREDOC_DELIMITER = "RAFTACTION";
|
|
48177
48184
|
var PrepareActionInputError = class extends Error {
|
|
48178
48185
|
constructor(code, message) {
|
|
48179
48186
|
super(message);
|
|
@@ -48192,8 +48199,8 @@ async function readStream(stream) {
|
|
|
48192
48199
|
function missingActionMessage() {
|
|
48193
48200
|
return [
|
|
48194
48201
|
"No action JSON received on stdin.",
|
|
48195
|
-
"Pipe a JSON ActionCardAction object (channel:create / agent:create / channel:add_member) into
|
|
48196
|
-
`
|
|
48202
|
+
"Pipe a JSON ActionCardAction object (channel:create / agent:create / channel:add_member) into raft action prepare:",
|
|
48203
|
+
` raft action prepare --target "#channel" <<'${ACTION_HEREDOC_DELIMITER}'`,
|
|
48197
48204
|
' {"type":"channel:create","name":"demo","visibility":"public"}',
|
|
48198
48205
|
` ${ACTION_HEREDOC_DELIMITER}`
|
|
48199
48206
|
].join("\n");
|
|
@@ -48352,7 +48359,7 @@ function formatServerInfo(data) {
|
|
|
48352
48359
|
text += " (none)\n";
|
|
48353
48360
|
}
|
|
48354
48361
|
text += "\n### Humans\n";
|
|
48355
|
-
text += `To start a new DM: raft message send --target "dm:@name" <<'
|
|
48362
|
+
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.
|
|
48356
48363
|
`;
|
|
48357
48364
|
text += "Role labels show server-level owner/admin authority; no role label means ordinary member.\n";
|
|
48358
48365
|
if (humans.length > 0) {
|
|
@@ -48935,10 +48942,24 @@ function makeChannelMuteCommand(action) {
|
|
|
48935
48942
|
{
|
|
48936
48943
|
name: action,
|
|
48937
48944
|
description: action === "mute" ? "Mute ordinary Activity delivery for a regular channel" : "Unmute ordinary Activity delivery for a regular channel",
|
|
48938
|
-
arguments: ["
|
|
48945
|
+
arguments: ["[target]"],
|
|
48946
|
+
options: [
|
|
48947
|
+
{
|
|
48948
|
+
flags: "--target <target>",
|
|
48949
|
+
description: `Regular channel to ${action}, e.g. '#engineering'`
|
|
48950
|
+
}
|
|
48951
|
+
]
|
|
48939
48952
|
},
|
|
48940
|
-
async (ctx, targetArg) => {
|
|
48941
|
-
const
|
|
48953
|
+
async (ctx, targetArg, opts = {}) => {
|
|
48954
|
+
const positionalTarget = targetArg?.trim();
|
|
48955
|
+
const flagTarget = opts.target?.trim();
|
|
48956
|
+
if (positionalTarget && flagTarget && positionalTarget !== flagTarget) {
|
|
48957
|
+
throw new CliError({
|
|
48958
|
+
code: "INVALID_ARG",
|
|
48959
|
+
message: "Positional target and --target must refer to the same channel when both are provided"
|
|
48960
|
+
});
|
|
48961
|
+
}
|
|
48962
|
+
const target = flagTarget || positionalTarget || "";
|
|
48942
48963
|
const channelName = parseRegularChannelTarget(target);
|
|
48943
48964
|
if (!channelName) {
|
|
48944
48965
|
throw new CliError({
|
|
@@ -49376,7 +49397,7 @@ function toKnowledgeErrorCode(errorCode2, status) {
|
|
|
49376
49397
|
var knowledgeGetCommand = defineCommand(
|
|
49377
49398
|
{
|
|
49378
49399
|
name: "get",
|
|
49379
|
-
description: "Fetch a
|
|
49400
|
+
description: "Fetch a Raft Manual for Agents topic from the current server",
|
|
49380
49401
|
arguments: ["<topic>"],
|
|
49381
49402
|
options: [
|
|
49382
49403
|
{
|
|
@@ -49441,7 +49462,7 @@ var inboxCheckCommand = defineCommand(
|
|
|
49441
49462
|
if (agentContext.clientMode !== "managed-runner") {
|
|
49442
49463
|
throw new CliError({
|
|
49443
49464
|
code: "INBOX_CHECK_FAILED",
|
|
49444
|
-
message: "`
|
|
49465
|
+
message: "`raft inbox check` is only available inside managed daemon runners.",
|
|
49445
49466
|
suggestedNextAction: "Use `raft message check` to drain messages."
|
|
49446
49467
|
});
|
|
49447
49468
|
}
|
|
@@ -49685,7 +49706,7 @@ function formatHistory(channel, data, opts) {
|
|
|
49685
49706
|
let header = `## Message History for ${channel}${opts?.around ? ` around ${opts.around}` : ""} (${data.messages.length} messages)`;
|
|
49686
49707
|
if ((data.last_read_seq ?? 0) > 0 && !opts?.after && !opts?.before && !opts?.around) {
|
|
49687
49708
|
header += `
|
|
49688
|
-
Your last read position: seq ${data.last_read_seq}. Use raft message read --
|
|
49709
|
+
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.`;
|
|
49689
49710
|
}
|
|
49690
49711
|
return `${header}
|
|
49691
49712
|
|
|
@@ -49873,7 +49894,7 @@ function normalizeAction(action) {
|
|
|
49873
49894
|
}
|
|
49874
49895
|
function formatActionCommands(action) {
|
|
49875
49896
|
const verbs = action.availableActions.map(normalizeAction).filter((verb) => verb !== null);
|
|
49876
|
-
return Array.from(new Set(verbs)).map((verb) => ` ${verb}:
|
|
49897
|
+
return Array.from(new Set(verbs)).map((verb) => ` ${verb}: raft mention ${verb} ${action.resolutionId}`);
|
|
49877
49898
|
}
|
|
49878
49899
|
function normalizePendingMentionActions(data) {
|
|
49879
49900
|
const value = data;
|
|
@@ -50010,7 +50031,7 @@ function clearSavedDraft(agentId, target) {
|
|
|
50010
50031
|
}
|
|
50011
50032
|
|
|
50012
50033
|
// src/commands/message/send.ts
|
|
50013
|
-
var MESSAGE_HEREDOC_DELIMITER = "
|
|
50034
|
+
var MESSAGE_HEREDOC_DELIMITER = "RAFTMSG";
|
|
50014
50035
|
var SendContentError = class extends Error {
|
|
50015
50036
|
constructor(code, message) {
|
|
50016
50037
|
super(message);
|
|
@@ -50347,6 +50368,32 @@ function registerCheckCommand(parent, runtimeOptions) {
|
|
|
50347
50368
|
|
|
50348
50369
|
// src/commands/message/read.ts
|
|
50349
50370
|
init_esm_shims();
|
|
50371
|
+
|
|
50372
|
+
// src/commands/_target.ts
|
|
50373
|
+
init_esm_shims();
|
|
50374
|
+
function resolveTargetAlias(opts) {
|
|
50375
|
+
const target = opts.target?.trim();
|
|
50376
|
+
const legacyChannel = opts.channel?.trim();
|
|
50377
|
+
if (target && legacyChannel && target !== legacyChannel) {
|
|
50378
|
+
throw new CliError({
|
|
50379
|
+
code: "INVALID_ARG",
|
|
50380
|
+
message: "--target and legacy --channel must refer to the same target when both are provided"
|
|
50381
|
+
});
|
|
50382
|
+
}
|
|
50383
|
+
return target || legacyChannel || void 0;
|
|
50384
|
+
}
|
|
50385
|
+
function requireTargetAlias(opts) {
|
|
50386
|
+
const target = resolveTargetAlias(opts);
|
|
50387
|
+
if (!target) {
|
|
50388
|
+
throw new CliError({
|
|
50389
|
+
code: "INVALID_ARG",
|
|
50390
|
+
message: "--target is required (legacy --channel is accepted during the transition)"
|
|
50391
|
+
});
|
|
50392
|
+
}
|
|
50393
|
+
return target;
|
|
50394
|
+
}
|
|
50395
|
+
|
|
50396
|
+
// src/commands/message/read.ts
|
|
50350
50397
|
function parsePositiveInt2(name, raw) {
|
|
50351
50398
|
if (raw === void 0) return void 0;
|
|
50352
50399
|
const n = Number(raw);
|
|
@@ -50385,13 +50432,7 @@ function mapReadFailure(res) {
|
|
|
50385
50432
|
});
|
|
50386
50433
|
}
|
|
50387
50434
|
function validateReadOpts(opts) {
|
|
50388
|
-
const channel = opts
|
|
50389
|
-
if (!channel) {
|
|
50390
|
-
throw new CliError({
|
|
50391
|
-
code: "INVALID_ARG",
|
|
50392
|
-
message: "--channel is required"
|
|
50393
|
-
});
|
|
50394
|
-
}
|
|
50435
|
+
const channel = requireTargetAlias(opts);
|
|
50395
50436
|
const limit = parsePositiveInt2("limit", opts.limit);
|
|
50396
50437
|
const before = opts.before?.trim();
|
|
50397
50438
|
const after = opts.after?.trim();
|
|
@@ -50408,10 +50449,11 @@ var messageReadCommand = defineCommand(
|
|
|
50408
50449
|
name: "read",
|
|
50409
50450
|
description: "Read message history for a channel, DM, or thread",
|
|
50410
50451
|
options: [
|
|
50411
|
-
{ flags: "--
|
|
50412
|
-
{ flags: "--
|
|
50413
|
-
{ flags: "--
|
|
50414
|
-
{ flags: "--
|
|
50452
|
+
{ flags: "--target <target>", description: "Target: '#channel', 'dm:@peer', '#channel:threadId', 'dm:@peer:threadId'" },
|
|
50453
|
+
{ flags: "--channel <target>", description: "Legacy alias for --target (accepted during transition)" },
|
|
50454
|
+
{ flags: "--before <idOrSeq>", description: "Return messages strictly before this full/short message id or seq anchor" },
|
|
50455
|
+
{ flags: "--after <idOrSeq>", description: "Return messages strictly after this full/short message id or seq anchor" },
|
|
50456
|
+
{ flags: "--around <idOrSeq>", description: "Center the window on this full/short message id or seq anchor" },
|
|
50415
50457
|
{ flags: "--limit <n>", description: "Max messages to return (server default applies if omitted)" }
|
|
50416
50458
|
]
|
|
50417
50459
|
},
|
|
@@ -50513,13 +50555,13 @@ function normalizeSearchOpts(opts) {
|
|
|
50513
50555
|
message: `--sort must be "relevance" or "recent"; got ${opts.sort}`
|
|
50514
50556
|
});
|
|
50515
50557
|
}
|
|
50516
|
-
const channel = opts
|
|
50558
|
+
const channel = resolveTargetAlias(opts);
|
|
50517
50559
|
const sender = opts.sender ? normalizeMemberHandleRef(opts.sender) : void 0;
|
|
50518
50560
|
const hasFilter = Boolean(channel || sender || opts.before || opts.after);
|
|
50519
50561
|
if (!query && !hasFilter) {
|
|
50520
50562
|
throw new CliError({
|
|
50521
50563
|
code: "INVALID_ARG",
|
|
50522
|
-
message: "--query is required unless --sender, --
|
|
50564
|
+
message: "--query is required unless --sender, --target, --before, or --after is provided"
|
|
50523
50565
|
});
|
|
50524
50566
|
}
|
|
50525
50567
|
if (!query && opts.sort === "relevance") {
|
|
@@ -50558,7 +50600,8 @@ var messageSearchCommand = defineCommand(
|
|
|
50558
50600
|
description: "Search messages across channels the agent can see",
|
|
50559
50601
|
options: [
|
|
50560
50602
|
{ flags: "--query <q>", description: "Search query string (optional when filters are provided)" },
|
|
50561
|
-
{ flags: "--
|
|
50603
|
+
{ flags: "--target <target>", description: "Restrict to a single channel/DM/thread" },
|
|
50604
|
+
{ flags: "--channel <target>", description: "Legacy alias for --target (accepted during transition)" },
|
|
50562
50605
|
{ flags: "--sender <handle>", description: "Restrict to messages by sender handle, e.g. @alice" },
|
|
50563
50606
|
{ flags: "--sort <mode>", description: "Sort results by relevance or recent (default: relevance; filter-only searches use recent)" },
|
|
50564
50607
|
{ flags: "--before <iso>", description: "Only messages before this ISO datetime" },
|
|
@@ -50807,9 +50850,10 @@ var attachmentUploadCommand = defineCommand(
|
|
|
50807
50850
|
options: [
|
|
50808
50851
|
{ flags: "--path <filepath>", description: "Absolute path to the local file to upload" },
|
|
50809
50852
|
{
|
|
50810
|
-
flags: "--
|
|
50853
|
+
flags: "--target <target>",
|
|
50811
50854
|
description: "Target where the attachment will be used: '#channel', 'dm:@peer', or thread variants. Required by the v0 server until channel-less uploads land."
|
|
50812
50855
|
},
|
|
50856
|
+
{ flags: "--channel <target>", description: "Legacy alias for --target (accepted during transition)" },
|
|
50813
50857
|
{ flags: "--mime-type <type>", description: "Explicit MIME type override, e.g. image/png" }
|
|
50814
50858
|
]
|
|
50815
50859
|
},
|
|
@@ -50830,10 +50874,11 @@ var attachmentUploadCommand = defineCommand(
|
|
|
50830
50874
|
if (err instanceof AttachmentUploadArgError) throw cliError(err.code, err.message, { cause: err });
|
|
50831
50875
|
throw err;
|
|
50832
50876
|
}
|
|
50833
|
-
|
|
50877
|
+
const target = resolveTargetAlias(opts);
|
|
50878
|
+
if (!target) {
|
|
50834
50879
|
throw cliError(
|
|
50835
50880
|
"MISSING_CHANNEL",
|
|
50836
|
-
"v0 server requires a
|
|
50881
|
+
"v0 server requires a target to attach the upload to. Pass --target '#name', 'dm:@peer', or a thread target."
|
|
50837
50882
|
);
|
|
50838
50883
|
}
|
|
50839
50884
|
const buffer = readFileSync3(opts.path);
|
|
@@ -50849,10 +50894,10 @@ var attachmentUploadCommand = defineCommand(
|
|
|
50849
50894
|
const agentContext = ctx.loadAgentContext();
|
|
50850
50895
|
const client = ctx.createApiClient(agentContext);
|
|
50851
50896
|
const agentApi = createAgentApiSurfaceClient(client);
|
|
50852
|
-
const resolved = await agentApi.channels.resolve({ target
|
|
50897
|
+
const resolved = await agentApi.channels.resolve({ target });
|
|
50853
50898
|
if (!resolved.ok || !resolved.data?.channelId) {
|
|
50854
50899
|
const code = resolved.status >= 500 ? "SERVER_5XX" : "RESOLVE_FAILED";
|
|
50855
|
-
throw cliError(code, resolved.error ?? `Could not resolve
|
|
50900
|
+
throw cliError(code, resolved.error ?? `Could not resolve target: ${target}`);
|
|
50856
50901
|
}
|
|
50857
50902
|
const channelId = resolved.data.channelId;
|
|
50858
50903
|
const blob = new Blob([buffer], { type: uploadMimeType });
|
|
@@ -50884,13 +50929,21 @@ function registerAttachmentUploadCommand(parent, runtimeOptions = {}) {
|
|
|
50884
50929
|
// src/commands/attachment/view.ts
|
|
50885
50930
|
init_esm_shims();
|
|
50886
50931
|
import { writeFileSync } from "fs";
|
|
50887
|
-
function validateViewOpts(opts) {
|
|
50888
|
-
const
|
|
50932
|
+
function validateViewOpts(positionalId, opts) {
|
|
50933
|
+
const positional = positionalId?.trim();
|
|
50934
|
+
const optionId = opts.id?.trim();
|
|
50935
|
+
if (positional && optionId) {
|
|
50936
|
+
throw new CliError({
|
|
50937
|
+
code: "INVALID_ARG",
|
|
50938
|
+
message: "pass the attachment id either positionally or with --id, not both"
|
|
50939
|
+
});
|
|
50940
|
+
}
|
|
50941
|
+
const id = positional || optionId;
|
|
50889
50942
|
const output = opts.output;
|
|
50890
50943
|
if (!id) {
|
|
50891
50944
|
throw new CliError({
|
|
50892
50945
|
code: "INVALID_ARG",
|
|
50893
|
-
message: "
|
|
50946
|
+
message: "attachment id is required (pass <attachmentId> or --id)"
|
|
50894
50947
|
});
|
|
50895
50948
|
}
|
|
50896
50949
|
if (!output) {
|
|
@@ -50905,13 +50958,16 @@ var attachmentViewCommand = defineCommand(
|
|
|
50905
50958
|
{
|
|
50906
50959
|
name: "view",
|
|
50907
50960
|
description: "Download an attachment by id and save it to a local path",
|
|
50961
|
+
arguments: ["[attachmentId]"],
|
|
50908
50962
|
options: [
|
|
50909
|
-
{ flags: "--id <attachmentId>", description: "Attachment UUID" },
|
|
50963
|
+
{ flags: "--id <attachmentId>", description: "Attachment UUID (transition alias; prefer positional <attachmentId>)" },
|
|
50910
50964
|
{ flags: "--output <path>", description: "Local path to write the file to" }
|
|
50911
50965
|
]
|
|
50912
50966
|
},
|
|
50913
|
-
async (ctx,
|
|
50914
|
-
const
|
|
50967
|
+
async (ctx, attachmentIdOrOpts, maybeOpts) => {
|
|
50968
|
+
const positionalId = typeof attachmentIdOrOpts === "string" ? attachmentIdOrOpts : void 0;
|
|
50969
|
+
const opts = typeof attachmentIdOrOpts === "object" && attachmentIdOrOpts !== null ? attachmentIdOrOpts : maybeOpts ?? {};
|
|
50970
|
+
const { id, output } = validateViewOpts(positionalId, opts);
|
|
50915
50971
|
const agentContext = ctx.loadAgentContext();
|
|
50916
50972
|
const client = ctx.createApiClient(agentContext);
|
|
50917
50973
|
const res = await createAgentApiSurfaceClient(client).attachments.view({ attachmentId: id });
|
|
@@ -51069,13 +51125,7 @@ function formatTaskStatusUpdated(taskNumber, status) {
|
|
|
51069
51125
|
// src/commands/task/list.ts
|
|
51070
51126
|
var VALID_STATUSES = ["all", "todo", "in_progress", "in_review", "done", "closed"];
|
|
51071
51127
|
function validateListOpts(opts) {
|
|
51072
|
-
const channel = opts
|
|
51073
|
-
if (!channel) {
|
|
51074
|
-
throw new CliError({
|
|
51075
|
-
code: "INVALID_ARG",
|
|
51076
|
-
message: "--channel is required"
|
|
51077
|
-
});
|
|
51078
|
-
}
|
|
51128
|
+
const channel = requireTargetAlias(opts);
|
|
51079
51129
|
if (opts.status && !VALID_STATUSES.includes(opts.status)) {
|
|
51080
51130
|
throw new CliError({
|
|
51081
51131
|
code: "INVALID_ARG",
|
|
@@ -51092,7 +51142,8 @@ var taskListCommand = defineCommand(
|
|
|
51092
51142
|
name: "list",
|
|
51093
51143
|
description: "List tasks in a channel",
|
|
51094
51144
|
options: [
|
|
51095
|
-
{ flags: "--
|
|
51145
|
+
{ flags: "--target <target>", description: "Channel target: '#channel'" },
|
|
51146
|
+
{ flags: "--channel <target>", description: "Legacy alias for --target (accepted during transition)" },
|
|
51096
51147
|
{ flags: "--status <s>", description: "Filter: all|todo|in_progress|in_review|done (default: server-side)" }
|
|
51097
51148
|
]
|
|
51098
51149
|
},
|
|
@@ -51133,7 +51184,8 @@ var taskCreateCommand = defineCommand(
|
|
|
51133
51184
|
name: "create",
|
|
51134
51185
|
description: "Create one or more tasks in a channel",
|
|
51135
51186
|
options: [
|
|
51136
|
-
{ flags: "--
|
|
51187
|
+
{ flags: "--target <target>", description: "Channel target: '#channel'" },
|
|
51188
|
+
{ flags: "--channel <target>", description: "Legacy alias for --target (accepted during transition)" },
|
|
51137
51189
|
{
|
|
51138
51190
|
flags: "--title <title>",
|
|
51139
51191
|
description: "Task title (repeatable for batch create)",
|
|
@@ -51142,10 +51194,7 @@ var taskCreateCommand = defineCommand(
|
|
|
51142
51194
|
]
|
|
51143
51195
|
},
|
|
51144
51196
|
async (ctx, opts) => {
|
|
51145
|
-
const channel = opts
|
|
51146
|
-
if (!channel) {
|
|
51147
|
-
throw cliError("INVALID_ARG", "--channel is required");
|
|
51148
|
-
}
|
|
51197
|
+
const channel = requireTargetAlias(opts);
|
|
51149
51198
|
const titles = opts.title ?? [];
|
|
51150
51199
|
if (titles.length === 0) throw cliError("INVALID_ARG", "--title is required (at least one)");
|
|
51151
51200
|
const body = { channel, tasks: titles.map((title) => ({ title })) };
|
|
@@ -51177,7 +51226,8 @@ var taskClaimCommand = defineCommand(
|
|
|
51177
51226
|
name: "claim",
|
|
51178
51227
|
description: "Claim one or more tasks (by task number or message id)",
|
|
51179
51228
|
options: [
|
|
51180
|
-
{ flags: "--
|
|
51229
|
+
{ flags: "--target <target>", description: "Channel target: '#channel'" },
|
|
51230
|
+
{ flags: "--channel <target>", description: "Legacy alias for --target (accepted during transition)" },
|
|
51181
51231
|
{
|
|
51182
51232
|
flags: "--number <n>",
|
|
51183
51233
|
description: "Task number to claim (repeatable)",
|
|
@@ -51191,9 +51241,7 @@ var taskClaimCommand = defineCommand(
|
|
|
51191
51241
|
]
|
|
51192
51242
|
},
|
|
51193
51243
|
async (ctx, opts) => {
|
|
51194
|
-
|
|
51195
|
-
throw cliError("INVALID_ARG", "--channel is required");
|
|
51196
|
-
}
|
|
51244
|
+
const channel = requireTargetAlias(opts);
|
|
51197
51245
|
const numbers = (opts.number ?? []).map((raw) => {
|
|
51198
51246
|
const n = Number(raw);
|
|
51199
51247
|
if (!Number.isFinite(n) || !Number.isInteger(n) || n <= 0) {
|
|
@@ -51205,7 +51253,7 @@ var taskClaimCommand = defineCommand(
|
|
|
51205
51253
|
if (numbers.length === 0 && messageIds.length === 0) {
|
|
51206
51254
|
throw cliError("INVALID_ARG", "Provide at least one --number or --message-id");
|
|
51207
51255
|
}
|
|
51208
|
-
const body = { channel
|
|
51256
|
+
const body = { channel };
|
|
51209
51257
|
if (numbers.length > 0) body.task_numbers = numbers;
|
|
51210
51258
|
if (messageIds.length > 0) body.message_ids = messageIds;
|
|
51211
51259
|
const agentContext = ctx.loadAgentContext();
|
|
@@ -51220,7 +51268,7 @@ var taskClaimCommand = defineCommand(
|
|
|
51220
51268
|
throw cliError("INVALID_JSON_RESPONSE", "Agent API taskClaim returned an empty response body");
|
|
51221
51269
|
}
|
|
51222
51270
|
if (isFreshnessHeldResponse(res.data)) {
|
|
51223
|
-
writeText(ctx.io, formatFreshnessHoldOutput(
|
|
51271
|
+
writeText(ctx.io, formatFreshnessHoldOutput(channel, res.data, {
|
|
51224
51272
|
heldAction: "Your task claim was not applied.",
|
|
51225
51273
|
draftInstructions: "After reviewing the newer context, rerun the task claim command if it is still correct.\n"
|
|
51226
51274
|
}));
|
|
@@ -51229,7 +51277,7 @@ var taskClaimCommand = defineCommand(
|
|
|
51229
51277
|
if (!isTaskClaimSuccessResponse(res.data)) {
|
|
51230
51278
|
throw cliError("INVALID_JSON_RESPONSE", "Agent API taskClaim returned an unexpected response body");
|
|
51231
51279
|
}
|
|
51232
|
-
writeText(ctx.io, formatClaimResults(
|
|
51280
|
+
writeText(ctx.io, formatClaimResults(channel, res.data) + "\n");
|
|
51233
51281
|
}
|
|
51234
51282
|
);
|
|
51235
51283
|
function registerTaskClaimCommand(parent, runtimeOptions = {}) {
|
|
@@ -51249,13 +51297,7 @@ function parseTaskNumber(raw) {
|
|
|
51249
51297
|
return n;
|
|
51250
51298
|
}
|
|
51251
51299
|
function validateUnclaimOpts(opts) {
|
|
51252
|
-
const channel = opts
|
|
51253
|
-
if (!channel) {
|
|
51254
|
-
throw new CliError({
|
|
51255
|
-
code: "INVALID_ARG",
|
|
51256
|
-
message: "--channel is required"
|
|
51257
|
-
});
|
|
51258
|
-
}
|
|
51300
|
+
const channel = requireTargetAlias(opts);
|
|
51259
51301
|
return { channel, taskNumber: parseTaskNumber(opts.number) };
|
|
51260
51302
|
}
|
|
51261
51303
|
var taskUnclaimCommand = defineCommand(
|
|
@@ -51263,7 +51305,8 @@ var taskUnclaimCommand = defineCommand(
|
|
|
51263
51305
|
name: "unclaim",
|
|
51264
51306
|
description: "Release a previously-claimed task",
|
|
51265
51307
|
options: [
|
|
51266
|
-
{ flags: "--
|
|
51308
|
+
{ flags: "--target <target>", description: "Channel target: '#channel'" },
|
|
51309
|
+
{ flags: "--channel <target>", description: "Legacy alias for --target (accepted during transition)" },
|
|
51267
51310
|
{ flags: "--number <n>", description: "Task number to unclaim" }
|
|
51268
51311
|
]
|
|
51269
51312
|
},
|
|
@@ -51317,13 +51360,7 @@ function parseStatus(raw) {
|
|
|
51317
51360
|
return raw;
|
|
51318
51361
|
}
|
|
51319
51362
|
function validateUpdateOpts(opts) {
|
|
51320
|
-
const channel = opts
|
|
51321
|
-
if (!channel) {
|
|
51322
|
-
throw new CliError({
|
|
51323
|
-
code: "INVALID_ARG",
|
|
51324
|
-
message: "--channel is required"
|
|
51325
|
-
});
|
|
51326
|
-
}
|
|
51363
|
+
const channel = requireTargetAlias(opts);
|
|
51327
51364
|
return {
|
|
51328
51365
|
channel,
|
|
51329
51366
|
taskNumber: parseTaskNumber2(opts.number),
|
|
@@ -51335,7 +51372,8 @@ var taskUpdateCommand = defineCommand(
|
|
|
51335
51372
|
name: "update",
|
|
51336
51373
|
description: "Update task status",
|
|
51337
51374
|
options: [
|
|
51338
|
-
{ flags: "--
|
|
51375
|
+
{ flags: "--target <target>", description: "Channel target: '#channel'" },
|
|
51376
|
+
{ flags: "--channel <target>", description: "Legacy alias for --target (accepted during transition)" },
|
|
51339
51377
|
{ flags: "--number <n>", description: "Task number to update" },
|
|
51340
51378
|
{ flags: "--status <status>", description: `New status. One of: ${STATUSES.join(", ")}` }
|
|
51341
51379
|
]
|
|
@@ -51525,13 +51563,13 @@ function pushServiceBlock(lines, service, active) {
|
|
|
51525
51563
|
lines.push(`- ${service.name}`);
|
|
51526
51564
|
lines.push(` service: ${service.clientId}`);
|
|
51527
51565
|
lines.push(` id: ${service.id}`);
|
|
51528
|
-
if (service.appType === "slock_builtin") lines.push(" type: built-in
|
|
51566
|
+
if (service.appType === "slock_builtin") lines.push(" type: built-in Raft app");
|
|
51529
51567
|
lines.push(` status: ${active ? "active login" : "not logged in"}`);
|
|
51530
51568
|
lines.push(` return URL: ${formatMaybe(service.returnUrl)}`);
|
|
51531
51569
|
if (service.agentManifestUrl) {
|
|
51532
51570
|
lines.push(` agent behavior manifest: ${service.agentManifestUrl}`);
|
|
51533
51571
|
lines.push(` local CLI env: raft integration env --service ${JSON.stringify(service.clientId)}`);
|
|
51534
|
-
lines.push(`
|
|
51572
|
+
lines.push(` for login_with_raft HTTP API action manifests: raft integration invoke --service ${JSON.stringify(service.clientId)} --list-actions`);
|
|
51535
51573
|
}
|
|
51536
51574
|
if (service.homepageUrl) lines.push(` homepage: ${service.homepageUrl}`);
|
|
51537
51575
|
if (service.description) lines.push(` description: ${service.description}`);
|
|
@@ -51543,7 +51581,7 @@ function formatIntegrationList(data) {
|
|
|
51543
51581
|
const registeredServices = data.services.filter((service) => service.appType !== "slock_builtin");
|
|
51544
51582
|
const lines = [];
|
|
51545
51583
|
if (builtInServices.length > 0) {
|
|
51546
|
-
lines.push("Built-in
|
|
51584
|
+
lines.push("Built-in Raft apps:");
|
|
51547
51585
|
for (const service of builtInServices) {
|
|
51548
51586
|
pushServiceBlock(lines, service, activeByServiceId.get(service.id));
|
|
51549
51587
|
}
|
|
@@ -51571,7 +51609,7 @@ function formatIntegrationList(data) {
|
|
|
51571
51609
|
if (login.agentManifestUrl) {
|
|
51572
51610
|
lines.push(` agent behavior manifest: ${login.agentManifestUrl}`);
|
|
51573
51611
|
lines.push(` local CLI env: raft integration env --service ${JSON.stringify(login.clientId)}`);
|
|
51574
|
-
lines.push(`
|
|
51612
|
+
lines.push(` for login_with_raft HTTP API action manifests: raft integration invoke --service ${JSON.stringify(login.clientId)} --list-actions`);
|
|
51575
51613
|
}
|
|
51576
51614
|
lines.push(` created: ${login.createdAt}`);
|
|
51577
51615
|
}
|
|
@@ -51608,16 +51646,16 @@ function formatIntegrationLogin(data) {
|
|
|
51608
51646
|
if (data.service.agentManifestUrl) {
|
|
51609
51647
|
lines.push(`agent behavior manifest: ${data.service.agentManifestUrl}`);
|
|
51610
51648
|
lines.push(`local CLI env: raft integration env --service ${JSON.stringify(data.service.clientId)}`);
|
|
51611
|
-
lines.push(`
|
|
51612
|
-
}
|
|
51613
|
-
lines.push("complete: this agent login is configured in
|
|
51614
|
-
lines.push("identity: run `raft profile show` if the service or human asks for your
|
|
51615
|
-
|
|
51616
|
-
|
|
51617
|
-
lines.push(`
|
|
51618
|
-
lines.push(
|
|
51619
|
-
lines.push(`next: prefer \`raft integration invoke --service ${JSON.stringify(data.service.clientId)} --list-actions\` when the service manifest exposes actions`);
|
|
51649
|
+
lines.push(`for login_with_raft HTTP API action manifests: raft integration invoke --service ${JSON.stringify(data.service.clientId)} --list-actions`);
|
|
51650
|
+
}
|
|
51651
|
+
lines.push("complete: this agent login is configured in Raft; no human OAuth is required");
|
|
51652
|
+
lines.push("identity: run `raft profile show` if the service or human asks for your Raft Agent identity card");
|
|
51653
|
+
if (data.session) {
|
|
51654
|
+
lines.push(`session: service session ${data.session.source === "fresh" ? "created" : "reused"} and stored for this agent`);
|
|
51655
|
+
if (data.session.path) lines.push(`session store: ${data.session.path}`);
|
|
51656
|
+
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`);
|
|
51620
51657
|
} else {
|
|
51658
|
+
lines.push("session: no service callback session was established; Raft grant is active");
|
|
51621
51659
|
lines.push("next: use the service, or run `raft integration list` to confirm active login");
|
|
51622
51660
|
}
|
|
51623
51661
|
return lines.join("\n");
|
|
@@ -51627,7 +51665,7 @@ function formatIntegrationLogin(data) {
|
|
|
51627
51665
|
var integrationListCommand = defineCommand(
|
|
51628
51666
|
{
|
|
51629
51667
|
name: "list",
|
|
51630
|
-
description: "List built-in
|
|
51668
|
+
description: "List built-in Raft apps, registered services, and this agent's active logins",
|
|
51631
51669
|
options: [{ flags: "--json", description: "Emit machine-readable JSON" }]
|
|
51632
51670
|
},
|
|
51633
51671
|
async (ctx, opts) => {
|
|
@@ -51652,6 +51690,202 @@ function registerIntegrationListCommand(parent, runtimeOptions = {}) {
|
|
|
51652
51690
|
|
|
51653
51691
|
// src/commands/integration/login.ts
|
|
51654
51692
|
init_esm_shims();
|
|
51693
|
+
|
|
51694
|
+
// src/commands/integration/_session.ts
|
|
51695
|
+
init_esm_shims();
|
|
51696
|
+
import fs5 from "fs";
|
|
51697
|
+
import os4 from "os";
|
|
51698
|
+
import path8 from "path";
|
|
51699
|
+
function safeUrl(value, label) {
|
|
51700
|
+
let url2;
|
|
51701
|
+
try {
|
|
51702
|
+
url2 = new URL(value);
|
|
51703
|
+
} catch {
|
|
51704
|
+
throw cliError("INVALID_ARG", `${label} must be a valid URL`);
|
|
51705
|
+
}
|
|
51706
|
+
if (url2.protocol !== "https:" && url2.protocol !== "http:") {
|
|
51707
|
+
throw cliError("INVALID_ARG", `${label} must use http or https`);
|
|
51708
|
+
}
|
|
51709
|
+
if (url2.username || url2.password) {
|
|
51710
|
+
throw cliError("INVALID_ARG", `${label} must not include credentials`);
|
|
51711
|
+
}
|
|
51712
|
+
return url2;
|
|
51713
|
+
}
|
|
51714
|
+
function resolveStateRoot(env) {
|
|
51715
|
+
const configured = env.RAFT_HOME?.trim() || env.SLOCK_HOME?.trim();
|
|
51716
|
+
if (configured) return configured;
|
|
51717
|
+
const home = env.HOME ?? os4.homedir();
|
|
51718
|
+
return path8.join(home, ".slock");
|
|
51719
|
+
}
|
|
51720
|
+
function integrationSessionFilePath(input) {
|
|
51721
|
+
const root = input.agentContext.profileCredentialPath ? path8.dirname(input.agentContext.profileCredentialPath) : path8.join(resolveStateRoot(input.env), "integration-sessions", input.agentContext.agentId);
|
|
51722
|
+
const safeClientId = encodeURIComponent(input.service.clientId).replace(/%/g, "_");
|
|
51723
|
+
return path8.join(root, "integrations", `${safeClientId}.json`);
|
|
51724
|
+
}
|
|
51725
|
+
function setCookieHeaderValues(headers) {
|
|
51726
|
+
const getSetCookie = headers.getSetCookie;
|
|
51727
|
+
return typeof getSetCookie === "function" ? getSetCookie.call(headers) : [headers.get("set-cookie")].filter((value) => Boolean(value));
|
|
51728
|
+
}
|
|
51729
|
+
function defaultCookiePath(pathname) {
|
|
51730
|
+
if (!pathname.startsWith("/") || pathname === "/") return "/";
|
|
51731
|
+
const lastSlash = pathname.lastIndexOf("/");
|
|
51732
|
+
if (lastSlash <= 0) return "/";
|
|
51733
|
+
return pathname.slice(0, lastSlash);
|
|
51734
|
+
}
|
|
51735
|
+
function parseCookieExpiry(parts) {
|
|
51736
|
+
const now = Date.now();
|
|
51737
|
+
for (const part of parts) {
|
|
51738
|
+
const separator = part.indexOf("=");
|
|
51739
|
+
const rawName = separator >= 0 ? part.slice(0, separator) : part;
|
|
51740
|
+
const rawValue = separator >= 0 ? part.slice(separator + 1) : "";
|
|
51741
|
+
const name = rawName.trim().toLowerCase();
|
|
51742
|
+
if (name === "max-age") {
|
|
51743
|
+
const seconds = Number(rawValue.trim());
|
|
51744
|
+
if (Number.isFinite(seconds)) return new Date(now + Math.max(0, seconds) * 1e3).toISOString();
|
|
51745
|
+
}
|
|
51746
|
+
if (name === "expires") {
|
|
51747
|
+
const time3 = Date.parse(rawValue.trim());
|
|
51748
|
+
if (Number.isFinite(time3)) return new Date(time3).toISOString();
|
|
51749
|
+
}
|
|
51750
|
+
}
|
|
51751
|
+
return void 0;
|
|
51752
|
+
}
|
|
51753
|
+
function parseSessionCookie(value, sourceUrl) {
|
|
51754
|
+
const parts = value.split(";").map((part) => part.trim()).filter(Boolean);
|
|
51755
|
+
const pair = parts.shift();
|
|
51756
|
+
if (!pair || !pair.includes("=") || pair.startsWith("=")) return null;
|
|
51757
|
+
const sourceHost = sourceUrl.hostname.toLowerCase();
|
|
51758
|
+
let host = sourceHost;
|
|
51759
|
+
let cookiePath = defaultCookiePath(sourceUrl.pathname);
|
|
51760
|
+
let secure = false;
|
|
51761
|
+
for (const part of parts) {
|
|
51762
|
+
const separator = part.indexOf("=");
|
|
51763
|
+
const rawName = separator >= 0 ? part.slice(0, separator) : part;
|
|
51764
|
+
const rawValue = separator >= 0 ? part.slice(separator + 1) : "";
|
|
51765
|
+
const name = rawName.trim().toLowerCase();
|
|
51766
|
+
if (name === "secure") {
|
|
51767
|
+
secure = true;
|
|
51768
|
+
} else if (name === "path" && rawValue.trim().startsWith("/")) {
|
|
51769
|
+
cookiePath = rawValue.trim();
|
|
51770
|
+
} else if (name === "domain") {
|
|
51771
|
+
const domain2 = rawValue.trim().replace(/^\./, "").toLowerCase();
|
|
51772
|
+
if (domain2 !== sourceHost) return null;
|
|
51773
|
+
host = domain2;
|
|
51774
|
+
}
|
|
51775
|
+
}
|
|
51776
|
+
return { pair, host, path: cookiePath, secure, expiresAt: parseCookieExpiry(parts) };
|
|
51777
|
+
}
|
|
51778
|
+
function cookiePathMatches(requestPath, cookiePath) {
|
|
51779
|
+
if (requestPath === cookiePath) return true;
|
|
51780
|
+
if (cookiePath.endsWith("/")) return requestPath.startsWith(cookiePath);
|
|
51781
|
+
return requestPath.startsWith(`${cookiePath}/`);
|
|
51782
|
+
}
|
|
51783
|
+
function cookieHeaderForUrl(cookies, url2) {
|
|
51784
|
+
const host = url2.hostname.toLowerCase();
|
|
51785
|
+
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);
|
|
51786
|
+
return valid.length > 0 ? valid.join("; ") : null;
|
|
51787
|
+
}
|
|
51788
|
+
function sessionCookiesFromSetCookie(headers, sourceUrl) {
|
|
51789
|
+
return setCookieHeaderValues(headers).map((value) => parseSessionCookie(value, sourceUrl)).filter((value) => Boolean(value));
|
|
51790
|
+
}
|
|
51791
|
+
function isCookieFresh(cookie) {
|
|
51792
|
+
if (!cookie.expiresAt) return true;
|
|
51793
|
+
return Date.parse(cookie.expiresAt) > Date.now() + 3e4;
|
|
51794
|
+
}
|
|
51795
|
+
function freshCookies(cookies) {
|
|
51796
|
+
return cookies.filter(isCookieFresh);
|
|
51797
|
+
}
|
|
51798
|
+
function loadStoredIntegrationSession(input) {
|
|
51799
|
+
const filePath = integrationSessionFilePath(input);
|
|
51800
|
+
if (!filePath) return null;
|
|
51801
|
+
let raw;
|
|
51802
|
+
try {
|
|
51803
|
+
raw = fs5.readFileSync(filePath, "utf8");
|
|
51804
|
+
} catch {
|
|
51805
|
+
return null;
|
|
51806
|
+
}
|
|
51807
|
+
let parsed;
|
|
51808
|
+
try {
|
|
51809
|
+
parsed = JSON.parse(raw);
|
|
51810
|
+
} catch {
|
|
51811
|
+
return null;
|
|
51812
|
+
}
|
|
51813
|
+
if (!parsed || typeof parsed !== "object") return null;
|
|
51814
|
+
const session = parsed;
|
|
51815
|
+
if (session.serviceId !== input.service.id || session.clientId !== input.service.clientId || session.returnUrl !== input.service.returnUrl || !Array.isArray(session.cookies)) {
|
|
51816
|
+
return null;
|
|
51817
|
+
}
|
|
51818
|
+
const cookies = freshCookies(session.cookies);
|
|
51819
|
+
if (cookies.length === 0) return null;
|
|
51820
|
+
return { ...session, cookies };
|
|
51821
|
+
}
|
|
51822
|
+
function storeIntegrationSession(input) {
|
|
51823
|
+
const filePath = integrationSessionFilePath(input);
|
|
51824
|
+
if (!filePath) return null;
|
|
51825
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
51826
|
+
const previous = loadStoredIntegrationSession(input);
|
|
51827
|
+
const body = {
|
|
51828
|
+
serviceId: input.service.id,
|
|
51829
|
+
clientId: input.service.clientId,
|
|
51830
|
+
returnUrl: input.service.returnUrl ?? "",
|
|
51831
|
+
cookies: freshCookies(input.cookies),
|
|
51832
|
+
createdAt: previous?.createdAt ?? now,
|
|
51833
|
+
updatedAt: now
|
|
51834
|
+
};
|
|
51835
|
+
fs5.mkdirSync(path8.dirname(filePath), { recursive: true, mode: 448 });
|
|
51836
|
+
fs5.writeFileSync(filePath, `${JSON.stringify(body, null, 2)}
|
|
51837
|
+
`, { mode: 384 });
|
|
51838
|
+
return filePath;
|
|
51839
|
+
}
|
|
51840
|
+
async function consumeAgentLoginHandoff(input) {
|
|
51841
|
+
if (!input.login.requestId) {
|
|
51842
|
+
throw cliError("INTEGRATION_LOGIN_FAILED", "agent login response did not include an internal one-time handoff request");
|
|
51843
|
+
}
|
|
51844
|
+
const callbackUrl = buildAgentCallbackHandoffUrl(input.service.returnUrl, input.login.requestId);
|
|
51845
|
+
if (!callbackUrl) {
|
|
51846
|
+
throw cliError("INTEGRATION_LOGIN_FAILED", "service return URL cannot be used for Agent Login callback handoff");
|
|
51847
|
+
}
|
|
51848
|
+
const parsedCallbackUrl = safeUrl(callbackUrl, "service callback URL");
|
|
51849
|
+
const response = await fetch(callbackUrl, {
|
|
51850
|
+
method: "GET",
|
|
51851
|
+
redirect: "manual",
|
|
51852
|
+
headers: { accept: "text/html,application/json" }
|
|
51853
|
+
});
|
|
51854
|
+
if (response.status < 200 || response.status >= 400) {
|
|
51855
|
+
if (response.status === 409) {
|
|
51856
|
+
throw cliError(
|
|
51857
|
+
"INTEGRATION_LOGIN_FAILED",
|
|
51858
|
+
"service callback handoff was rejected as expired or already used; rerun `raft integration login` to obtain a fresh handoff"
|
|
51859
|
+
);
|
|
51860
|
+
}
|
|
51861
|
+
throw cliError("INTEGRATION_LOGIN_FAILED", `service callback handoff failed with HTTP ${response.status}`);
|
|
51862
|
+
}
|
|
51863
|
+
const cookies = sessionCookiesFromSetCookie(response.headers, parsedCallbackUrl);
|
|
51864
|
+
if (cookies.length === 0) {
|
|
51865
|
+
throw cliError(
|
|
51866
|
+
"INTEGRATION_LOGIN_FAILED",
|
|
51867
|
+
"service callback handoff did not set a session cookie; the service may not support stateless Agent Login sessions yet"
|
|
51868
|
+
);
|
|
51869
|
+
}
|
|
51870
|
+
return cookies;
|
|
51871
|
+
}
|
|
51872
|
+
async function ensureIntegrationServiceSession(input) {
|
|
51873
|
+
if (!input.refresh) {
|
|
51874
|
+
const stored = loadStoredIntegrationSession(input);
|
|
51875
|
+
if (stored) {
|
|
51876
|
+
return {
|
|
51877
|
+
cookies: stored.cookies,
|
|
51878
|
+
source: "cache",
|
|
51879
|
+
sessionPath: integrationSessionFilePath(input)
|
|
51880
|
+
};
|
|
51881
|
+
}
|
|
51882
|
+
}
|
|
51883
|
+
const cookies = await consumeAgentLoginHandoff(input);
|
|
51884
|
+
const sessionPath = storeIntegrationSession({ ...input, cookies });
|
|
51885
|
+
return { cookies, source: "fresh", sessionPath };
|
|
51886
|
+
}
|
|
51887
|
+
|
|
51888
|
+
// src/commands/integration/login.ts
|
|
51655
51889
|
function normalizeScopes(raw) {
|
|
51656
51890
|
if (!raw || raw.length === 0) return void 0;
|
|
51657
51891
|
const scopes = Array.from(new Set(
|
|
@@ -51662,10 +51896,15 @@ function normalizeScopes(raw) {
|
|
|
51662
51896
|
}
|
|
51663
51897
|
return scopes;
|
|
51664
51898
|
}
|
|
51899
|
+
function redactSuccessfulRequestId(data) {
|
|
51900
|
+
if (data.status === "approval_required") return data;
|
|
51901
|
+
const { requestId: _requestId, ...rest } = data;
|
|
51902
|
+
return rest;
|
|
51903
|
+
}
|
|
51665
51904
|
var integrationLoginCommand = defineCommand(
|
|
51666
51905
|
{
|
|
51667
51906
|
name: "login",
|
|
51668
|
-
description: "Provision or reuse this agent's login for a built-in
|
|
51907
|
+
description: "Provision or reuse this agent's login for a built-in Raft app or registered service",
|
|
51669
51908
|
options: [
|
|
51670
51909
|
{ flags: "--service <id>", description: "Registered service id, client id, or exact service name" },
|
|
51671
51910
|
{
|
|
@@ -51697,11 +51936,30 @@ var integrationLoginCommand = defineCommand(
|
|
|
51697
51936
|
const code = res.status >= 500 ? "SERVER_5XX" : "INTEGRATION_LOGIN_FAILED";
|
|
51698
51937
|
throw cliError(code, res.error ?? `HTTP ${res.status}`);
|
|
51699
51938
|
}
|
|
51939
|
+
let data = res.data;
|
|
51940
|
+
if (data.status !== "approval_required" && data.service.returnUrl) {
|
|
51941
|
+
const session = await ensureIntegrationServiceSession({
|
|
51942
|
+
login: data,
|
|
51943
|
+
service: data.service,
|
|
51944
|
+
agentContext,
|
|
51945
|
+
env: ctx.env,
|
|
51946
|
+
refresh: true
|
|
51947
|
+
});
|
|
51948
|
+
data = {
|
|
51949
|
+
...data,
|
|
51950
|
+
session: {
|
|
51951
|
+
status: "stored",
|
|
51952
|
+
source: session.source,
|
|
51953
|
+
path: session.sessionPath
|
|
51954
|
+
}
|
|
51955
|
+
};
|
|
51956
|
+
}
|
|
51957
|
+
const outputData = redactSuccessfulRequestId(data);
|
|
51700
51958
|
if (opts.json) {
|
|
51701
|
-
writeJson(ctx.io, { ok: true, data:
|
|
51959
|
+
writeJson(ctx.io, { ok: true, data: outputData });
|
|
51702
51960
|
return;
|
|
51703
51961
|
}
|
|
51704
|
-
writeText(ctx.io, `${formatIntegrationLogin(
|
|
51962
|
+
writeText(ctx.io, `${formatIntegrationLogin(outputData)}
|
|
51705
51963
|
`);
|
|
51706
51964
|
}
|
|
51707
51965
|
);
|
|
@@ -51714,9 +51972,9 @@ init_esm_shims();
|
|
|
51714
51972
|
|
|
51715
51973
|
// src/commands/integration/manifest.ts
|
|
51716
51974
|
init_esm_shims();
|
|
51717
|
-
import
|
|
51718
|
-
import
|
|
51719
|
-
import
|
|
51975
|
+
import fs6 from "fs";
|
|
51976
|
+
import os5 from "os";
|
|
51977
|
+
import path9 from "path";
|
|
51720
51978
|
var AGENT_MANIFEST_MAX_BYTES = 64 * 1024;
|
|
51721
51979
|
var AGENT_MANIFEST_SCHEMA_V0 = "slock-agent-manifest.v0";
|
|
51722
51980
|
var RAFT_AGENT_MANIFEST_SCHEMA_V0 = "raft-agent-manifest.v0";
|
|
@@ -51784,22 +52042,22 @@ function requireEndpointPath(value, field) {
|
|
|
51784
52042
|
if (typeof value !== "string" || !value.trim()) {
|
|
51785
52043
|
throw new Error(`${field} must be a non-empty path string`);
|
|
51786
52044
|
}
|
|
51787
|
-
const
|
|
51788
|
-
if (!
|
|
52045
|
+
const path10 = value.trim();
|
|
52046
|
+
if (!path10.startsWith("/")) {
|
|
51789
52047
|
throw new Error(`${field} must start with /`);
|
|
51790
52048
|
}
|
|
51791
|
-
if (
|
|
52049
|
+
if (path10.startsWith("//")) {
|
|
51792
52050
|
throw new Error(`${field} must be a relative service path`);
|
|
51793
52051
|
}
|
|
51794
52052
|
try {
|
|
51795
|
-
const parsed = new URL(
|
|
52053
|
+
const parsed = new URL(path10, "https://manifest.local");
|
|
51796
52054
|
if (parsed.origin !== "https://manifest.local" || parsed.username || parsed.password || parsed.hash) {
|
|
51797
52055
|
throw new Error();
|
|
51798
52056
|
}
|
|
51799
52057
|
} catch {
|
|
51800
52058
|
throw new Error(`${field} must be a relative service path`);
|
|
51801
52059
|
}
|
|
51802
|
-
return
|
|
52060
|
+
return path10;
|
|
51803
52061
|
}
|
|
51804
52062
|
function normalizeActionMethod(value) {
|
|
51805
52063
|
if (typeof value !== "string") {
|
|
@@ -51995,14 +52253,14 @@ function sanitizePathSegment(value) {
|
|
|
51995
52253
|
const segment = value.trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
51996
52254
|
return segment || "service";
|
|
51997
52255
|
}
|
|
51998
|
-
function resolveSlockHome(env, homeDir =
|
|
52256
|
+
function resolveSlockHome(env, homeDir = os5.homedir()) {
|
|
51999
52257
|
const configured = env.SLOCK_HOME?.trim() || env.RAFT_HOME?.trim();
|
|
52000
|
-
const raw = configured && configured.length > 0 ? configured :
|
|
52001
|
-
return
|
|
52258
|
+
const raw = configured && configured.length > 0 ? configured : path9.join(homeDir, ".slock");
|
|
52259
|
+
return path9.resolve(expandHome(raw, homeDir));
|
|
52002
52260
|
}
|
|
52003
52261
|
function expandHome(input, homeDir) {
|
|
52004
52262
|
if (input === "~") return homeDir;
|
|
52005
|
-
if (input.startsWith("~/")) return
|
|
52263
|
+
if (input.startsWith("~/")) return path9.join(homeDir, input.slice(2));
|
|
52006
52264
|
return input;
|
|
52007
52265
|
}
|
|
52008
52266
|
function buildLocalCliProfileEnv(input) {
|
|
@@ -52016,15 +52274,15 @@ function buildLocalCliProfileEnv(input) {
|
|
|
52016
52274
|
throw new Error("manifest must set credential_boundary.forbid_user_home=true for local_cli isolation");
|
|
52017
52275
|
}
|
|
52018
52276
|
const root = resolveSlockHome(input.env ?? process.env, input.homeDir);
|
|
52019
|
-
const profileHome =
|
|
52277
|
+
const profileHome = path9.join(
|
|
52020
52278
|
root,
|
|
52021
52279
|
"integration-profiles",
|
|
52022
52280
|
sanitizePathSegment(input.ctx.serverId ?? "server"),
|
|
52023
52281
|
sanitizePathSegment(input.ctx.agentId),
|
|
52024
52282
|
sanitizePathSegment(input.serviceId)
|
|
52025
52283
|
);
|
|
52026
|
-
|
|
52027
|
-
|
|
52284
|
+
fs6.mkdirSync(profileHome, { recursive: true, mode: 448 });
|
|
52285
|
+
fs6.chmodSync(profileHome, 448);
|
|
52028
52286
|
return {
|
|
52029
52287
|
serviceId: input.serviceId,
|
|
52030
52288
|
command: input.manifest.execution.command,
|
|
@@ -52033,10 +52291,10 @@ function buildLocalCliProfileEnv(input) {
|
|
|
52033
52291
|
SLOCK_INTEGRATION_SERVICE: input.serviceId,
|
|
52034
52292
|
SLOCK_INTEGRATION_PROFILE_HOME: profileHome,
|
|
52035
52293
|
HOME: profileHome,
|
|
52036
|
-
XDG_CONFIG_HOME:
|
|
52037
|
-
XDG_CACHE_HOME:
|
|
52038
|
-
XDG_DATA_HOME:
|
|
52039
|
-
XDG_STATE_HOME:
|
|
52294
|
+
XDG_CONFIG_HOME: path9.join(profileHome, ".config"),
|
|
52295
|
+
XDG_CACHE_HOME: path9.join(profileHome, ".cache"),
|
|
52296
|
+
XDG_DATA_HOME: path9.join(profileHome, ".local", "share"),
|
|
52297
|
+
XDG_STATE_HOME: path9.join(profileHome, ".local", "state")
|
|
52040
52298
|
}
|
|
52041
52299
|
};
|
|
52042
52300
|
}
|
|
@@ -52045,9 +52303,9 @@ function shellQuote(value) {
|
|
|
52045
52303
|
}
|
|
52046
52304
|
function formatShellExports(profile) {
|
|
52047
52305
|
const lines = [
|
|
52048
|
-
`#
|
|
52306
|
+
`# Raft integration profile for ${profile.serviceId}`,
|
|
52049
52307
|
`# command: ${profile.command}`,
|
|
52050
|
-
"# This only exports env;
|
|
52308
|
+
"# This only exports env; Raft does not execute manifest commands.",
|
|
52051
52309
|
"# Apply these exports before invoking the local CLI yourself."
|
|
52052
52310
|
];
|
|
52053
52311
|
for (const [key, value] of Object.entries(profile.env)) {
|
|
@@ -52075,10 +52333,10 @@ function describeNoLocalEnv(manifest) {
|
|
|
52075
52333
|
return "manifest execution mode is http_api; no local CLI env is required";
|
|
52076
52334
|
}
|
|
52077
52335
|
if (!manifest.credential_boundary) {
|
|
52078
|
-
return "manifest does not request a
|
|
52336
|
+
return "manifest does not request a Raft-managed local environment";
|
|
52079
52337
|
}
|
|
52080
52338
|
if (manifest.credential_boundary.storage === "slock_managed_token") {
|
|
52081
|
-
return "manifest uses
|
|
52339
|
+
return "manifest uses Raft-managed token storage; no local HOME/XDG exports are required";
|
|
52082
52340
|
}
|
|
52083
52341
|
return "manifest does not request local CLI env exports";
|
|
52084
52342
|
}
|
|
@@ -52157,7 +52415,7 @@ async function resolveIntegrationEnv(input) {
|
|
|
52157
52415
|
}
|
|
52158
52416
|
function formatNoLocalEnv(input) {
|
|
52159
52417
|
const lines = [
|
|
52160
|
-
`#
|
|
52418
|
+
`# Raft integration profile for ${input.service}`,
|
|
52161
52419
|
input.manifestUrl ? `# manifest: ${input.manifestUrl}` : "# manifest: none declared",
|
|
52162
52420
|
"# No local CLI environment exports are required for this service.",
|
|
52163
52421
|
`# ${input.message}`
|
|
@@ -52167,7 +52425,7 @@ function formatNoLocalEnv(input) {
|
|
|
52167
52425
|
lines.push(`# list actions: raft integration invoke --service ${JSON.stringify(input.service)} --list-actions`);
|
|
52168
52426
|
lines.push(`# invoke action: raft integration invoke --service ${JSON.stringify(input.service)} --action <name>`);
|
|
52169
52427
|
}
|
|
52170
|
-
lines.push("#
|
|
52428
|
+
lines.push("# Raft did not set HOME/XDG exports and did not execute manifest commands.");
|
|
52171
52429
|
return lines.join("\n");
|
|
52172
52430
|
}
|
|
52173
52431
|
var integrationEnvCommand = defineCommand(
|
|
@@ -52252,7 +52510,7 @@ function registerIntegrationEnvCommand(parent, runtimeOptions = {}) {
|
|
|
52252
52510
|
|
|
52253
52511
|
// src/commands/integration/invoke.ts
|
|
52254
52512
|
init_esm_shims();
|
|
52255
|
-
import
|
|
52513
|
+
import fs7 from "fs";
|
|
52256
52514
|
function normalizeService2(value) {
|
|
52257
52515
|
return value.trim().toLowerCase();
|
|
52258
52516
|
}
|
|
@@ -52284,10 +52542,10 @@ function parseHandlerArgs(serviceArgOrOpts, actionArgOrOpts, maybeOpts) {
|
|
|
52284
52542
|
}
|
|
52285
52543
|
function readTextReference(value) {
|
|
52286
52544
|
if (!value.startsWith("@")) return value;
|
|
52287
|
-
const
|
|
52288
|
-
if (!
|
|
52289
|
-
if (
|
|
52290
|
-
return
|
|
52545
|
+
const path10 = value.slice(1);
|
|
52546
|
+
if (!path10) throw cliError("INVALID_ARG", "@ file references must include a path");
|
|
52547
|
+
if (path10 === "-") return fs7.readFileSync(0, "utf8");
|
|
52548
|
+
return fs7.readFileSync(path10, "utf8");
|
|
52291
52549
|
}
|
|
52292
52550
|
function parseJsonObject(raw, label) {
|
|
52293
52551
|
let parsed;
|
|
@@ -52310,7 +52568,7 @@ function parseActionPayload(opts) {
|
|
|
52310
52568
|
Object.assign(payload, parseJsonObject(opts.dataJson, "--data-json"));
|
|
52311
52569
|
}
|
|
52312
52570
|
if (opts.dataFile) {
|
|
52313
|
-
const raw = opts.dataFile === "-" ?
|
|
52571
|
+
const raw = opts.dataFile === "-" ? fs7.readFileSync(0, "utf8") : fs7.readFileSync(opts.dataFile, "utf8");
|
|
52314
52572
|
Object.assign(payload, parseJsonObject(raw, "--data-file"));
|
|
52315
52573
|
}
|
|
52316
52574
|
for (const rawParam of opts.param ?? []) {
|
|
@@ -52332,7 +52590,7 @@ function validateRequiredParams(action, payload) {
|
|
|
52332
52590
|
}
|
|
52333
52591
|
}
|
|
52334
52592
|
}
|
|
52335
|
-
function
|
|
52593
|
+
function safeUrl2(value, label) {
|
|
52336
52594
|
let url2;
|
|
52337
52595
|
try {
|
|
52338
52596
|
url2 = new URL(value);
|
|
@@ -52348,87 +52606,16 @@ function safeUrl(value, label) {
|
|
|
52348
52606
|
return url2;
|
|
52349
52607
|
}
|
|
52350
52608
|
function resolveActionUrl(input) {
|
|
52351
|
-
const base = input.manifest.execution.base_url ?? input.manifest.app_origin ?? input.service.homepageUrl ?? (input.service.returnUrl ?
|
|
52609
|
+
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);
|
|
52352
52610
|
if (!base) {
|
|
52353
52611
|
throw cliError(
|
|
52354
52612
|
"INVALID_ARG",
|
|
52355
52613
|
"manifest must provide execution.base_url or app_origin, or the service must provide a homepage/return URL"
|
|
52356
52614
|
);
|
|
52357
52615
|
}
|
|
52358
|
-
const baseUrl =
|
|
52616
|
+
const baseUrl = safeUrl2(base, "action base URL");
|
|
52359
52617
|
return new URL(input.action.endpoint.path, baseUrl);
|
|
52360
52618
|
}
|
|
52361
|
-
function setCookieHeaderValues(headers) {
|
|
52362
|
-
const getSetCookie = headers.getSetCookie;
|
|
52363
|
-
return typeof getSetCookie === "function" ? getSetCookie.call(headers) : [headers.get("set-cookie")].filter((value) => Boolean(value));
|
|
52364
|
-
}
|
|
52365
|
-
function defaultCookiePath(pathname) {
|
|
52366
|
-
if (!pathname.startsWith("/") || pathname === "/") return "/";
|
|
52367
|
-
const lastSlash = pathname.lastIndexOf("/");
|
|
52368
|
-
if (lastSlash <= 0) return "/";
|
|
52369
|
-
return pathname.slice(0, lastSlash);
|
|
52370
|
-
}
|
|
52371
|
-
function parseSessionCookie(value, sourceUrl) {
|
|
52372
|
-
const parts = value.split(";").map((part) => part.trim()).filter(Boolean);
|
|
52373
|
-
const pair = parts.shift();
|
|
52374
|
-
if (!pair || !pair.includes("=") || pair.startsWith("=")) return null;
|
|
52375
|
-
const sourceHost = sourceUrl.hostname.toLowerCase();
|
|
52376
|
-
let host = sourceHost;
|
|
52377
|
-
let path9 = defaultCookiePath(sourceUrl.pathname);
|
|
52378
|
-
let secure = false;
|
|
52379
|
-
for (const part of parts) {
|
|
52380
|
-
const separator = part.indexOf("=");
|
|
52381
|
-
const rawName = separator >= 0 ? part.slice(0, separator) : part;
|
|
52382
|
-
const rawValue = separator >= 0 ? part.slice(separator + 1) : "";
|
|
52383
|
-
const name = rawName.trim().toLowerCase();
|
|
52384
|
-
if (name === "secure") {
|
|
52385
|
-
secure = true;
|
|
52386
|
-
} else if (name === "path" && rawValue.trim().startsWith("/")) {
|
|
52387
|
-
path9 = rawValue.trim();
|
|
52388
|
-
} else if (name === "domain") {
|
|
52389
|
-
const domain2 = rawValue.trim().replace(/^\./, "").toLowerCase();
|
|
52390
|
-
if (domain2 !== sourceHost) return null;
|
|
52391
|
-
host = domain2;
|
|
52392
|
-
}
|
|
52393
|
-
}
|
|
52394
|
-
return { pair, host, path: path9, secure };
|
|
52395
|
-
}
|
|
52396
|
-
function cookiePathMatches(requestPath, cookiePath) {
|
|
52397
|
-
if (requestPath === cookiePath) return true;
|
|
52398
|
-
if (cookiePath.endsWith("/")) return requestPath.startsWith(cookiePath);
|
|
52399
|
-
return requestPath.startsWith(`${cookiePath}/`);
|
|
52400
|
-
}
|
|
52401
|
-
function cookieHeaderForUrl(cookies, url2) {
|
|
52402
|
-
const host = url2.hostname.toLowerCase();
|
|
52403
|
-
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);
|
|
52404
|
-
return valid.length > 0 ? valid.join("; ") : null;
|
|
52405
|
-
}
|
|
52406
|
-
function sessionCookiesFromSetCookie(headers, sourceUrl) {
|
|
52407
|
-
return setCookieHeaderValues(headers).map((value) => parseSessionCookie(value, sourceUrl)).filter((value) => Boolean(value));
|
|
52408
|
-
}
|
|
52409
|
-
async function establishServiceSession(input) {
|
|
52410
|
-
const callbackUrl = buildAgentCallbackHandoffUrl(input.service.returnUrl, input.login.requestId);
|
|
52411
|
-
if (!callbackUrl) {
|
|
52412
|
-
throw cliError("INTEGRATION_INVOKE_FAILED", "service return URL cannot be used for Agent Login callback handoff");
|
|
52413
|
-
}
|
|
52414
|
-
const parsedCallbackUrl = safeUrl(callbackUrl, "service callback URL");
|
|
52415
|
-
const response = await fetch(callbackUrl, {
|
|
52416
|
-
method: "GET",
|
|
52417
|
-
redirect: "manual",
|
|
52418
|
-
headers: { accept: "text/html,application/json" }
|
|
52419
|
-
});
|
|
52420
|
-
if (response.status < 200 || response.status >= 400) {
|
|
52421
|
-
throw cliError("INTEGRATION_INVOKE_FAILED", `service callback handoff failed with HTTP ${response.status}`);
|
|
52422
|
-
}
|
|
52423
|
-
const cookies = sessionCookiesFromSetCookie(response.headers, parsedCallbackUrl);
|
|
52424
|
-
if (cookies.length === 0) {
|
|
52425
|
-
throw cliError(
|
|
52426
|
-
"INTEGRATION_INVOKE_FAILED",
|
|
52427
|
-
"service callback handoff did not set a session cookie; the service may not support stateless Agent Login API actions yet"
|
|
52428
|
-
);
|
|
52429
|
-
}
|
|
52430
|
-
return cookies;
|
|
52431
|
-
}
|
|
52432
52619
|
function appendPayloadAsQuery(url2, payload) {
|
|
52433
52620
|
for (const [key, value] of Object.entries(payload)) {
|
|
52434
52621
|
if (value === void 0 || value === null) continue;
|
|
@@ -52466,6 +52653,15 @@ async function invokeHttpAction(input) {
|
|
|
52466
52653
|
throw cliError("INVALID_JSON_RESPONSE", `service action returned invalid JSON (HTTP ${response.status})`);
|
|
52467
52654
|
});
|
|
52468
52655
|
if (!response.ok) {
|
|
52656
|
+
if (response.status === 401 || response.status === 403) {
|
|
52657
|
+
throw cliError(
|
|
52658
|
+
"INTEGRATION_INVOKE_FAILED",
|
|
52659
|
+
`service session was rejected or expired (HTTP ${response.status})`,
|
|
52660
|
+
{
|
|
52661
|
+
suggestedNextAction: `Run \`raft integration login --service ${input.service.clientId}\` and retry the action.`
|
|
52662
|
+
}
|
|
52663
|
+
);
|
|
52664
|
+
}
|
|
52469
52665
|
const message = value2 && typeof value2 === "object" && "error" in value2 ? String(value2.error) : `service action failed with HTTP ${response.status}`;
|
|
52470
52666
|
throw cliError("INTEGRATION_INVOKE_FAILED", message);
|
|
52471
52667
|
}
|
|
@@ -52473,6 +52669,15 @@ async function invokeHttpAction(input) {
|
|
|
52473
52669
|
}
|
|
52474
52670
|
const value = await response.text();
|
|
52475
52671
|
if (!response.ok) {
|
|
52672
|
+
if (response.status === 401 || response.status === 403) {
|
|
52673
|
+
throw cliError(
|
|
52674
|
+
"INTEGRATION_INVOKE_FAILED",
|
|
52675
|
+
`service session was rejected or expired (HTTP ${response.status})`,
|
|
52676
|
+
{
|
|
52677
|
+
suggestedNextAction: `Run \`raft integration login --service ${input.service.clientId}\` and retry the action.`
|
|
52678
|
+
}
|
|
52679
|
+
);
|
|
52680
|
+
}
|
|
52476
52681
|
throw cliError("INTEGRATION_INVOKE_FAILED", value || `service action failed with HTTP ${response.status}`);
|
|
52477
52682
|
}
|
|
52478
52683
|
return { kind: "text", status: response.status, value };
|
|
@@ -52518,7 +52723,53 @@ function formatActionResult(input) {
|
|
|
52518
52723
|
}
|
|
52519
52724
|
return lines.join("\n");
|
|
52520
52725
|
}
|
|
52521
|
-
|
|
52726
|
+
function unsupportedAuthNextAction(service, handoff2) {
|
|
52727
|
+
const loginCommand = `raft integration login --service ${JSON.stringify(service.clientId)}`;
|
|
52728
|
+
const manifestGuidance = [
|
|
52729
|
+
"or ask the service owner to publish a current login_with_raft HTTP API action manifest for integration invoke.",
|
|
52730
|
+
"`oauth_session_cookie` manifests are session-cookie services and are not directly invokable through this command yet."
|
|
52731
|
+
];
|
|
52732
|
+
if (handoff2?.kind === "handoff_url") {
|
|
52733
|
+
return [
|
|
52734
|
+
"A login request was created or reused for this agent.",
|
|
52735
|
+
`Use the service callback handoff URL to establish the service session: ${handoff2.url}`,
|
|
52736
|
+
...manifestGuidance
|
|
52737
|
+
].join(" ");
|
|
52738
|
+
}
|
|
52739
|
+
if (handoff2?.kind === "approval_required") {
|
|
52740
|
+
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.`;
|
|
52741
|
+
return [
|
|
52742
|
+
"Human approval is required before a service callback handoff URL can be generated.",
|
|
52743
|
+
card,
|
|
52744
|
+
"Ask a server owner/admin to approve it, then rerun this command to receive the callback handoff URL.",
|
|
52745
|
+
`To post an approval card, rerun with --target <channel-or-thread>, or run \`${loginCommand} --target <channel-or-thread>\`.`,
|
|
52746
|
+
...manifestGuidance
|
|
52747
|
+
].join(" ");
|
|
52748
|
+
}
|
|
52749
|
+
if (service.returnUrl) {
|
|
52750
|
+
const lines = [
|
|
52751
|
+
`Run \`${loginCommand}\` and use the printed service callback handoff URL to establish the service session,`,
|
|
52752
|
+
...manifestGuidance
|
|
52753
|
+
];
|
|
52754
|
+
if (handoff2?.kind === "unavailable") {
|
|
52755
|
+
lines.unshift(`Could not prepare a callback handoff URL automatically: ${handoff2.reason}.`);
|
|
52756
|
+
}
|
|
52757
|
+
return lines.join(" ");
|
|
52758
|
+
}
|
|
52759
|
+
return [
|
|
52760
|
+
"Ask the service owner to publish a current login_with_raft HTTP API action manifest for integration invoke.",
|
|
52761
|
+
"`oauth_session_cookie` manifests are session-cookie services and are not directly invokable through this command yet."
|
|
52762
|
+
].join(" ");
|
|
52763
|
+
}
|
|
52764
|
+
async function manifestInvalidNextAction(service, err, prepareHandoff) {
|
|
52765
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
52766
|
+
if (/auth\.type must be login_with_raft/.test(message)) {
|
|
52767
|
+
return unsupportedAuthNextAction(service, await prepareHandoff?.());
|
|
52768
|
+
}
|
|
52769
|
+
return void 0;
|
|
52770
|
+
}
|
|
52771
|
+
async function fetchManifestForInvoke(input) {
|
|
52772
|
+
const service = input.service;
|
|
52522
52773
|
if (!service.agentManifestUrl) {
|
|
52523
52774
|
throw cliError("INTEGRATION_MANIFEST_MISSING", `${service.name} does not expose an agent behavior manifest`);
|
|
52524
52775
|
}
|
|
@@ -52532,9 +52783,20 @@ async function fetchManifestForInvoke(service) {
|
|
|
52532
52783
|
if (err instanceof AgentManifestResponseFormatError) {
|
|
52533
52784
|
throw cliError("INTEGRATION_MANIFEST_INVALID", err.message, { cause: err });
|
|
52534
52785
|
}
|
|
52535
|
-
|
|
52786
|
+
const suggestedNextAction = await manifestInvalidNextAction(
|
|
52787
|
+
service,
|
|
52788
|
+
err,
|
|
52789
|
+
input.prepareUnsupportedAuthHandoff
|
|
52790
|
+
);
|
|
52791
|
+
throw cliError("INTEGRATION_MANIFEST_INVALID", err.message, {
|
|
52792
|
+
cause: err,
|
|
52793
|
+
suggestedNextAction
|
|
52794
|
+
});
|
|
52536
52795
|
}
|
|
52537
52796
|
}
|
|
52797
|
+
function loginFailureReason(res) {
|
|
52798
|
+
return res.error ?? `HTTP ${res.status}`;
|
|
52799
|
+
}
|
|
52538
52800
|
var integrationInvokeCommand = defineCommand(
|
|
52539
52801
|
{
|
|
52540
52802
|
name: "invoke",
|
|
@@ -52584,7 +52846,44 @@ var integrationInvokeCommand = defineCommand(
|
|
|
52584
52846
|
if (!service) {
|
|
52585
52847
|
throw cliError("INTEGRATION_NOT_FOUND", `No registered integration matched ${serviceQuery}`);
|
|
52586
52848
|
}
|
|
52587
|
-
const
|
|
52849
|
+
const prepareUnsupportedAuthHandoff = async () => {
|
|
52850
|
+
if (!service.returnUrl) return void 0;
|
|
52851
|
+
let scopes2;
|
|
52852
|
+
try {
|
|
52853
|
+
scopes2 = normalizeScopes2(opts.scope);
|
|
52854
|
+
} catch (err) {
|
|
52855
|
+
return { kind: "unavailable", reason: err instanceof Error ? err.message : String(err) };
|
|
52856
|
+
}
|
|
52857
|
+
const loginRes = await api.integrations.login({
|
|
52858
|
+
service: service.clientId,
|
|
52859
|
+
scopes: scopes2,
|
|
52860
|
+
target: opts.target?.trim() || void 0
|
|
52861
|
+
});
|
|
52862
|
+
if (!loginRes.ok || !loginRes.data) {
|
|
52863
|
+
return { kind: "unavailable", reason: loginFailureReason(loginRes) };
|
|
52864
|
+
}
|
|
52865
|
+
if (loginRes.data.status === "approval_required") {
|
|
52866
|
+
const requestId = loginRes.data.approval?.requestId ?? loginRes.data.requestId;
|
|
52867
|
+
if (!requestId) {
|
|
52868
|
+
return { kind: "unavailable", reason: "approval-required login response did not include a request id" };
|
|
52869
|
+
}
|
|
52870
|
+
return {
|
|
52871
|
+
kind: "approval_required",
|
|
52872
|
+
requestId,
|
|
52873
|
+
target: loginRes.data.approval?.target ?? null,
|
|
52874
|
+
actionCardMessageId: loginRes.data.approval?.actionCardMessageId ?? null
|
|
52875
|
+
};
|
|
52876
|
+
}
|
|
52877
|
+
if (!loginRes.data.requestId) {
|
|
52878
|
+
return { kind: "unavailable", reason: "agent login response did not include an internal one-time handoff request" };
|
|
52879
|
+
}
|
|
52880
|
+
const callbackHandoffUrl = buildAgentCallbackHandoffUrl(
|
|
52881
|
+
loginRes.data.service.returnUrl ?? service.returnUrl,
|
|
52882
|
+
loginRes.data.requestId
|
|
52883
|
+
);
|
|
52884
|
+
return callbackHandoffUrl ? { kind: "handoff_url", url: callbackHandoffUrl } : { kind: "unavailable", reason: "service return URL cannot be used for Agent Login callback handoff" };
|
|
52885
|
+
};
|
|
52886
|
+
const manifest = await fetchManifestForInvoke({ service, prepareUnsupportedAuthHandoff });
|
|
52588
52887
|
if (manifest.execution.mode !== "http_api") {
|
|
52589
52888
|
throw cliError("INTEGRATION_MANIFEST_UNSUPPORTED", "manifest execution mode is not http_api");
|
|
52590
52889
|
}
|
|
@@ -52609,25 +52908,36 @@ var integrationInvokeCommand = defineCommand(
|
|
|
52609
52908
|
const payload = parseActionPayload(opts);
|
|
52610
52909
|
validateRequiredParams(action, payload);
|
|
52611
52910
|
const scopes = normalizeScopes2(opts.scope);
|
|
52612
|
-
const
|
|
52613
|
-
|
|
52614
|
-
|
|
52615
|
-
|
|
52616
|
-
|
|
52617
|
-
|
|
52618
|
-
|
|
52619
|
-
|
|
52620
|
-
|
|
52621
|
-
|
|
52622
|
-
|
|
52623
|
-
|
|
52624
|
-
|
|
52625
|
-
|
|
52626
|
-
|
|
52911
|
+
const storedSession = scopes || opts.target ? null : loadStoredIntegrationSession({ service, agentContext, env: cmdCtx.env });
|
|
52912
|
+
let cookies = storedSession?.cookies ?? null;
|
|
52913
|
+
if (!cookies) {
|
|
52914
|
+
const loginRes = await api.integrations.login({
|
|
52915
|
+
service: service.clientId,
|
|
52916
|
+
scopes,
|
|
52917
|
+
target: opts.target?.trim() || void 0
|
|
52918
|
+
});
|
|
52919
|
+
if (!loginRes.ok || !loginRes.data) {
|
|
52920
|
+
const code = loginRes.status >= 500 ? "SERVER_5XX" : "INTEGRATION_LOGIN_FAILED";
|
|
52921
|
+
throw cliError(code, loginRes.error ?? `HTTP ${loginRes.status}`);
|
|
52922
|
+
}
|
|
52923
|
+
if (loginRes.data.status === "approval_required") {
|
|
52924
|
+
throw cliError(
|
|
52925
|
+
"INTEGRATION_APPROVAL_REQUIRED",
|
|
52926
|
+
"human approval is required before invoking this integration action",
|
|
52927
|
+
{ suggestedNextAction: "Ask a server owner/admin to approve the integration login request, then rerun the command." }
|
|
52928
|
+
);
|
|
52929
|
+
}
|
|
52930
|
+
const session = await ensureIntegrationServiceSession({
|
|
52931
|
+
login: loginRes.data,
|
|
52932
|
+
service,
|
|
52933
|
+
agentContext,
|
|
52934
|
+
env: cmdCtx.env,
|
|
52935
|
+
refresh: true
|
|
52936
|
+
});
|
|
52937
|
+
cookies = session.cookies;
|
|
52627
52938
|
}
|
|
52628
|
-
const cookies = await establishServiceSession({ login: loginRes.data, service });
|
|
52629
52939
|
const url2 = resolveActionUrl({ service, manifest, action });
|
|
52630
|
-
const result2 = await invokeHttpAction({ url: url2, action, payload, cookies });
|
|
52940
|
+
const result2 = await invokeHttpAction({ url: url2, action, payload, cookies, service });
|
|
52631
52941
|
if (opts.json) {
|
|
52632
52942
|
writeJson(cmdCtx.io, {
|
|
52633
52943
|
ok: true,
|
|
@@ -52862,6 +53172,18 @@ function formatReminderType(r) {
|
|
|
52862
53172
|
|
|
52863
53173
|
// src/commands/reminder/schedule.ts
|
|
52864
53174
|
function buildScheduleBody(opts, now = () => Intl.DateTimeFormat().resolvedOptions().timeZone) {
|
|
53175
|
+
const canonicalMessageId = opts.messageId?.trim();
|
|
53176
|
+
const legacyMsgId = opts.msgId?.trim();
|
|
53177
|
+
if (canonicalMessageId && legacyMsgId && canonicalMessageId !== legacyMsgId) {
|
|
53178
|
+
return {
|
|
53179
|
+
body: {},
|
|
53180
|
+
error: {
|
|
53181
|
+
code: "INVALID_ARG",
|
|
53182
|
+
message: "Pass only one message anchor; --msg-id is a deprecated alias for --message-id"
|
|
53183
|
+
}
|
|
53184
|
+
};
|
|
53185
|
+
}
|
|
53186
|
+
const msgId = canonicalMessageId || legacyMsgId || void 0;
|
|
52865
53187
|
if (!opts.delaySeconds && !opts.fireAt && !opts.repeat) {
|
|
52866
53188
|
return {
|
|
52867
53189
|
body: {},
|
|
@@ -52877,7 +53199,7 @@ function buildScheduleBody(opts, now = () => Intl.DateTimeFormat().resolvedOptio
|
|
|
52877
53199
|
}
|
|
52878
53200
|
};
|
|
52879
53201
|
}
|
|
52880
|
-
const body = { title: opts.title, msgId:
|
|
53202
|
+
const body = { title: opts.title, msgId: msgId ?? null };
|
|
52881
53203
|
if (opts.delaySeconds !== void 0) {
|
|
52882
53204
|
const n = Number(opts.delaySeconds);
|
|
52883
53205
|
if (!Number.isFinite(n) || !Number.isInteger(n) || n <= 0) {
|
|
@@ -52902,7 +53224,7 @@ function buildScheduleBody(opts, now = () => Intl.DateTimeFormat().resolvedOptio
|
|
|
52902
53224
|
body: {},
|
|
52903
53225
|
error: {
|
|
52904
53226
|
code: "INVALID_ARG",
|
|
52905
|
-
message: "Reminder create requires an anchor msgId; resolve a message first and pass --
|
|
53227
|
+
message: "Reminder create requires an anchor msgId; resolve a message first and pass --message-id"
|
|
52906
53228
|
}
|
|
52907
53229
|
};
|
|
52908
53230
|
}
|
|
@@ -52918,7 +53240,8 @@ var reminderScheduleCommand = defineCommand(
|
|
|
52918
53240
|
{ flags: "--fire-at <iso>", description: "ISO-8601 UTC timestamp, e.g. 2026-04-21T09:00:00Z. Use only for absolute calendar times" },
|
|
52919
53241
|
{ flags: "--repeat <rule>", description: "Recurrence rule: every:15m | every:2h | every:1d | daily@09:00 | weekly:mon,fri@09:00" },
|
|
52920
53242
|
{ flags: "--channel <ref>", description: "Optional channel to post a receipt message in (e.g. #general, dm:@alice)." },
|
|
52921
|
-
{ flags: "--
|
|
53243
|
+
{ flags: "--message-id <id>", description: "Message id (full or short) this reminder is anchored to. Required for agent-created reminders." },
|
|
53244
|
+
{ flags: "--msg-id <id>", description: "Deprecated alias for --message-id." }
|
|
52922
53245
|
]
|
|
52923
53246
|
},
|
|
52924
53247
|
async (ctx, opts) => {
|
|
@@ -53192,20 +53515,12 @@ function registerReminderLogCommand(parent, runtimeOptions = {}) {
|
|
|
53192
53515
|
}
|
|
53193
53516
|
|
|
53194
53517
|
// src/index.ts
|
|
53195
|
-
function resolveCliInvocationName(argv1) {
|
|
53196
|
-
if (process.env.SLOCK_CLI_INVOCATION_NAME === "raft") {
|
|
53197
|
-
return "raft";
|
|
53198
|
-
}
|
|
53199
|
-
const basename3 = argv1?.split(/[\\/]/).pop() ?? "";
|
|
53200
|
-
return basename3 === "raft" ? "raft" : "slock";
|
|
53201
|
-
}
|
|
53202
53518
|
var program2 = new Command();
|
|
53203
|
-
|
|
53204
|
-
|
|
53205
|
-
"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."
|
|
53519
|
+
program2.name("raft").description(
|
|
53520
|
+
"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."
|
|
53206
53521
|
).option(
|
|
53207
53522
|
"-p, --profile <slug>",
|
|
53208
|
-
"Use
|
|
53523
|
+
"Use an existing local profile credential. Equivalent to setting RAFT_PROFILE=<slug>. To create a new profile, use `raft agent login --profile-slug <slug>`."
|
|
53209
53524
|
).version(readCliVersion());
|
|
53210
53525
|
program2.hook("preAction", () => {
|
|
53211
53526
|
const opts = program2.opts();
|
|
@@ -53215,7 +53530,7 @@ program2.hook("preAction", () => {
|
|
|
53215
53530
|
});
|
|
53216
53531
|
var authCmd = program2.command("auth").description("Auth introspection");
|
|
53217
53532
|
registerWhoamiCommand(authCmd);
|
|
53218
|
-
var agentCmd = program2.command("agent").description("External agent onboarding (device-code login \u2192 sk_agent_* mint \u2192
|
|
53533
|
+
var agentCmd = program2.command("agent").description("External agent onboarding (device-code login \u2192 sk_agent_* mint \u2192 local profile credential)");
|
|
53219
53534
|
registerAgentLoginCommand(agentCmd);
|
|
53220
53535
|
registerAgentListCommand(agentCmd);
|
|
53221
53536
|
registerAgentBridgeCommand(agentCmd);
|
|
@@ -53234,7 +53549,7 @@ registerThreadUnfollowCommand(threadCmd);
|
|
|
53234
53549
|
var serverCmd = program2.command("server").description("Server / workspace introspection");
|
|
53235
53550
|
registerServerInfoCommand(serverCmd);
|
|
53236
53551
|
registerServerUpdateCommand(serverCmd);
|
|
53237
|
-
var manualCmd = program2.command("manual").description("
|
|
53552
|
+
var manualCmd = program2.command("manual").description("Raft Manual for Agents retrieval (canonical operating topics)");
|
|
53238
53553
|
registerKnowledgeGetCommand(manualCmd);
|
|
53239
53554
|
var knowledgeCmd = program2.command("knowledge").description("Legacy alias for `raft manual`");
|
|
53240
53555
|
registerKnowledgeGetCommand(knowledgeCmd);
|