@botiverse/raft-daemon 0.63.5 → 0.63.6
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-DZ25KV6L.js → chunk-DUWRNQQE.js} +502 -138
- package/dist/cli/index.js +331 -20
- package/dist/core.js +1 -1
- package/dist/{dist-KC6QHBPD.js → dist-S7UP42L2.js} +323 -20
- package/dist/index.js +1 -1
- package/package.json +2 -1
package/dist/cli/index.js
CHANGED
|
@@ -956,6 +956,58 @@ function delay(ms) {
|
|
|
956
956
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
957
957
|
}
|
|
958
958
|
|
|
959
|
+
// src/core/browserHandoff.ts
|
|
960
|
+
import { spawn } from "child_process";
|
|
961
|
+
function canInstallEnterToOpenUrl(input) {
|
|
962
|
+
const tty = input;
|
|
963
|
+
return Boolean(tty?.isTTY === true && typeof tty.on === "function" && typeof tty.off === "function");
|
|
964
|
+
}
|
|
965
|
+
function openUrlInBrowser(url2) {
|
|
966
|
+
const platform = process.platform;
|
|
967
|
+
let command;
|
|
968
|
+
let args;
|
|
969
|
+
if (platform === "darwin") {
|
|
970
|
+
command = "open";
|
|
971
|
+
args = [url2];
|
|
972
|
+
} else if (platform === "win32") {
|
|
973
|
+
command = "cmd";
|
|
974
|
+
args = ["/c", "start", "", url2];
|
|
975
|
+
} else {
|
|
976
|
+
command = "xdg-open";
|
|
977
|
+
args = [url2];
|
|
978
|
+
}
|
|
979
|
+
const child = spawn(command, args, {
|
|
980
|
+
detached: true,
|
|
981
|
+
stdio: "ignore",
|
|
982
|
+
windowsHide: true
|
|
983
|
+
});
|
|
984
|
+
child.on("error", () => {
|
|
985
|
+
});
|
|
986
|
+
child.unref();
|
|
987
|
+
}
|
|
988
|
+
function installEnterToOpenUrl(options) {
|
|
989
|
+
if (!canInstallEnterToOpenUrl(options.input)) return () => {
|
|
990
|
+
};
|
|
991
|
+
const input = options.input;
|
|
992
|
+
const openUrl = options.openUrl ?? openUrlInBrowser;
|
|
993
|
+
let active = true;
|
|
994
|
+
const cleanup = () => {
|
|
995
|
+
if (!active) return;
|
|
996
|
+
active = false;
|
|
997
|
+
input.off("data", onData);
|
|
998
|
+
input.pause?.();
|
|
999
|
+
};
|
|
1000
|
+
const onData = (chunk) => {
|
|
1001
|
+
const text = Buffer.isBuffer(chunk) ? chunk.toString("utf8") : String(chunk);
|
|
1002
|
+
if (!text.includes("\n") && !text.includes("\r")) return;
|
|
1003
|
+
cleanup();
|
|
1004
|
+
openUrl(options.url);
|
|
1005
|
+
};
|
|
1006
|
+
input.on("data", onData);
|
|
1007
|
+
input.resume?.();
|
|
1008
|
+
return cleanup;
|
|
1009
|
+
}
|
|
1010
|
+
|
|
959
1011
|
// src/commands/agent/list.ts
|
|
960
1012
|
function describeListResult(reason, serverUrl) {
|
|
961
1013
|
switch (reason) {
|
|
@@ -981,15 +1033,25 @@ var agentListCommand = defineCommand(
|
|
|
981
1033
|
throw cliError("INVALID_ARG", "--server is required");
|
|
982
1034
|
}
|
|
983
1035
|
let userSession;
|
|
1036
|
+
let cleanupEnterToOpen;
|
|
984
1037
|
try {
|
|
985
1038
|
userSession = await runDeviceCodeLogin({
|
|
986
1039
|
serverUrl: options.server,
|
|
987
1040
|
...options.clientName ? { clientName: options.clientName } : {},
|
|
988
|
-
onUserAction: ({ verificationUri, userCode, expiresInSeconds }) => {
|
|
1041
|
+
onUserAction: ({ verificationUri, verificationUriComplete, userCode, expiresInSeconds }) => {
|
|
1042
|
+
const enterOpensBrowser = canInstallEnterToOpenUrl(ctx.io.stdin);
|
|
1043
|
+
const url2 = verificationUriComplete ?? verificationUri;
|
|
989
1044
|
ctx.io.stderr.write(
|
|
990
|
-
`
|
|
1045
|
+
(enterOpensBrowser ? `Press Enter to open the browser authorization URL: ${url2}
|
|
1046
|
+
` : `Open this browser authorization URL: ${url2}
|
|
1047
|
+
`) + (verificationUriComplete ? ` Code is pre-filled. Approve the login in the browser; this command will continue automatically.
|
|
1048
|
+
` : ` Enter code ${userCode} and approve the login in the browser; this command will continue automatically.
|
|
1049
|
+
`) + ` Expires in ~${Math.max(0, Math.floor(expiresInSeconds / 60))}m.
|
|
991
1050
|
`
|
|
992
1051
|
);
|
|
1052
|
+
if (enterOpensBrowser) {
|
|
1053
|
+
cleanupEnterToOpen = installEnterToOpenUrl({ input: ctx.io.stdin, url: url2 });
|
|
1054
|
+
}
|
|
993
1055
|
}
|
|
994
1056
|
});
|
|
995
1057
|
} catch (err) {
|
|
@@ -997,6 +1059,8 @@ var agentListCommand = defineCommand(
|
|
|
997
1059
|
throw cliError(err.code, err.message, { cause: err });
|
|
998
1060
|
}
|
|
999
1061
|
throw err;
|
|
1062
|
+
} finally {
|
|
1063
|
+
cleanupEnterToOpen?.();
|
|
1000
1064
|
}
|
|
1001
1065
|
const res = await undiciFetch(
|
|
1002
1066
|
`${options.server.replace(/\/+$/, "")}/api/agents/manageable`,
|
|
@@ -1091,16 +1155,26 @@ var agentLoginCommand = defineCommand(
|
|
|
1091
1155
|
const idempotent = await handleExistingCredential(ctx, options, paths);
|
|
1092
1156
|
if (idempotent === "handled") return;
|
|
1093
1157
|
let userSession;
|
|
1158
|
+
let cleanupEnterToOpen;
|
|
1094
1159
|
try {
|
|
1095
1160
|
userSession = await runDeviceCodeLogin({
|
|
1096
1161
|
serverUrl: options.server,
|
|
1097
1162
|
...options.clientName ? { clientName: options.clientName } : {},
|
|
1098
1163
|
onUserAction: (action) => {
|
|
1099
|
-
ctx.io.
|
|
1164
|
+
const enterOpensBrowser = canInstallEnterToOpenUrl(ctx.io.stdin);
|
|
1165
|
+
ctx.io.stderr.write(formatVerificationHandoff(action, { enterOpensBrowser }));
|
|
1166
|
+
if (enterOpensBrowser) {
|
|
1167
|
+
cleanupEnterToOpen = installEnterToOpenUrl({
|
|
1168
|
+
input: ctx.io.stdin,
|
|
1169
|
+
url: action.verificationUriComplete ?? action.verificationUri
|
|
1170
|
+
});
|
|
1171
|
+
}
|
|
1100
1172
|
}
|
|
1101
1173
|
});
|
|
1102
1174
|
} catch (err) {
|
|
1103
1175
|
throw asCliError(err);
|
|
1176
|
+
} finally {
|
|
1177
|
+
cleanupEnterToOpen?.();
|
|
1104
1178
|
}
|
|
1105
1179
|
await mintAndPersist(ctx, options, userSession.accessToken, paths);
|
|
1106
1180
|
}
|
|
@@ -1299,14 +1373,19 @@ Next (if you are the agent): run \`raft manual get raft-cli-overview\`, then use
|
|
|
1299
1373
|
`
|
|
1300
1374
|
);
|
|
1301
1375
|
}
|
|
1302
|
-
function formatVerificationHandoff(action) {
|
|
1376
|
+
function formatVerificationHandoff(action, options) {
|
|
1303
1377
|
const mins = Math.max(0, Math.floor(action.expiresInSeconds / 60));
|
|
1378
|
+
const url2 = action.verificationUriComplete ?? action.verificationUri;
|
|
1379
|
+
const openLine = options.enterOpensBrowser ? `Press Enter to open the browser authorization URL: ${url2}
|
|
1380
|
+
` : `Open this browser authorization URL: ${url2}
|
|
1381
|
+
`;
|
|
1304
1382
|
if (action.verificationUriComplete) {
|
|
1305
|
-
return
|
|
1383
|
+
return openLine + ` Code is pre-filled. Approve the login in the browser; this command will continue automatically.
|
|
1306
1384
|
Expires in ~${mins}m.
|
|
1307
1385
|
`;
|
|
1308
1386
|
}
|
|
1309
|
-
return `
|
|
1387
|
+
return openLine + ` Enter code ${action.userCode} and approve the login in the browser; this command will continue automatically.
|
|
1388
|
+
Expires in ~${mins}m.
|
|
1310
1389
|
`;
|
|
1311
1390
|
}
|
|
1312
1391
|
function formatStartHandoff(authorization, options, paths) {
|
|
@@ -1316,10 +1395,12 @@ function formatStartHandoff(authorization, options, paths) {
|
|
|
1316
1395
|
out += `Login started for profile '${paths.profileSlug}'. Ask the user to approve in a browser:
|
|
1317
1396
|
`;
|
|
1318
1397
|
if (authorization.verificationUriComplete) {
|
|
1319
|
-
out += `
|
|
1398
|
+
out += ` Browser authorization URL (code pre-filled): ${authorization.verificationUriComplete}
|
|
1320
1399
|
`;
|
|
1321
1400
|
} else {
|
|
1322
|
-
out += `
|
|
1401
|
+
out += ` Browser authorization URL: ${authorization.verificationUri}
|
|
1402
|
+
`;
|
|
1403
|
+
out += ` Enter code ${authorization.userCode} and approve the login.
|
|
1323
1404
|
`;
|
|
1324
1405
|
}
|
|
1325
1406
|
out += ` Code expires in ~${mins}m.
|
|
@@ -1483,6 +1564,72 @@ function makeIsMember(members) {
|
|
|
1483
1564
|
return (value) => typeof value === "string" && set2.has(value);
|
|
1484
1565
|
}
|
|
1485
1566
|
|
|
1567
|
+
// ../shared/src/generated/runtimeProviderDisplayNames.ts
|
|
1568
|
+
var RUNTIME_PROVIDER_DISPLAY_NAMES = {
|
|
1569
|
+
"anthropic": "Anthropic",
|
|
1570
|
+
"deepseek": "DeepSeek",
|
|
1571
|
+
"fusecode": "FuseCode",
|
|
1572
|
+
"google": "Google",
|
|
1573
|
+
"openai": "OpenAI",
|
|
1574
|
+
"opencode": "OpenCode",
|
|
1575
|
+
"opencode-go": "OpenCode Go",
|
|
1576
|
+
"openrouter": "OpenRouter"
|
|
1577
|
+
};
|
|
1578
|
+
|
|
1579
|
+
// ../shared/src/runtimeProviderDisplay.ts
|
|
1580
|
+
function getRuntimeProviderDisplayName(providerId) {
|
|
1581
|
+
return RUNTIME_PROVIDER_DISPLAY_NAMES[providerId] ?? humanizeRuntimeProviderSegment(providerId);
|
|
1582
|
+
}
|
|
1583
|
+
function formatRuntimeProviderModelLabel(modelId) {
|
|
1584
|
+
const separatorIndex = modelId.indexOf("/");
|
|
1585
|
+
if (separatorIndex <= 0 || separatorIndex === modelId.length - 1) return modelId;
|
|
1586
|
+
const providerId = modelId.slice(0, separatorIndex);
|
|
1587
|
+
const modelName = modelId.slice(separatorIndex + 1);
|
|
1588
|
+
const providerLabel = getRuntimeProviderDisplayName(providerId);
|
|
1589
|
+
const modelParts = modelName.split("/");
|
|
1590
|
+
const modelLabel = humanizeRuntimeProviderSegment(modelParts[modelParts.length - 1] || modelName);
|
|
1591
|
+
if (modelParts.length === 1) return `${modelLabel} \xB7 ${providerLabel}`;
|
|
1592
|
+
const upstreamLabel = modelParts.slice(0, -1).map(getRuntimeProviderDisplayName).join(" / ");
|
|
1593
|
+
return `${modelLabel} \xB7 ${upstreamLabel} via ${providerLabel}`;
|
|
1594
|
+
}
|
|
1595
|
+
function humanizeRuntimeProviderSegment(value) {
|
|
1596
|
+
return value.replace(/\[(\d+)m\]/gi, "-$1m").split(/[-_/]/).filter(Boolean).map(formatRuntimeProviderLabelToken).join(" ");
|
|
1597
|
+
}
|
|
1598
|
+
function formatRuntimeProviderLabelToken(token) {
|
|
1599
|
+
const normalized = token.toLowerCase();
|
|
1600
|
+
const specialCases = {
|
|
1601
|
+
ai: "AI",
|
|
1602
|
+
api: "API",
|
|
1603
|
+
chatgpt: "ChatGPT",
|
|
1604
|
+
claude: "Claude",
|
|
1605
|
+
codestral: "Codestral",
|
|
1606
|
+
deepseek: "DeepSeek",
|
|
1607
|
+
flash: "Flash",
|
|
1608
|
+
free: "Free",
|
|
1609
|
+
gemini: "Gemini",
|
|
1610
|
+
glm: "GLM",
|
|
1611
|
+
gpt: "GPT",
|
|
1612
|
+
hy3: "HY3",
|
|
1613
|
+
kimi: "Kimi",
|
|
1614
|
+
minimax: "MiniMax",
|
|
1615
|
+
nano: "Nano",
|
|
1616
|
+
nemotron: "Nemotron",
|
|
1617
|
+
omni: "Omni",
|
|
1618
|
+
opus: "Opus",
|
|
1619
|
+
pro: "Pro",
|
|
1620
|
+
sonnet: "Sonnet",
|
|
1621
|
+
super: "Super"
|
|
1622
|
+
};
|
|
1623
|
+
if (specialCases[normalized]) return specialCases[normalized];
|
|
1624
|
+
if (normalized === "b" || normalized === "m") return normalized.toUpperCase();
|
|
1625
|
+
if (/^v\d+(\.\d+)?$/.test(normalized)) return normalized.toUpperCase();
|
|
1626
|
+
if (/^\d+m$/i.test(token)) return token.toUpperCase();
|
|
1627
|
+
if (/^\d+[bk]$/i.test(token)) return token.toUpperCase();
|
|
1628
|
+
if (/^m\d+(\.\d+)?$/i.test(token)) return token.toUpperCase();
|
|
1629
|
+
if (/^\d/.test(token)) return token;
|
|
1630
|
+
return normalized.charAt(0).toUpperCase() + normalized.slice(1);
|
|
1631
|
+
}
|
|
1632
|
+
|
|
1486
1633
|
// ../shared/src/slockRefs.ts
|
|
1487
1634
|
var SLOCK_REF_CHANNEL_NAME_PATTERN = String.raw`[\p{L}\p{N}_-]+`;
|
|
1488
1635
|
var SLOCK_REF_USER_NAME_PATTERN = SLOCK_REF_CHANNEL_NAME_PATTERN;
|
|
@@ -15443,11 +15590,36 @@ var integrationApproveAgentLoginOperationSchema = external_exports.object({
|
|
|
15443
15590
|
scopes: external_exports.array(external_exports.string().trim().min(1).max(120)).max(64),
|
|
15444
15591
|
draftHint: draftHintSchema
|
|
15445
15592
|
});
|
|
15593
|
+
var integrationAppDraftFieldsSchema = external_exports.object({
|
|
15594
|
+
name: external_exports.string().trim().min(1).max(120).optional(),
|
|
15595
|
+
description: external_exports.string().trim().max(1e3).optional(),
|
|
15596
|
+
homepageUrl: external_exports.string().trim().max(2e3).optional(),
|
|
15597
|
+
returnUrl: external_exports.string().trim().max(2e3).optional(),
|
|
15598
|
+
agentManifestUrl: external_exports.string().trim().max(2e3).optional()
|
|
15599
|
+
});
|
|
15600
|
+
var integrationRegisterAppOperationSchema = integrationAppDraftFieldsSchema.extend({
|
|
15601
|
+
type: external_exports.literal("integration:register_app"),
|
|
15602
|
+
name: external_exports.string().trim().min(1).max(120),
|
|
15603
|
+
clientKey: external_exports.string().trim().min(1).max(120),
|
|
15604
|
+
returnUrl: external_exports.string().trim().min(1).max(2e3),
|
|
15605
|
+
scopes: external_exports.array(external_exports.string().trim().min(1).max(120)).max(64).default([]),
|
|
15606
|
+
unsafeDemoUrlOverride: external_exports.boolean().optional(),
|
|
15607
|
+
draftHint: draftHintSchema
|
|
15608
|
+
});
|
|
15609
|
+
var integrationUpdateAppRegistrationOperationSchema = integrationAppDraftFieldsSchema.extend({
|
|
15610
|
+
type: external_exports.literal("integration:update_app_registration"),
|
|
15611
|
+
clientKey: external_exports.string().trim().min(1).max(120),
|
|
15612
|
+
scopes: external_exports.array(external_exports.string().trim().min(1).max(120)).max(64).optional(),
|
|
15613
|
+
unsafeDemoUrlOverride: external_exports.boolean().optional(),
|
|
15614
|
+
draftHint: draftHintSchema
|
|
15615
|
+
});
|
|
15446
15616
|
var actionCardActionSchema = external_exports.discriminatedUnion("type", [
|
|
15447
15617
|
channelCreateOperationSchema,
|
|
15448
15618
|
agentCreateOperationSchema,
|
|
15449
15619
|
channelAddMemberOperationSchema,
|
|
15450
|
-
integrationApproveAgentLoginOperationSchema
|
|
15620
|
+
integrationApproveAgentLoginOperationSchema,
|
|
15621
|
+
integrationRegisterAppOperationSchema,
|
|
15622
|
+
integrationUpdateAppRegistrationOperationSchema
|
|
15451
15623
|
]);
|
|
15452
15624
|
function validateActionCardAction(action) {
|
|
15453
15625
|
if (action.type === "agent:create") {
|
|
@@ -15461,6 +15633,12 @@ function validateActionCardAction(action) {
|
|
|
15461
15633
|
return "channel:add_member must include at least one human or agent";
|
|
15462
15634
|
}
|
|
15463
15635
|
}
|
|
15636
|
+
if (action.type === "integration:update_app_registration") {
|
|
15637
|
+
const hasMetadataPatch = action.name !== void 0 || action.description !== void 0 || action.homepageUrl !== void 0 || action.returnUrl !== void 0 || action.agentManifestUrl !== void 0 || action.scopes !== void 0;
|
|
15638
|
+
if (!hasMetadataPatch) {
|
|
15639
|
+
return "integration:update_app_registration must include at least one field to update";
|
|
15640
|
+
}
|
|
15641
|
+
}
|
|
15464
15642
|
return null;
|
|
15465
15643
|
}
|
|
15466
15644
|
|
|
@@ -15818,9 +15996,9 @@ var RUNTIME_MODELS = {
|
|
|
15818
15996
|
],
|
|
15819
15997
|
opencode: [
|
|
15820
15998
|
{ id: "default", label: "Configured Default / Auto", verified: "suggestion_only" },
|
|
15821
|
-
{ id: "deepseek/deepseek-v4-pro", label: "
|
|
15822
|
-
{ id: "openrouter/anthropic/claude-opus-4.5", label: "
|
|
15823
|
-
{ id: "fusecode/opus[1m]", label: "
|
|
15999
|
+
{ id: "deepseek/deepseek-v4-pro", label: formatRuntimeProviderModelLabel("deepseek/deepseek-v4-pro"), verified: "suggestion_only" },
|
|
16000
|
+
{ id: "openrouter/anthropic/claude-opus-4.5", label: formatRuntimeProviderModelLabel("openrouter/anthropic/claude-opus-4.5"), verified: "suggestion_only" },
|
|
16001
|
+
{ id: "fusecode/opus[1m]", label: formatRuntimeProviderModelLabel("fusecode/opus[1m]"), verified: "suggestion_only" }
|
|
15824
16002
|
],
|
|
15825
16003
|
pi: [
|
|
15826
16004
|
{ id: "default", label: "Configured Default / Auto", verified: "suggestion_only" }
|
|
@@ -15854,6 +16032,11 @@ var CONTROLLED_RUNTIME_ENV_KEYS = {
|
|
|
15854
16032
|
// this list in sync as new providers are added.
|
|
15855
16033
|
pi: Object.values(PI_BUILTIN_PROVIDER_ENV_KEYS)
|
|
15856
16034
|
};
|
|
16035
|
+
var PRO_SEAT_MONTHLY_USD = 10;
|
|
16036
|
+
var PRO_AGENT_SEAT_BLOCK_SIZE = 10;
|
|
16037
|
+
var PRO_AGENT_SEAT_FRACTION = 1 / PRO_AGENT_SEAT_BLOCK_SIZE;
|
|
16038
|
+
var PRO_SEAT_ANNUAL_MONTHLY_USD = 8.8;
|
|
16039
|
+
var PRO_PACK_AGENT_SEATS = PRO_AGENT_SEAT_BLOCK_SIZE;
|
|
15857
16040
|
var PLAN_CONFIG = {
|
|
15858
16041
|
free: {
|
|
15859
16042
|
displayName: "Free",
|
|
@@ -15880,9 +16063,9 @@ var PLAN_CONFIG = {
|
|
|
15880
16063
|
},
|
|
15881
16064
|
pro: {
|
|
15882
16065
|
displayName: "Pro",
|
|
15883
|
-
limits: { maxMachines: -1, maxAgents:
|
|
16066
|
+
limits: { maxMachines: -1, maxAgents: PRO_PACK_AGENT_SEATS, maxChannels: -1, messageHistoryDays: -1, includedAgents: PRO_PACK_AGENT_SEATS },
|
|
15884
16067
|
comingSoon: false,
|
|
15885
|
-
price:
|
|
16068
|
+
price: PRO_SEAT_MONTHLY_USD,
|
|
15886
16069
|
extraAgentPrice: 0
|
|
15887
16070
|
}
|
|
15888
16071
|
};
|
|
@@ -15892,8 +16075,8 @@ var DISPLAY_PLAN_CONFIG = {
|
|
|
15892
16075
|
displayName: "Pro",
|
|
15893
16076
|
limits: { maxMachines: -1, maxAgents: -1, maxChannels: -1, messageHistoryDays: -1, includedAgents: -1 },
|
|
15894
16077
|
comingSoon: false,
|
|
15895
|
-
price:
|
|
15896
|
-
priceCadence: "/ seat
|
|
16078
|
+
price: PRO_SEAT_MONTHLY_USD,
|
|
16079
|
+
priceCadence: "/ seat / month",
|
|
15897
16080
|
extraAgentPrice: 0,
|
|
15898
16081
|
displayFeatures: [
|
|
15899
16082
|
"Everything in Free",
|
|
@@ -15903,7 +16086,7 @@ var DISPLAY_PLAN_CONFIG = {
|
|
|
15903
16086
|
"More professional features coming soon"
|
|
15904
16087
|
],
|
|
15905
16088
|
displayDescription: "For builders and teams scaling agent collaboration.",
|
|
15906
|
-
displayNote:
|
|
16089
|
+
displayNote: `$${PRO_SEAT_ANNUAL_MONTHLY_USD.toFixed(2)} / seat / month when billed yearly. Each human uses 1 seat; each agent uses ${PRO_AGENT_SEAT_FRACTION} seat.`
|
|
15907
16090
|
},
|
|
15908
16091
|
enterprise: {
|
|
15909
16092
|
displayName: "Enterprise",
|
|
@@ -17237,7 +17420,7 @@ var actionPrepareCommand = defineCommand(
|
|
|
17237
17420
|
options: [
|
|
17238
17421
|
{
|
|
17239
17422
|
flags: "--target <target>",
|
|
17240
|
-
description: "Channel/DM/thread target to post the card. Same format as raft message send: '#channel', 'dm:@peer', '#channel:shortid'"
|
|
17423
|
+
description: "Channel/DM/thread target to post the card. Same format as raft message send: '#channel', 'dm:@peer', '#channel:shortid', 'dm:@peer:shortid'"
|
|
17241
17424
|
}
|
|
17242
17425
|
]
|
|
17243
17426
|
},
|
|
@@ -19103,8 +19286,10 @@ var attachmentUploadCommand = defineCommand(
|
|
|
19103
19286
|
form
|
|
19104
19287
|
);
|
|
19105
19288
|
if (!res.ok) {
|
|
19106
|
-
const code = res.status >= 500 ? "SERVER_5XX" : "UPLOAD_FAILED";
|
|
19107
|
-
throw cliError(code, res.error ?? `HTTP ${res.status}
|
|
19289
|
+
const code = res.errorCode ?? (res.status >= 500 ? "SERVER_5XX" : "UPLOAD_FAILED");
|
|
19290
|
+
throw cliError(code, res.error ?? `HTTP ${res.status}`, {
|
|
19291
|
+
suggestedNextAction: res.suggestedNextAction ?? void 0
|
|
19292
|
+
});
|
|
19108
19293
|
}
|
|
19109
19294
|
const d = res.data;
|
|
19110
19295
|
writeText(ctx.io, `File uploaded: ${d.filename} (${(d.sizeBytes / 1024).toFixed(1)}KB)
|
|
@@ -20525,6 +20710,131 @@ function registerIntegrationEnvCommand(parent, runtimeOptions = {}) {
|
|
|
20525
20710
|
registerCliCommand(parent, integrationEnvCommand, runtimeOptions);
|
|
20526
20711
|
}
|
|
20527
20712
|
|
|
20713
|
+
// src/commands/integration/app.ts
|
|
20714
|
+
function normalizeScopes2(raw) {
|
|
20715
|
+
if (!raw || raw.length === 0) return void 0;
|
|
20716
|
+
const scopes = Array.from(new Set(
|
|
20717
|
+
raw.flatMap((value) => value.split(",")).map((value) => value.trim()).filter(Boolean)
|
|
20718
|
+
)).sort();
|
|
20719
|
+
if (scopes.length === 0) {
|
|
20720
|
+
throw cliError("INVALID_ARG", "--scope must include at least one non-empty scope");
|
|
20721
|
+
}
|
|
20722
|
+
return scopes;
|
|
20723
|
+
}
|
|
20724
|
+
function requiredTrimmed(value, flag) {
|
|
20725
|
+
const trimmed = value?.trim() ?? "";
|
|
20726
|
+
if (!trimmed) throw cliError("INVALID_ARG", `${flag} is required`);
|
|
20727
|
+
return trimmed;
|
|
20728
|
+
}
|
|
20729
|
+
function optionalTrimmed(value) {
|
|
20730
|
+
return value?.trim() || void 0;
|
|
20731
|
+
}
|
|
20732
|
+
function formatAppPrepare(data) {
|
|
20733
|
+
const lines = [
|
|
20734
|
+
`Integration app ${data.mode} card prepared`,
|
|
20735
|
+
`client key: ${data.action.clientKey}`,
|
|
20736
|
+
`card: ${data.actionCardMessageId}`,
|
|
20737
|
+
`target: ${data.target}`
|
|
20738
|
+
];
|
|
20739
|
+
if (data.action.name) lines.push(`name: ${data.action.name}`);
|
|
20740
|
+
if (data.action.homepageUrl) lines.push(`app URL: ${data.action.homepageUrl}`);
|
|
20741
|
+
if (data.action.returnUrl) lines.push(`redirect URL: ${data.action.returnUrl}`);
|
|
20742
|
+
if (data.action.agentManifestUrl) lines.push(`agent manifest: ${data.action.agentManifestUrl}`);
|
|
20743
|
+
if (data.action.scopes) lines.push(`scopes: ${data.action.scopes.length > 0 ? data.action.scopes.join(", ") : "-"}`);
|
|
20744
|
+
if (data.action.unsafeDemoUrlOverride) lines.push("unsafe demo URL override: requested");
|
|
20745
|
+
lines.push("next: ask a server owner/admin to review and execute the action card");
|
|
20746
|
+
lines.push("secret: not stored in the card; after owner/admin execution, the requester agent receives a private one-time handoff");
|
|
20747
|
+
return lines.join("\n");
|
|
20748
|
+
}
|
|
20749
|
+
async function prepareApp(mode, ctx, opts) {
|
|
20750
|
+
const target = requiredTrimmed(opts.target, "--target");
|
|
20751
|
+
const clientKey = requiredTrimmed(opts.clientKey, "--client-key");
|
|
20752
|
+
const scopes = normalizeScopes2([...opts.scope ?? [], ...opts.scopes ?? []]);
|
|
20753
|
+
const agentContext = ctx.loadAgentContext();
|
|
20754
|
+
const client = ctx.createApiClient(agentContext);
|
|
20755
|
+
const body = {
|
|
20756
|
+
mode,
|
|
20757
|
+
target,
|
|
20758
|
+
clientKey,
|
|
20759
|
+
name: optionalTrimmed(opts.name),
|
|
20760
|
+
description: optionalTrimmed(opts.description),
|
|
20761
|
+
homepageUrl: optionalTrimmed(opts.homepageUrl) ?? optionalTrimmed(opts.appUrl),
|
|
20762
|
+
returnUrl: optionalTrimmed(opts.redirectUrl),
|
|
20763
|
+
agentManifestUrl: optionalTrimmed(opts.agentManifestUrl),
|
|
20764
|
+
scopes,
|
|
20765
|
+
unsafeDemoUrlOverride: opts.unsafeDemoUrlOverride === true
|
|
20766
|
+
};
|
|
20767
|
+
if (mode === "register") {
|
|
20768
|
+
requiredTrimmed(body.name, "--name");
|
|
20769
|
+
requiredTrimmed(body.returnUrl, "--redirect-url");
|
|
20770
|
+
}
|
|
20771
|
+
const res = await client.request(
|
|
20772
|
+
"POST",
|
|
20773
|
+
`/internal/agent/${encodeURIComponent(agentContext.agentId)}/integrations/app/prepare`,
|
|
20774
|
+
body
|
|
20775
|
+
);
|
|
20776
|
+
if (!res.ok || !res.data) {
|
|
20777
|
+
const code = res.status >= 500 ? "SERVER_5XX" : "INTEGRATION_APP_PREPARE_FAILED";
|
|
20778
|
+
throw cliError(code, res.error ?? `HTTP ${res.status}`);
|
|
20779
|
+
}
|
|
20780
|
+
if (opts.json) {
|
|
20781
|
+
writeJson(ctx.io, { ok: true, data: res.data });
|
|
20782
|
+
return;
|
|
20783
|
+
}
|
|
20784
|
+
writeText(ctx.io, `${formatAppPrepare(res.data)}
|
|
20785
|
+
`);
|
|
20786
|
+
}
|
|
20787
|
+
var sharedOptions = [
|
|
20788
|
+
{ flags: "--client-key <key>", description: "Stable app client key / OAuth client_id to reserve or update" },
|
|
20789
|
+
{ flags: "--name <name>", description: "App display name" },
|
|
20790
|
+
{ flags: "--redirect-url <url>", description: "OAuth redirect/callback URL" },
|
|
20791
|
+
{ flags: "--app-url <url>", description: "App homepage URL" },
|
|
20792
|
+
{ flags: "--homepage-url <url>", description: "App homepage URL (alias-friendly explicit name)" },
|
|
20793
|
+
{ flags: "--description <text>", description: "App description" },
|
|
20794
|
+
{ flags: "--agent-manifest-url <url>", description: "Optional agent behavior manifest URL" },
|
|
20795
|
+
{
|
|
20796
|
+
flags: "--scope <scope>",
|
|
20797
|
+
description: "Requested/displayed scope; can be repeated or comma-separated",
|
|
20798
|
+
parse: (value, previous = []) => {
|
|
20799
|
+
previous.push(value);
|
|
20800
|
+
return previous;
|
|
20801
|
+
}
|
|
20802
|
+
},
|
|
20803
|
+
{
|
|
20804
|
+
flags: "--scopes <scopes>",
|
|
20805
|
+
description: "Requested/displayed scopes; alias for --scope, comma-separated",
|
|
20806
|
+
parse: (value, previous = []) => {
|
|
20807
|
+
previous.push(value);
|
|
20808
|
+
return previous;
|
|
20809
|
+
}
|
|
20810
|
+
},
|
|
20811
|
+
{ flags: "--unsafe-demo-url-override", description: "Explicitly mark localhost/private URL use as an unsafe demo override" },
|
|
20812
|
+
{ flags: "--target <target>", description: "Channel/DM/thread target to post the human action card" },
|
|
20813
|
+
{ flags: "--json", description: "Emit machine-readable JSON" }
|
|
20814
|
+
];
|
|
20815
|
+
var integrationAppPrepareRegisterCommand = defineCommand(
|
|
20816
|
+
{
|
|
20817
|
+
name: "register",
|
|
20818
|
+
description: "Prepare a third-party app registration action card for a human owner/admin to commit",
|
|
20819
|
+
options: sharedOptions
|
|
20820
|
+
},
|
|
20821
|
+
async (ctx, opts) => prepareApp("register", ctx, opts)
|
|
20822
|
+
);
|
|
20823
|
+
var integrationAppPrepareUpdateCommand = defineCommand(
|
|
20824
|
+
{
|
|
20825
|
+
name: "update",
|
|
20826
|
+
description: "Prepare a third-party app registration update action card for a human owner/admin to commit",
|
|
20827
|
+
options: sharedOptions
|
|
20828
|
+
},
|
|
20829
|
+
async (ctx, opts) => prepareApp("update", ctx, opts)
|
|
20830
|
+
);
|
|
20831
|
+
function registerIntegrationAppCommands(parent, runtimeOptions = {}) {
|
|
20832
|
+
const appCmd = parent.command("app").description("Third-party app registration preparation");
|
|
20833
|
+
const prepareCmd = appCmd.command("prepare").description("Prepare app registration/update action cards");
|
|
20834
|
+
registerCliCommand(prepareCmd, integrationAppPrepareRegisterCommand, runtimeOptions);
|
|
20835
|
+
registerCliCommand(prepareCmd, integrationAppPrepareUpdateCommand, runtimeOptions);
|
|
20836
|
+
}
|
|
20837
|
+
|
|
20528
20838
|
// src/commands/reminder/_format.ts
|
|
20529
20839
|
var MODIFY_HINT = "(to modify: snooze/update/cancel; raft reminder --help)";
|
|
20530
20840
|
function formatReminder(r) {
|
|
@@ -20981,6 +21291,7 @@ var integrationCmd = program.command("integration").description("Third-party ser
|
|
|
20981
21291
|
registerIntegrationListCommand(integrationCmd);
|
|
20982
21292
|
registerIntegrationLoginCommand(integrationCmd);
|
|
20983
21293
|
registerIntegrationEnvCommand(integrationCmd);
|
|
21294
|
+
registerIntegrationAppCommands(integrationCmd);
|
|
20984
21295
|
var reminderCmd = program.command("reminder").description("Reminder operations");
|
|
20985
21296
|
registerReminderScheduleCommand(reminderCmd);
|
|
20986
21297
|
registerReminderListCommand(reminderCmd);
|