@botiverse/raft-daemon 0.65.0 → 0.66.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-53ZFBLI4.js → chunk-EX73HXGE.js} +959 -120
- package/dist/cli/index.js +2185 -525
- package/dist/core.js +1 -1
- package/dist/{dist-OGRAMTIO.js → dist-PCKZII47.js} +2154 -516
- package/dist/index.js +1 -1
- package/package.json +3 -3
package/dist/cli/index.js
CHANGED
|
@@ -998,7 +998,7 @@ var require_command = __commonJS({
|
|
|
998
998
|
var EventEmitter = __require("events").EventEmitter;
|
|
999
999
|
var childProcess = __require("child_process");
|
|
1000
1000
|
var path9 = __require("path");
|
|
1001
|
-
var
|
|
1001
|
+
var fs7 = __require("fs");
|
|
1002
1002
|
var process3 = __require("process");
|
|
1003
1003
|
var { Argument: Argument2, humanReadableArgName } = require_argument();
|
|
1004
1004
|
var { CommanderError: CommanderError2 } = require_error();
|
|
@@ -1931,10 +1931,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1931
1931
|
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
1932
1932
|
function findFile(baseDir, baseName) {
|
|
1933
1933
|
const localBin = path9.resolve(baseDir, baseName);
|
|
1934
|
-
if (
|
|
1934
|
+
if (fs7.existsSync(localBin)) return localBin;
|
|
1935
1935
|
if (sourceExt.includes(path9.extname(baseName))) return void 0;
|
|
1936
1936
|
const foundExt = sourceExt.find(
|
|
1937
|
-
(ext) =>
|
|
1937
|
+
(ext) => fs7.existsSync(`${localBin}${ext}`)
|
|
1938
1938
|
);
|
|
1939
1939
|
if (foundExt) return `${localBin}${foundExt}`;
|
|
1940
1940
|
return void 0;
|
|
@@ -1946,7 +1946,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1946
1946
|
if (this._scriptPath) {
|
|
1947
1947
|
let resolvedScriptPath;
|
|
1948
1948
|
try {
|
|
1949
|
-
resolvedScriptPath =
|
|
1949
|
+
resolvedScriptPath = fs7.realpathSync(this._scriptPath);
|
|
1950
1950
|
} catch (err) {
|
|
1951
1951
|
resolvedScriptPath = this._scriptPath;
|
|
1952
1952
|
}
|
|
@@ -15542,7 +15542,7 @@ var require_mock_utils = __commonJS({
|
|
|
15542
15542
|
}
|
|
15543
15543
|
return normalizedQp;
|
|
15544
15544
|
}
|
|
15545
|
-
function
|
|
15545
|
+
function safeUrl2(path9) {
|
|
15546
15546
|
if (typeof path9 !== "string") {
|
|
15547
15547
|
return path9;
|
|
15548
15548
|
}
|
|
@@ -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" ? safeUrl2(basePath) : basePath;
|
|
15582
15582
|
const resolvedPathWithoutTrailingSlash = removeTrailingSlash(resolvedPath);
|
|
15583
15583
|
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path9, ignoreTrailingSlash }) => {
|
|
15584
|
-
return ignoreTrailingSlash ? matchValue(removeTrailingSlash(
|
|
15584
|
+
return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl2(path9)), resolvedPathWithoutTrailingSlash) : matchValue(safeUrl2(path9), resolvedPath);
|
|
15585
15585
|
});
|
|
15586
15586
|
if (matchedMockDispatches.length === 0) {
|
|
15587
15587
|
throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
|
|
@@ -42798,6 +42798,21 @@ var agentApiHistoryQuerySchema = passthroughObject({
|
|
|
42798
42798
|
around: optionalStringSchema,
|
|
42799
42799
|
limit: optionalStringSchema
|
|
42800
42800
|
});
|
|
42801
|
+
var agentApiKnowledgeGetQuerySchema = passthroughObject({
|
|
42802
|
+
topic: external_exports.string().trim().min(1),
|
|
42803
|
+
reason: optionalStringSchema,
|
|
42804
|
+
turn_id: optionalStringSchema,
|
|
42805
|
+
trace_id: optionalStringSchema
|
|
42806
|
+
});
|
|
42807
|
+
var agentApiKnowledgeGetResponseSchema = passthroughObject({
|
|
42808
|
+
ok: external_exports.literal(true),
|
|
42809
|
+
docId: external_exports.string(),
|
|
42810
|
+
topicOrPath: external_exports.string(),
|
|
42811
|
+
docVersion: external_exports.string(),
|
|
42812
|
+
docState: external_exports.string(),
|
|
42813
|
+
contentType: external_exports.string(),
|
|
42814
|
+
content: external_exports.string()
|
|
42815
|
+
});
|
|
42801
42816
|
var agentApiMessageSearchQuerySchema = passthroughObject({
|
|
42802
42817
|
q: optionalStringSchema,
|
|
42803
42818
|
channel: optionalStringSchema,
|
|
@@ -42835,6 +42850,58 @@ var agentApiMessageReactionBodySchema = passthroughObject({
|
|
|
42835
42850
|
var agentApiChannelMembershipParamsSchema = passthroughObject({
|
|
42836
42851
|
channelId: external_exports.string().trim().min(1).transform(asChannelId)
|
|
42837
42852
|
});
|
|
42853
|
+
var agentApiAttachmentDownloadParamsSchema = passthroughObject({
|
|
42854
|
+
attachmentId: external_exports.string().trim().min(1)
|
|
42855
|
+
});
|
|
42856
|
+
var agentApiAttachmentCommentsParamsSchema = passthroughObject({
|
|
42857
|
+
attachmentId: external_exports.string().trim().min(1)
|
|
42858
|
+
});
|
|
42859
|
+
var agentApiAttachmentCommentsQuerySchema = passthroughObject({
|
|
42860
|
+
limit: optionalStringSchema
|
|
42861
|
+
});
|
|
42862
|
+
var agentApiAttachmentCommentAnchorSchema = passthroughObject({
|
|
42863
|
+
type: external_exports.string().trim().min(1),
|
|
42864
|
+
data: external_exports.record(external_exports.string(), external_exports.unknown())
|
|
42865
|
+
});
|
|
42866
|
+
var agentApiAttachmentCommentReactionSchema = passthroughObject({
|
|
42867
|
+
emoji: external_exports.string().trim().min(1),
|
|
42868
|
+
reactorType: external_exports.string().trim().min(1),
|
|
42869
|
+
reactorId: external_exports.string().trim().min(1),
|
|
42870
|
+
createdAt: external_exports.string().datetime()
|
|
42871
|
+
});
|
|
42872
|
+
var agentApiAttachmentCommentResolvedBySchema = passthroughObject({
|
|
42873
|
+
reactorId: external_exports.string().trim().min(1),
|
|
42874
|
+
reactorType: external_exports.string().trim().min(1)
|
|
42875
|
+
});
|
|
42876
|
+
var agentApiAttachmentCommentSchema = passthroughObject({
|
|
42877
|
+
id: external_exports.string().trim().min(1),
|
|
42878
|
+
channelId: external_exports.string().trim().min(1).optional(),
|
|
42879
|
+
senderId: external_exports.string().trim().min(1),
|
|
42880
|
+
senderType: external_exports.enum(["user", "agent"]),
|
|
42881
|
+
senderName: external_exports.string().trim().min(1),
|
|
42882
|
+
senderAvatarUrl: nullableStringSchema.optional(),
|
|
42883
|
+
senderGravatarHash: nullableStringSchema.optional(),
|
|
42884
|
+
content: external_exports.string(),
|
|
42885
|
+
createdAt: external_exports.string().datetime(),
|
|
42886
|
+
reactions: external_exports.array(agentApiAttachmentCommentReactionSchema),
|
|
42887
|
+
anchor: agentApiAttachmentCommentAnchorSchema.nullable(),
|
|
42888
|
+
resolved: external_exports.boolean().optional(),
|
|
42889
|
+
resolvedBy: agentApiAttachmentCommentResolvedBySchema.nullable().optional(),
|
|
42890
|
+
resolvedAt: external_exports.string().datetime().nullable().optional()
|
|
42891
|
+
});
|
|
42892
|
+
var agentApiAttachmentCommentsResponseSchema = passthroughObject({
|
|
42893
|
+
comments: external_exports.array(agentApiAttachmentCommentSchema),
|
|
42894
|
+
threadChannelId: nullableStringSchema.optional(),
|
|
42895
|
+
viewer: passthroughObject({
|
|
42896
|
+
canComment: external_exports.boolean(),
|
|
42897
|
+
reason: external_exports.string().optional(),
|
|
42898
|
+
canResolve: external_exports.boolean(),
|
|
42899
|
+
resolveAction: passthroughObject({
|
|
42900
|
+
type: external_exports.string().trim().min(1),
|
|
42901
|
+
emoji: external_exports.string().trim().min(1)
|
|
42902
|
+
}).optional()
|
|
42903
|
+
}).optional()
|
|
42904
|
+
});
|
|
42838
42905
|
var agentApiChannelMembersQuerySchema = passthroughObject({
|
|
42839
42906
|
channel: external_exports.string().trim().min(1)
|
|
42840
42907
|
});
|
|
@@ -42989,6 +43056,9 @@ var agentApiIntegrationAppPrepareBodySchema = passthroughObject({
|
|
|
42989
43056
|
unsafeDemoUrlOverride: optionalBooleanSchema,
|
|
42990
43057
|
draftHint: optionalStringSchema
|
|
42991
43058
|
});
|
|
43059
|
+
var agentApiIntegrationAppRotateSecretBodySchema = passthroughObject({
|
|
43060
|
+
clientKey: external_exports.string().trim().min(1)
|
|
43061
|
+
});
|
|
42992
43062
|
var agentApiActionPrepareBodySchema = passthroughObject({
|
|
42993
43063
|
target: external_exports.string().trim().min(1),
|
|
42994
43064
|
action: actionCardActionSchema
|
|
@@ -42996,6 +43066,9 @@ var agentApiActionPrepareBodySchema = passthroughObject({
|
|
|
42996
43066
|
var agentApiServerInfoResponseSchema = passthroughObject({
|
|
42997
43067
|
runtimeContext: passthroughObject({
|
|
42998
43068
|
agentId: external_exports.string(),
|
|
43069
|
+
runtime: external_exports.string().optional(),
|
|
43070
|
+
model: external_exports.string().optional(),
|
|
43071
|
+
reasoningEffort: reasoningEffortSchema.nullable().optional(),
|
|
42999
43072
|
serverId: external_exports.string(),
|
|
43000
43073
|
machineId: external_exports.string().nullable().optional(),
|
|
43001
43074
|
machineName: external_exports.string().nullable().optional(),
|
|
@@ -43012,10 +43085,12 @@ var agentApiServerInfoResponseSchema = passthroughObject({
|
|
|
43012
43085
|
joined: external_exports.boolean()
|
|
43013
43086
|
})),
|
|
43014
43087
|
agents: external_exports.array(passthroughObject({
|
|
43015
|
-
name: external_exports.string()
|
|
43088
|
+
name: external_exports.string(),
|
|
43089
|
+
role: external_exports.enum(["owner", "admin", "member"]).nullable().optional()
|
|
43016
43090
|
})),
|
|
43017
43091
|
humans: external_exports.array(passthroughObject({
|
|
43018
|
-
name: external_exports.string()
|
|
43092
|
+
name: external_exports.string(),
|
|
43093
|
+
role: external_exports.enum(["owner", "admin", "member"]).nullable().optional()
|
|
43019
43094
|
}))
|
|
43020
43095
|
});
|
|
43021
43096
|
var agentApiMentionActionsPendingQuerySchema = passthroughObject({
|
|
@@ -43090,6 +43165,12 @@ var agentApiIntegrationAppPrepareResponseSchema = passthroughObject({
|
|
|
43090
43165
|
integrationUpdateAppRegistrationOperationSchema
|
|
43091
43166
|
])
|
|
43092
43167
|
});
|
|
43168
|
+
var agentApiIntegrationAppRotateSecretResponseSchema = passthroughObject({
|
|
43169
|
+
clientId: external_exports.string(),
|
|
43170
|
+
clientKey: external_exports.string(),
|
|
43171
|
+
clientName: external_exports.string(),
|
|
43172
|
+
clientSecret: external_exports.string()
|
|
43173
|
+
});
|
|
43093
43174
|
var agentApiAttachmentEnvelopeSchema = passthroughObject({
|
|
43094
43175
|
id: external_exports.string(),
|
|
43095
43176
|
filename: external_exports.string()
|
|
@@ -43225,6 +43306,21 @@ var agentApiChannelMembersResponseSchema = passthroughObject({
|
|
|
43225
43306
|
role: optionalStringSchema
|
|
43226
43307
|
}))
|
|
43227
43308
|
});
|
|
43309
|
+
var agentApiChannelMuteResponseSchema = passthroughObject({
|
|
43310
|
+
activityMuted: optionalBooleanSchema,
|
|
43311
|
+
muteFromSeq: nullableNumberSchema.optional(),
|
|
43312
|
+
attention: passthroughObject({
|
|
43313
|
+
state: optionalStringSchema,
|
|
43314
|
+
ordinaryActivity: optionalStringSchema,
|
|
43315
|
+
unmuteCommand: optionalStringSchema,
|
|
43316
|
+
unmuteApi: optionalStringSchema,
|
|
43317
|
+
muteCommand: optionalStringSchema,
|
|
43318
|
+
muteApi: optionalStringSchema,
|
|
43319
|
+
stillArrives: optionalStringArraySchema,
|
|
43320
|
+
threadBoundary: optionalStringSchema,
|
|
43321
|
+
catchUp: optionalStringSchema
|
|
43322
|
+
}).optional()
|
|
43323
|
+
});
|
|
43228
43324
|
var agentApiTaskClaimResultSchema = passthroughObject({
|
|
43229
43325
|
taskNumber: external_exports.number().int().positive().optional(),
|
|
43230
43326
|
messageId: optionalStringSchema,
|
|
@@ -43337,6 +43433,16 @@ var agentApiContract = {
|
|
|
43337
43433
|
request: { query: agentApiHistoryQuerySchema },
|
|
43338
43434
|
response: { body: agentApiHistoryResponseSchema }
|
|
43339
43435
|
}),
|
|
43436
|
+
knowledgeGet: route({
|
|
43437
|
+
key: "knowledgeGet",
|
|
43438
|
+
method: "GET",
|
|
43439
|
+
path: "/knowledge",
|
|
43440
|
+
client: { resource: "knowledge", method: "get" },
|
|
43441
|
+
capability: "knowledge",
|
|
43442
|
+
description: "Fetch a Slock Manual for Agents topic from the current server.",
|
|
43443
|
+
request: { query: agentApiKnowledgeGetQuerySchema },
|
|
43444
|
+
response: { body: agentApiKnowledgeGetResponseSchema }
|
|
43445
|
+
}),
|
|
43340
43446
|
messageSend: route({
|
|
43341
43447
|
key: "messageSend",
|
|
43342
43448
|
method: "POST",
|
|
@@ -43407,6 +43513,26 @@ var agentApiContract = {
|
|
|
43407
43513
|
request: { params: agentApiChannelMembershipParamsSchema },
|
|
43408
43514
|
response: { body: agentApiOkResponseSchema }
|
|
43409
43515
|
}),
|
|
43516
|
+
channelMute: route({
|
|
43517
|
+
key: "channelMute",
|
|
43518
|
+
method: "POST",
|
|
43519
|
+
path: "/channels/:channelId/mute",
|
|
43520
|
+
client: { resource: "channels", method: "mute" },
|
|
43521
|
+
capability: "channels",
|
|
43522
|
+
description: "Mute ordinary activity delivery for a visible regular channel as the bound agent credential.",
|
|
43523
|
+
request: { params: agentApiChannelMembershipParamsSchema },
|
|
43524
|
+
response: { body: agentApiChannelMuteResponseSchema }
|
|
43525
|
+
}),
|
|
43526
|
+
channelUnmute: route({
|
|
43527
|
+
key: "channelUnmute",
|
|
43528
|
+
method: "POST",
|
|
43529
|
+
path: "/channels/:channelId/unmute",
|
|
43530
|
+
client: { resource: "channels", method: "unmute" },
|
|
43531
|
+
capability: "channels",
|
|
43532
|
+
description: "Unmute ordinary activity delivery for a visible regular channel as the bound agent credential.",
|
|
43533
|
+
request: { params: agentApiChannelMembershipParamsSchema },
|
|
43534
|
+
response: { body: agentApiChannelMuteResponseSchema }
|
|
43535
|
+
}),
|
|
43410
43536
|
channelMembers: route({
|
|
43411
43537
|
key: "channelMembers",
|
|
43412
43538
|
method: "GET",
|
|
@@ -43597,6 +43723,16 @@ var agentApiContract = {
|
|
|
43597
43723
|
request: { body: agentApiProfileUpdateBodySchema },
|
|
43598
43724
|
response: { body: agentApiProfileViewSchema }
|
|
43599
43725
|
}),
|
|
43726
|
+
profileAvatarUpdate: route({
|
|
43727
|
+
key: "profileAvatarUpdate",
|
|
43728
|
+
method: "POST",
|
|
43729
|
+
path: "/profile/avatar",
|
|
43730
|
+
client: { resource: "profile", method: "updateAvatar" },
|
|
43731
|
+
capability: "server",
|
|
43732
|
+
description: "Update the bound agent profile avatar using multipart form data.",
|
|
43733
|
+
request: {},
|
|
43734
|
+
response: { body: agentApiProfileViewSchema }
|
|
43735
|
+
}),
|
|
43600
43736
|
integrationList: route({
|
|
43601
43737
|
key: "integrationList",
|
|
43602
43738
|
method: "GET",
|
|
@@ -43627,6 +43763,22 @@ var agentApiContract = {
|
|
|
43627
43763
|
request: { body: agentApiIntegrationAppPrepareBodySchema },
|
|
43628
43764
|
response: { body: agentApiIntegrationAppPrepareResponseSchema }
|
|
43629
43765
|
}),
|
|
43766
|
+
integrationAppRotateSecret: route({
|
|
43767
|
+
key: "integrationAppRotateSecret",
|
|
43768
|
+
method: "POST",
|
|
43769
|
+
path: "/integrations/app/rotate-secret",
|
|
43770
|
+
client: { resource: "integrations", method: "rotateAppSecret" },
|
|
43771
|
+
// Mirrors integrationAppPrepare's "read" capability: the AgentApiCapability
|
|
43772
|
+
// enum has no generic "mutation"/"integrations" scope, and the sibling
|
|
43773
|
+
// integration app routes (prepare/login) all gate on "read". Owner-scope is
|
|
43774
|
+
// enforced server-side in rotateClientSecretForAgent's WHERE clause (and the
|
|
43775
|
+
// bound agent credential), so the capability tier is not the security
|
|
43776
|
+
// boundary here. Keep parity with integrationAppPrepare.
|
|
43777
|
+
capability: "read",
|
|
43778
|
+
description: "Regenerate the one-time client secret for a server-local integration app the calling agent owns; invalidates the previous secret.",
|
|
43779
|
+
request: { body: agentApiIntegrationAppRotateSecretBodySchema },
|
|
43780
|
+
response: { body: agentApiIntegrationAppRotateSecretResponseSchema }
|
|
43781
|
+
}),
|
|
43630
43782
|
actionPrepare: route({
|
|
43631
43783
|
key: "actionPrepare",
|
|
43632
43784
|
method: "POST",
|
|
@@ -43646,13 +43798,43 @@ var agentApiContract = {
|
|
|
43646
43798
|
description: "Upload a multipart attachment as the bound agent credential.",
|
|
43647
43799
|
request: {},
|
|
43648
43800
|
response: { body: agentApiAttachmentUploadResponseSchema }
|
|
43801
|
+
}),
|
|
43802
|
+
attachmentDownload: route({
|
|
43803
|
+
key: "attachmentDownload",
|
|
43804
|
+
method: "GET",
|
|
43805
|
+
path: "/attachments/:attachmentId",
|
|
43806
|
+
client: { resource: "attachments", method: "download" },
|
|
43807
|
+
capability: "read",
|
|
43808
|
+
description: "Download attachment bytes visible to the bound agent credential.",
|
|
43809
|
+
request: { params: agentApiAttachmentDownloadParamsSchema },
|
|
43810
|
+
response: { kind: "binary" }
|
|
43811
|
+
}),
|
|
43812
|
+
attachmentCommentsList: route({
|
|
43813
|
+
key: "attachmentCommentsList",
|
|
43814
|
+
method: "GET",
|
|
43815
|
+
path: "/attachments/:attachmentId/comments",
|
|
43816
|
+
client: { resource: "attachments", method: "comments" },
|
|
43817
|
+
capability: "read",
|
|
43818
|
+
description: "List comments scoped to an attachment visible to the bound agent credential.",
|
|
43819
|
+
request: { params: agentApiAttachmentCommentsParamsSchema, query: agentApiAttachmentCommentsQuerySchema },
|
|
43820
|
+
response: { body: agentApiAttachmentCommentsResponseSchema }
|
|
43649
43821
|
})
|
|
43650
43822
|
};
|
|
43651
|
-
function
|
|
43652
|
-
return
|
|
43823
|
+
function getAgentApiResponseKind(response) {
|
|
43824
|
+
return "kind" in response ? response.kind ?? "json" : "json";
|
|
43653
43825
|
}
|
|
43654
43826
|
function parseAgentApiResponse(key, value) {
|
|
43655
|
-
|
|
43827
|
+
const response = agentApiContract[key].response;
|
|
43828
|
+
if (getAgentApiResponseKind(response) === "binary") {
|
|
43829
|
+
if (!(value instanceof Uint8Array)) {
|
|
43830
|
+
throw new TypeError(`Agent API ${key} response did not contain binary bytes`);
|
|
43831
|
+
}
|
|
43832
|
+
return value;
|
|
43833
|
+
}
|
|
43834
|
+
if (!("body" in response)) {
|
|
43835
|
+
throw new TypeError(`Agent API ${key} response contract is missing a JSON body schema`);
|
|
43836
|
+
}
|
|
43837
|
+
return response.body.parse(value);
|
|
43656
43838
|
}
|
|
43657
43839
|
|
|
43658
43840
|
// ../shared/src/agentApiRawClient.ts
|
|
@@ -43667,17 +43849,17 @@ function failure(routeKey, reason, message, details = {}) {
|
|
|
43667
43849
|
};
|
|
43668
43850
|
}
|
|
43669
43851
|
function encodePathParams(routeKey, params) {
|
|
43670
|
-
const
|
|
43852
|
+
const route3 = agentApiContract[routeKey];
|
|
43671
43853
|
let parsed;
|
|
43672
43854
|
try {
|
|
43673
|
-
parsed = "params" in
|
|
43855
|
+
parsed = "params" in route3.request ? route3.request.params.parse(params ?? {}) : {};
|
|
43674
43856
|
} catch (cause) {
|
|
43675
|
-
return failure(routeKey, "request_contract_mismatch", `Agent API ${
|
|
43857
|
+
return failure(routeKey, "request_contract_mismatch", `Agent API ${route3.key} path params did not match the shared contract`, { cause });
|
|
43676
43858
|
}
|
|
43677
|
-
return
|
|
43859
|
+
return route3.path.replace(/:([A-Za-z][A-Za-z0-9_]*)/g, (_match, key) => {
|
|
43678
43860
|
const value = parsed[key];
|
|
43679
43861
|
if (value === void 0 || value === null) {
|
|
43680
|
-
throw new MissingPathParamError(
|
|
43862
|
+
throw new MissingPathParamError(route3.key, key);
|
|
43681
43863
|
}
|
|
43682
43864
|
return encodeURIComponent(String(value));
|
|
43683
43865
|
});
|
|
@@ -43691,12 +43873,12 @@ var MissingPathParamError = class extends Error {
|
|
|
43691
43873
|
};
|
|
43692
43874
|
function encodeQuery(routeKey, query) {
|
|
43693
43875
|
if (query === void 0) return void 0;
|
|
43694
|
-
const
|
|
43876
|
+
const route3 = agentApiContract[routeKey];
|
|
43695
43877
|
let parsed;
|
|
43696
43878
|
try {
|
|
43697
|
-
parsed = "query" in
|
|
43879
|
+
parsed = "query" in route3.request ? route3.request.query.parse(query) : {};
|
|
43698
43880
|
} catch (cause) {
|
|
43699
|
-
return failure(routeKey, "request_contract_mismatch", `Agent API ${
|
|
43881
|
+
return failure(routeKey, "request_contract_mismatch", `Agent API ${route3.key} query did not match the shared contract`, { cause });
|
|
43700
43882
|
}
|
|
43701
43883
|
const params = new URLSearchParams();
|
|
43702
43884
|
for (const [key, value] of Object.entries(parsed)) {
|
|
@@ -43711,11 +43893,11 @@ function encodeQuery(routeKey, query) {
|
|
|
43711
43893
|
}
|
|
43712
43894
|
function parseBody(routeKey, body) {
|
|
43713
43895
|
if (body === void 0) return void 0;
|
|
43714
|
-
const
|
|
43896
|
+
const route3 = agentApiContract[routeKey];
|
|
43715
43897
|
try {
|
|
43716
|
-
return "body" in
|
|
43898
|
+
return "body" in route3.request ? route3.request.body.parse(body) : void 0;
|
|
43717
43899
|
} catch (cause) {
|
|
43718
|
-
return failure(routeKey, "request_contract_mismatch", `Agent API ${
|
|
43900
|
+
return failure(routeKey, "request_contract_mismatch", `Agent API ${route3.key} body did not match the shared contract`, { cause });
|
|
43719
43901
|
}
|
|
43720
43902
|
}
|
|
43721
43903
|
function isAgentApiRawFailure(value) {
|
|
@@ -43741,7 +43923,7 @@ function buildAgentApiRawRoutePath(routeKey, options = {}) {
|
|
|
43741
43923
|
return `${options.pathPrefix ?? AGENT_API_BASE_PATH}${path9}${suffix}`;
|
|
43742
43924
|
}
|
|
43743
43925
|
async function requestAgentApiRawRoute(transport, routeKey, options = {}) {
|
|
43744
|
-
const
|
|
43926
|
+
const route3 = agentApiContract[routeKey];
|
|
43745
43927
|
const path9 = buildAgentApiRawRoutePath(routeKey, options);
|
|
43746
43928
|
if (typeof path9 !== "string") return path9;
|
|
43747
43929
|
const body = parseBody(routeKey, options.body);
|
|
@@ -43750,12 +43932,12 @@ async function requestAgentApiRawRoute(transport, routeKey, options = {}) {
|
|
|
43750
43932
|
try {
|
|
43751
43933
|
response = await transport.request({
|
|
43752
43934
|
routeKey,
|
|
43753
|
-
method:
|
|
43935
|
+
method: route3.method,
|
|
43754
43936
|
path: path9,
|
|
43755
43937
|
body
|
|
43756
43938
|
});
|
|
43757
43939
|
} catch (cause) {
|
|
43758
|
-
return failure(routeKey, "transport_error", `Agent API ${
|
|
43940
|
+
return failure(routeKey, "transport_error", `Agent API ${route3.key} transport request failed`, { cause });
|
|
43759
43941
|
}
|
|
43760
43942
|
if (!response.ok) {
|
|
43761
43943
|
return failure(routeKey, "http_error", response.error ?? `HTTP ${response.status}`, {
|
|
@@ -43765,8 +43947,22 @@ async function requestAgentApiRawRoute(transport, routeKey, options = {}) {
|
|
|
43765
43947
|
response: response.data
|
|
43766
43948
|
});
|
|
43767
43949
|
}
|
|
43950
|
+
if (getAgentApiResponseKind(route3.response) === "binary") {
|
|
43951
|
+
if (!(response.data instanceof Uint8Array)) {
|
|
43952
|
+
return failure(routeKey, "response_contract_mismatch", `Agent API ${route3.key} response did not contain binary bytes`, {
|
|
43953
|
+
status: response.status,
|
|
43954
|
+
response: response.data
|
|
43955
|
+
});
|
|
43956
|
+
}
|
|
43957
|
+
return {
|
|
43958
|
+
ok: true,
|
|
43959
|
+
routeKey,
|
|
43960
|
+
status: response.status,
|
|
43961
|
+
data: response.data
|
|
43962
|
+
};
|
|
43963
|
+
}
|
|
43768
43964
|
if (response.data === null) {
|
|
43769
|
-
return failure(routeKey, "empty_response", `Agent API ${
|
|
43965
|
+
return failure(routeKey, "empty_response", `Agent API ${route3.key} returned an empty response body`, {
|
|
43770
43966
|
status: response.status
|
|
43771
43967
|
});
|
|
43772
43968
|
}
|
|
@@ -43778,7 +43974,7 @@ async function requestAgentApiRawRoute(transport, routeKey, options = {}) {
|
|
|
43778
43974
|
data: parseAgentApiResponse(routeKey, response.data)
|
|
43779
43975
|
};
|
|
43780
43976
|
} catch (cause) {
|
|
43781
|
-
return failure(routeKey, "response_contract_mismatch", `Agent API ${
|
|
43977
|
+
return failure(routeKey, "response_contract_mismatch", `Agent API ${route3.key} response did not match the shared contract`, {
|
|
43782
43978
|
status: response.status,
|
|
43783
43979
|
cause,
|
|
43784
43980
|
response: response.data
|
|
@@ -43786,16 +43982,16 @@ async function requestAgentApiRawRoute(transport, routeKey, options = {}) {
|
|
|
43786
43982
|
}
|
|
43787
43983
|
}
|
|
43788
43984
|
function requestOptionsFromMethodArgs(routeKey, pathPrefix, args) {
|
|
43789
|
-
const
|
|
43985
|
+
const route3 = agentApiContract[routeKey];
|
|
43790
43986
|
let index = 0;
|
|
43791
43987
|
const requestOptions = { pathPrefix };
|
|
43792
|
-
if ("params" in
|
|
43988
|
+
if ("params" in route3.request) {
|
|
43793
43989
|
requestOptions.params = args[index++];
|
|
43794
43990
|
}
|
|
43795
|
-
if ("query" in
|
|
43991
|
+
if ("query" in route3.request) {
|
|
43796
43992
|
requestOptions.query = args[index++];
|
|
43797
43993
|
}
|
|
43798
|
-
if ("body" in
|
|
43994
|
+
if ("body" in route3.request) {
|
|
43799
43995
|
requestOptions.body = args[index++];
|
|
43800
43996
|
}
|
|
43801
43997
|
return requestOptions;
|
|
@@ -43803,9 +43999,9 @@ function requestOptionsFromMethodArgs(routeKey, pathPrefix, args) {
|
|
|
43803
43999
|
function createAgentApiRawClient(transport, options = {}) {
|
|
43804
44000
|
const pathPrefix = options.pathPrefix ?? AGENT_API_BASE_PATH;
|
|
43805
44001
|
const client = {};
|
|
43806
|
-
for (const
|
|
43807
|
-
const routeKey =
|
|
43808
|
-
const { resource, method } =
|
|
44002
|
+
for (const route3 of Object.values(agentApiContract)) {
|
|
44003
|
+
const routeKey = route3.key;
|
|
44004
|
+
const { resource, method } = route3.client;
|
|
43809
44005
|
const resourceClient = client[resource] ??= {};
|
|
43810
44006
|
resourceClient[method] = (...args) => requestAgentApiRawRoute(
|
|
43811
44007
|
transport,
|
|
@@ -43828,7 +44024,10 @@ async function authHeadersForRequest(auth, request) {
|
|
|
43828
44024
|
if (!auth) return void 0;
|
|
43829
44025
|
return typeof auth === "function" ? auth(request) : auth;
|
|
43830
44026
|
}
|
|
43831
|
-
async function parseFetchResponse(response) {
|
|
44027
|
+
async function parseFetchResponse(response, responseKind) {
|
|
44028
|
+
if (response.ok && responseKind === "binary") {
|
|
44029
|
+
return new Uint8Array(await response.arrayBuffer());
|
|
44030
|
+
}
|
|
43832
44031
|
const text = await response.text();
|
|
43833
44032
|
if (!text.trim()) return null;
|
|
43834
44033
|
try {
|
|
@@ -43864,8 +44063,9 @@ function createAgentApiFetchTransport(options) {
|
|
|
43864
44063
|
request: async (input) => {
|
|
43865
44064
|
await options.throttle?.beforeRequest?.(input);
|
|
43866
44065
|
const authHeaders = await authHeadersForRequest(options.auth, input);
|
|
44066
|
+
const responseKind = getAgentApiResponseKind(agentApiContract[input.routeKey].response);
|
|
43867
44067
|
const headers = mergeHeaders(
|
|
43868
|
-
{ accept: "application/json" },
|
|
44068
|
+
{ accept: responseKind === "binary" ? "*/*" : "application/json" },
|
|
43869
44069
|
input.body === void 0 ? void 0 : { "content-type": "application/json" },
|
|
43870
44070
|
options.headers,
|
|
43871
44071
|
authHeaders
|
|
@@ -43879,7 +44079,7 @@ function createAgentApiFetchTransport(options) {
|
|
|
43879
44079
|
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
|
|
43880
44080
|
try {
|
|
43881
44081
|
const response = await fetchImpl(`${baseUrl}${input.path}`, init);
|
|
43882
|
-
return transportResponseFromFetch(response, await parseFetchResponse(response));
|
|
44082
|
+
return transportResponseFromFetch(response, await parseFetchResponse(response, responseKind));
|
|
43883
44083
|
} catch (cause) {
|
|
43884
44084
|
lastError = cause;
|
|
43885
44085
|
if (attempt === maxAttempts) throw cause;
|
|
@@ -43889,33 +44089,33 @@ function createAgentApiFetchTransport(options) {
|
|
|
43889
44089
|
}
|
|
43890
44090
|
};
|
|
43891
44091
|
}
|
|
43892
|
-
function errorFromRawFailure(
|
|
43893
|
-
if (
|
|
44092
|
+
function errorFromRawFailure(failure3) {
|
|
44093
|
+
if (failure3.reason === "transport_error") {
|
|
43894
44094
|
return {
|
|
43895
44095
|
kind: "transport",
|
|
43896
|
-
reason:
|
|
43897
|
-
message:
|
|
43898
|
-
cause:
|
|
44096
|
+
reason: failure3.reason,
|
|
44097
|
+
message: failure3.message,
|
|
44098
|
+
cause: failure3.cause
|
|
43899
44099
|
};
|
|
43900
44100
|
}
|
|
43901
|
-
if (
|
|
44101
|
+
if (failure3.reason === "http_error") {
|
|
43902
44102
|
return {
|
|
43903
44103
|
kind: "http",
|
|
43904
|
-
reason:
|
|
43905
|
-
message:
|
|
43906
|
-
status:
|
|
43907
|
-
errorCode:
|
|
43908
|
-
suggestedNextAction:
|
|
43909
|
-
response:
|
|
44104
|
+
reason: failure3.reason,
|
|
44105
|
+
message: failure3.message,
|
|
44106
|
+
status: failure3.status ?? 0,
|
|
44107
|
+
errorCode: failure3.errorCode,
|
|
44108
|
+
suggestedNextAction: failure3.suggestedNextAction,
|
|
44109
|
+
response: failure3.response
|
|
43910
44110
|
};
|
|
43911
44111
|
}
|
|
43912
44112
|
return {
|
|
43913
44113
|
kind: "validation",
|
|
43914
|
-
reason:
|
|
43915
|
-
message:
|
|
43916
|
-
status:
|
|
43917
|
-
cause:
|
|
43918
|
-
response:
|
|
44114
|
+
reason: failure3.reason,
|
|
44115
|
+
message: failure3.message,
|
|
44116
|
+
status: failure3.status,
|
|
44117
|
+
cause: failure3.cause,
|
|
44118
|
+
response: failure3.response
|
|
43919
44119
|
};
|
|
43920
44120
|
}
|
|
43921
44121
|
function agentApiClientResultFromRaw(result2) {
|
|
@@ -43963,6 +44163,375 @@ function createAgentApiClient(transportOrOptions, maybeOptions = {}) {
|
|
|
43963
44163
|
};
|
|
43964
44164
|
}
|
|
43965
44165
|
|
|
44166
|
+
// ../shared/src/daemonApiContract.ts
|
|
44167
|
+
init_esm_shims();
|
|
44168
|
+
var DAEMON_API_BASE_PATH = "/internal/agent-api";
|
|
44169
|
+
var optionalStringSchema2 = external_exports.string().trim().optional();
|
|
44170
|
+
var optionalNonNegativeIntSchema = external_exports.number().int().nonnegative().optional();
|
|
44171
|
+
var optionalQueryIntSchema = external_exports.union([external_exports.number().int().nonnegative(), external_exports.string().trim().min(1)]).optional();
|
|
44172
|
+
var nullableNumberSchema2 = external_exports.number().finite().nullable();
|
|
44173
|
+
var passthroughObject2 = (shape) => external_exports.object(shape).passthrough();
|
|
44174
|
+
var daemonApiInboxFlagSchema = external_exports.enum(["mention", "thread", "dm", "task"]);
|
|
44175
|
+
var daemonApiInboxTargetRowSchema = passthroughObject2({
|
|
44176
|
+
target: external_exports.string().trim().min(1),
|
|
44177
|
+
channelId: optionalStringSchema2,
|
|
44178
|
+
channelType: optionalStringSchema2,
|
|
44179
|
+
pendingCount: external_exports.number().int().nonnegative(),
|
|
44180
|
+
firstPendingMsgId: optionalStringSchema2,
|
|
44181
|
+
firstPendingSeq: optionalNonNegativeIntSchema,
|
|
44182
|
+
latestMsgId: optionalStringSchema2,
|
|
44183
|
+
latestSeq: optionalNonNegativeIntSchema,
|
|
44184
|
+
latestSenderName: optionalStringSchema2,
|
|
44185
|
+
latestSenderType: external_exports.enum(["human", "agent", "system"]).optional(),
|
|
44186
|
+
flags: external_exports.array(daemonApiInboxFlagSchema)
|
|
44187
|
+
});
|
|
44188
|
+
var daemonApiInboxCheckResponseSchema = passthroughObject2({
|
|
44189
|
+
rows: external_exports.array(daemonApiInboxTargetRowSchema).optional()
|
|
44190
|
+
});
|
|
44191
|
+
var daemonApiWakeHintsQuerySchema = passthroughObject2({
|
|
44192
|
+
since: external_exports.union([external_exports.literal("latest"), external_exports.number().int().nonnegative(), external_exports.string().trim().min(1)]).optional(),
|
|
44193
|
+
limit: optionalQueryIntSchema
|
|
44194
|
+
});
|
|
44195
|
+
var daemonApiWakeHintSchema = passthroughObject2({
|
|
44196
|
+
hintId: optionalStringSchema2,
|
|
44197
|
+
hint_id: optionalStringSchema2,
|
|
44198
|
+
eventId: optionalStringSchema2,
|
|
44199
|
+
event_id: optionalStringSchema2,
|
|
44200
|
+
messageId: external_exports.string().nullable().optional(),
|
|
44201
|
+
message_id: external_exports.string().nullable().optional(),
|
|
44202
|
+
seq: optionalNonNegativeIntSchema,
|
|
44203
|
+
id: optionalStringSchema2,
|
|
44204
|
+
target: optionalStringSchema2,
|
|
44205
|
+
targetType: optionalStringSchema2,
|
|
44206
|
+
target_type: optionalStringSchema2,
|
|
44207
|
+
reason: optionalStringSchema2,
|
|
44208
|
+
wake_reason: optionalStringSchema2,
|
|
44209
|
+
createdAt: optionalStringSchema2,
|
|
44210
|
+
created_at: optionalStringSchema2
|
|
44211
|
+
});
|
|
44212
|
+
var daemonApiWakeHintsFetchResponseSchema = passthroughObject2({
|
|
44213
|
+
hints: external_exports.array(daemonApiWakeHintSchema).optional(),
|
|
44214
|
+
wake_hints: external_exports.array(daemonApiWakeHintSchema).optional(),
|
|
44215
|
+
last_seen_hint_seq: nullableNumberSchema2.optional(),
|
|
44216
|
+
last_hint_seq: nullableNumberSchema2.optional(),
|
|
44217
|
+
has_more: external_exports.boolean().optional()
|
|
44218
|
+
});
|
|
44219
|
+
var daemonApiActivityEventSchema = passthroughObject2({
|
|
44220
|
+
schema: optionalStringSchema2
|
|
44221
|
+
});
|
|
44222
|
+
var daemonApiActivityForwardBodySchema = passthroughObject2({
|
|
44223
|
+
schema: external_exports.literal("raft-agent-activity-ingest.v1"),
|
|
44224
|
+
coreSessionId: optionalStringSchema2,
|
|
44225
|
+
adapterInstance: optionalStringSchema2,
|
|
44226
|
+
events: external_exports.array(daemonApiActivityEventSchema),
|
|
44227
|
+
dropped: optionalNonNegativeIntSchema
|
|
44228
|
+
});
|
|
44229
|
+
var daemonApiActivityForwardResponseSchema = passthroughObject2({
|
|
44230
|
+
ok: external_exports.literal(true).optional(),
|
|
44231
|
+
acceptedCount: external_exports.number().int().nonnegative().optional(),
|
|
44232
|
+
rejectedCount: external_exports.number().int().nonnegative().optional(),
|
|
44233
|
+
droppedCount: external_exports.number().int().nonnegative().optional()
|
|
44234
|
+
});
|
|
44235
|
+
function route2(input) {
|
|
44236
|
+
return {
|
|
44237
|
+
...input,
|
|
44238
|
+
fullPath: `${DAEMON_API_BASE_PATH}${input.path}`
|
|
44239
|
+
};
|
|
44240
|
+
}
|
|
44241
|
+
var daemonApiContract = {
|
|
44242
|
+
inboxCheck: route2({
|
|
44243
|
+
key: "inboxCheck",
|
|
44244
|
+
method: "GET",
|
|
44245
|
+
path: "/inbox",
|
|
44246
|
+
client: { resource: "inbox", method: "check" },
|
|
44247
|
+
description: "Read the managed-runner daemon inbox snapshot without draining message content.",
|
|
44248
|
+
request: {},
|
|
44249
|
+
response: { body: daemonApiInboxCheckResponseSchema }
|
|
44250
|
+
}),
|
|
44251
|
+
wakeHintsFetch: route2({
|
|
44252
|
+
key: "wakeHintsFetch",
|
|
44253
|
+
method: "GET",
|
|
44254
|
+
path: "/wake-hints",
|
|
44255
|
+
client: { resource: "wakeHints", method: "fetch" },
|
|
44256
|
+
description: "Peek content-free wake hints without advancing delivery cursors.",
|
|
44257
|
+
request: { query: daemonApiWakeHintsQuerySchema },
|
|
44258
|
+
response: { body: daemonApiWakeHintsFetchResponseSchema }
|
|
44259
|
+
}),
|
|
44260
|
+
activityForward: route2({
|
|
44261
|
+
key: "activityForward",
|
|
44262
|
+
method: "POST",
|
|
44263
|
+
path: "/activity",
|
|
44264
|
+
client: { resource: "activity", method: "forward" },
|
|
44265
|
+
description: "Forward plugin-observed activity from a local bridge to the daemon/server activity ingest path.",
|
|
44266
|
+
request: { body: daemonApiActivityForwardBodySchema },
|
|
44267
|
+
response: { body: daemonApiActivityForwardResponseSchema }
|
|
44268
|
+
})
|
|
44269
|
+
};
|
|
44270
|
+
function parseDaemonApiResponse(routeKey, data) {
|
|
44271
|
+
return daemonApiContract[routeKey].response.body.parse(data);
|
|
44272
|
+
}
|
|
44273
|
+
|
|
44274
|
+
// ../shared/src/daemonApiRawClient.ts
|
|
44275
|
+
init_esm_shims();
|
|
44276
|
+
function failure2(routeKey, reason, message, details = {}) {
|
|
44277
|
+
return {
|
|
44278
|
+
ok: false,
|
|
44279
|
+
...routeKey ? { routeKey } : {},
|
|
44280
|
+
reason,
|
|
44281
|
+
message,
|
|
44282
|
+
...details
|
|
44283
|
+
};
|
|
44284
|
+
}
|
|
44285
|
+
function encodeQuery2(routeKey, query) {
|
|
44286
|
+
if (query === void 0) return void 0;
|
|
44287
|
+
const route3 = daemonApiContract[routeKey];
|
|
44288
|
+
let parsed;
|
|
44289
|
+
try {
|
|
44290
|
+
parsed = "query" in route3.request ? route3.request.query.parse(query) : {};
|
|
44291
|
+
} catch (cause) {
|
|
44292
|
+
return failure2(routeKey, "request_contract_mismatch", `Daemon API ${route3.key} query did not match the shared contract`, { cause });
|
|
44293
|
+
}
|
|
44294
|
+
const params = new URLSearchParams();
|
|
44295
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
44296
|
+
if (value === void 0 || value === null) continue;
|
|
44297
|
+
if (Array.isArray(value)) {
|
|
44298
|
+
for (const item of value) params.append(key, String(item));
|
|
44299
|
+
continue;
|
|
44300
|
+
}
|
|
44301
|
+
params.set(key, String(value));
|
|
44302
|
+
}
|
|
44303
|
+
return params;
|
|
44304
|
+
}
|
|
44305
|
+
function parseBody2(routeKey, body) {
|
|
44306
|
+
if (body === void 0) return void 0;
|
|
44307
|
+
const route3 = daemonApiContract[routeKey];
|
|
44308
|
+
try {
|
|
44309
|
+
return "body" in route3.request ? route3.request.body.parse(body) : void 0;
|
|
44310
|
+
} catch (cause) {
|
|
44311
|
+
return failure2(routeKey, "request_contract_mismatch", `Daemon API ${route3.key} body did not match the shared contract`, { cause });
|
|
44312
|
+
}
|
|
44313
|
+
}
|
|
44314
|
+
function isDaemonApiRawFailure(value) {
|
|
44315
|
+
return Boolean(
|
|
44316
|
+
value && typeof value === "object" && value.ok === false && typeof value.reason === "string" && typeof value.message === "string"
|
|
44317
|
+
);
|
|
44318
|
+
}
|
|
44319
|
+
function buildDaemonApiRawRoutePath(routeKey, options = {}) {
|
|
44320
|
+
const route3 = daemonApiContract[routeKey];
|
|
44321
|
+
const query = encodeQuery2(routeKey, options.query);
|
|
44322
|
+
if (query && !(query instanceof URLSearchParams)) return query;
|
|
44323
|
+
const suffix = query && query.size > 0 ? `?${query.toString()}` : "";
|
|
44324
|
+
return `${options.pathPrefix ?? DAEMON_API_BASE_PATH}${route3.path}${suffix}`;
|
|
44325
|
+
}
|
|
44326
|
+
async function requestDaemonApiRawRoute(transport, routeKey, options = {}) {
|
|
44327
|
+
const route3 = daemonApiContract[routeKey];
|
|
44328
|
+
const path9 = buildDaemonApiRawRoutePath(routeKey, options);
|
|
44329
|
+
if (typeof path9 !== "string") return path9;
|
|
44330
|
+
const body = parseBody2(routeKey, options.body);
|
|
44331
|
+
if (isDaemonApiRawFailure(body)) return body;
|
|
44332
|
+
let response;
|
|
44333
|
+
try {
|
|
44334
|
+
response = await transport.request({
|
|
44335
|
+
routeKey,
|
|
44336
|
+
method: route3.method,
|
|
44337
|
+
path: path9,
|
|
44338
|
+
body
|
|
44339
|
+
});
|
|
44340
|
+
} catch (cause) {
|
|
44341
|
+
return failure2(routeKey, "transport_error", `Daemon API ${route3.key} transport request failed`, { cause });
|
|
44342
|
+
}
|
|
44343
|
+
if (!response.ok) {
|
|
44344
|
+
return failure2(routeKey, "http_error", response.error ?? `HTTP ${response.status}`, {
|
|
44345
|
+
status: response.status,
|
|
44346
|
+
errorCode: response.errorCode,
|
|
44347
|
+
suggestedNextAction: response.suggestedNextAction,
|
|
44348
|
+
response: response.data
|
|
44349
|
+
});
|
|
44350
|
+
}
|
|
44351
|
+
if (response.data === null) {
|
|
44352
|
+
return failure2(routeKey, "empty_response", `Daemon API ${route3.key} returned an empty response body`, {
|
|
44353
|
+
status: response.status
|
|
44354
|
+
});
|
|
44355
|
+
}
|
|
44356
|
+
try {
|
|
44357
|
+
return {
|
|
44358
|
+
ok: true,
|
|
44359
|
+
routeKey,
|
|
44360
|
+
status: response.status,
|
|
44361
|
+
data: parseDaemonApiResponse(routeKey, response.data)
|
|
44362
|
+
};
|
|
44363
|
+
} catch (cause) {
|
|
44364
|
+
return failure2(routeKey, "response_contract_mismatch", `Daemon API ${route3.key} response did not match the shared contract`, {
|
|
44365
|
+
status: response.status,
|
|
44366
|
+
cause,
|
|
44367
|
+
response: response.data
|
|
44368
|
+
});
|
|
44369
|
+
}
|
|
44370
|
+
}
|
|
44371
|
+
function requestOptionsFromMethodArgs2(routeKey, pathPrefix, args) {
|
|
44372
|
+
const route3 = daemonApiContract[routeKey];
|
|
44373
|
+
let index = 0;
|
|
44374
|
+
const requestOptions = { pathPrefix };
|
|
44375
|
+
if ("query" in route3.request) {
|
|
44376
|
+
requestOptions.query = args[index++];
|
|
44377
|
+
}
|
|
44378
|
+
if ("body" in route3.request) {
|
|
44379
|
+
requestOptions.body = args[index++];
|
|
44380
|
+
}
|
|
44381
|
+
return requestOptions;
|
|
44382
|
+
}
|
|
44383
|
+
function createDaemonApiRawClient(transport, options = {}) {
|
|
44384
|
+
const pathPrefix = options.pathPrefix ?? DAEMON_API_BASE_PATH;
|
|
44385
|
+
const client = {};
|
|
44386
|
+
for (const route3 of Object.values(daemonApiContract)) {
|
|
44387
|
+
const routeKey = route3.key;
|
|
44388
|
+
const { resource, method } = route3.client;
|
|
44389
|
+
const resourceClient = client[resource] ??= {};
|
|
44390
|
+
resourceClient[method] = (...args) => requestDaemonApiRawRoute(
|
|
44391
|
+
transport,
|
|
44392
|
+
routeKey,
|
|
44393
|
+
requestOptionsFromMethodArgs2(routeKey, pathPrefix, args)
|
|
44394
|
+
);
|
|
44395
|
+
}
|
|
44396
|
+
return client;
|
|
44397
|
+
}
|
|
44398
|
+
|
|
44399
|
+
// ../shared/src/daemonApiClient.ts
|
|
44400
|
+
init_esm_shims();
|
|
44401
|
+
function normalizeBaseUrl2(baseUrl) {
|
|
44402
|
+
return baseUrl.replace(/\/+$/, "");
|
|
44403
|
+
}
|
|
44404
|
+
function mergeHeaders2(...headers) {
|
|
44405
|
+
return Object.assign({}, ...headers.filter(Boolean));
|
|
44406
|
+
}
|
|
44407
|
+
async function authHeadersForRequest2(auth, request) {
|
|
44408
|
+
if (!auth) return void 0;
|
|
44409
|
+
return typeof auth === "function" ? auth(request) : auth;
|
|
44410
|
+
}
|
|
44411
|
+
async function parseFetchResponse2(response) {
|
|
44412
|
+
const text = await response.text();
|
|
44413
|
+
if (!text.trim()) return null;
|
|
44414
|
+
try {
|
|
44415
|
+
return JSON.parse(text);
|
|
44416
|
+
} catch {
|
|
44417
|
+
return text;
|
|
44418
|
+
}
|
|
44419
|
+
}
|
|
44420
|
+
function transportResponseFromFetch2(response, data) {
|
|
44421
|
+
if (response.ok) {
|
|
44422
|
+
return {
|
|
44423
|
+
ok: true,
|
|
44424
|
+
status: response.status,
|
|
44425
|
+
data,
|
|
44426
|
+
error: null
|
|
44427
|
+
};
|
|
44428
|
+
}
|
|
44429
|
+
const objectData = data && typeof data === "object" ? data : {};
|
|
44430
|
+
return {
|
|
44431
|
+
ok: false,
|
|
44432
|
+
status: response.status,
|
|
44433
|
+
data,
|
|
44434
|
+
error: typeof objectData.error === "string" ? objectData.error : response.statusText || `HTTP ${response.status}`,
|
|
44435
|
+
errorCode: typeof objectData.errorCode === "string" ? objectData.errorCode : null,
|
|
44436
|
+
suggestedNextAction: typeof objectData.suggestedNextAction === "string" ? objectData.suggestedNextAction : null
|
|
44437
|
+
};
|
|
44438
|
+
}
|
|
44439
|
+
function createDaemonApiFetchTransport(options) {
|
|
44440
|
+
const fetchImpl = options.fetch ?? fetch;
|
|
44441
|
+
const baseUrl = normalizeBaseUrl2(options.baseUrl);
|
|
44442
|
+
return {
|
|
44443
|
+
request: async (input) => {
|
|
44444
|
+
const authHeaders = await authHeadersForRequest2(options.auth, input);
|
|
44445
|
+
const headers = mergeHeaders2(
|
|
44446
|
+
{ accept: "application/json" },
|
|
44447
|
+
input.body === void 0 ? void 0 : { "content-type": "application/json" },
|
|
44448
|
+
options.headers,
|
|
44449
|
+
authHeaders
|
|
44450
|
+
);
|
|
44451
|
+
const init = {
|
|
44452
|
+
method: input.method,
|
|
44453
|
+
headers,
|
|
44454
|
+
body: input.body === void 0 ? void 0 : JSON.stringify(input.body)
|
|
44455
|
+
};
|
|
44456
|
+
const response = await fetchImpl(`${baseUrl}${input.path}`, init);
|
|
44457
|
+
return transportResponseFromFetch2(response, await parseFetchResponse2(response));
|
|
44458
|
+
}
|
|
44459
|
+
};
|
|
44460
|
+
}
|
|
44461
|
+
function errorFromRawFailure2(failure3) {
|
|
44462
|
+
if (failure3.reason === "transport_error") {
|
|
44463
|
+
return {
|
|
44464
|
+
kind: "transport",
|
|
44465
|
+
reason: failure3.reason,
|
|
44466
|
+
message: failure3.message,
|
|
44467
|
+
cause: failure3.cause
|
|
44468
|
+
};
|
|
44469
|
+
}
|
|
44470
|
+
if (failure3.reason === "http_error") {
|
|
44471
|
+
return {
|
|
44472
|
+
kind: "http",
|
|
44473
|
+
reason: failure3.reason,
|
|
44474
|
+
message: failure3.message,
|
|
44475
|
+
status: failure3.status ?? 0,
|
|
44476
|
+
errorCode: failure3.errorCode,
|
|
44477
|
+
suggestedNextAction: failure3.suggestedNextAction,
|
|
44478
|
+
response: failure3.response
|
|
44479
|
+
};
|
|
44480
|
+
}
|
|
44481
|
+
return {
|
|
44482
|
+
kind: "validation",
|
|
44483
|
+
reason: failure3.reason,
|
|
44484
|
+
message: failure3.message,
|
|
44485
|
+
status: failure3.status,
|
|
44486
|
+
cause: failure3.cause,
|
|
44487
|
+
response: failure3.response
|
|
44488
|
+
};
|
|
44489
|
+
}
|
|
44490
|
+
function daemonApiClientResultFromRaw(result2) {
|
|
44491
|
+
if (result2.ok) {
|
|
44492
|
+
const success2 = result2;
|
|
44493
|
+
return {
|
|
44494
|
+
ok: true,
|
|
44495
|
+
routeKey: success2.routeKey,
|
|
44496
|
+
status: success2.status,
|
|
44497
|
+
data: success2.data
|
|
44498
|
+
};
|
|
44499
|
+
}
|
|
44500
|
+
return {
|
|
44501
|
+
ok: false,
|
|
44502
|
+
routeKey: result2.routeKey,
|
|
44503
|
+
status: result2.status,
|
|
44504
|
+
error: errorFromRawFailure2(result2)
|
|
44505
|
+
};
|
|
44506
|
+
}
|
|
44507
|
+
function wrapRawClient2(rawClient) {
|
|
44508
|
+
const client = {};
|
|
44509
|
+
for (const [resource, methods] of Object.entries(rawClient)) {
|
|
44510
|
+
client[resource] = {};
|
|
44511
|
+
for (const [method, rawMethod] of Object.entries(methods)) {
|
|
44512
|
+
client[resource][method] = async (...args) => daemonApiClientResultFromRaw(await rawMethod(...args));
|
|
44513
|
+
}
|
|
44514
|
+
}
|
|
44515
|
+
return client;
|
|
44516
|
+
}
|
|
44517
|
+
function createDaemonApiClient(transportOrOptions, maybeOptions = {}) {
|
|
44518
|
+
const options = "request" in transportOrOptions ? { ...maybeOptions, transport: transportOrOptions } : transportOrOptions;
|
|
44519
|
+
const transport = options.transport ?? (options.fetch ? createDaemonApiFetchTransport(options.fetch) : void 0);
|
|
44520
|
+
if (!transport) {
|
|
44521
|
+
throw new Error("createDaemonApiClient requires either a transport or fetch options");
|
|
44522
|
+
}
|
|
44523
|
+
const pathPrefix = options.pathPrefix ?? DAEMON_API_BASE_PATH;
|
|
44524
|
+
const rawClient = createDaemonApiRawClient(transport, { pathPrefix });
|
|
44525
|
+
const generated = wrapRawClient2(rawClient);
|
|
44526
|
+
return {
|
|
44527
|
+
...generated,
|
|
44528
|
+
request: async (routeKey, requestOptions = {}) => daemonApiClientResultFromRaw(await requestDaemonApiRawRoute(transport, routeKey, {
|
|
44529
|
+
pathPrefix,
|
|
44530
|
+
...requestOptions
|
|
44531
|
+
}))
|
|
44532
|
+
};
|
|
44533
|
+
}
|
|
44534
|
+
|
|
43966
44535
|
// ../shared/src/agentInbox.ts
|
|
43967
44536
|
init_esm_shims();
|
|
43968
44537
|
function formatAgentInboxSnapshot(rows) {
|
|
@@ -44494,66 +45063,84 @@ function buildAgentApiEventsPath(query) {
|
|
|
44494
45063
|
}
|
|
44495
45064
|
function rawTransportForClient(client) {
|
|
44496
45065
|
return {
|
|
44497
|
-
request: async (input) =>
|
|
45066
|
+
request: async (input) => {
|
|
45067
|
+
const route3 = agentApiContract[input.routeKey];
|
|
45068
|
+
if (getAgentApiResponseKind(route3.response) === "binary") {
|
|
45069
|
+
if (typeof client.requestBinary !== "function") {
|
|
45070
|
+
throw new CliError({
|
|
45071
|
+
code: "VIEW_FAILED",
|
|
45072
|
+
message: "Agent API binary download transport is unavailable in this CLI context"
|
|
45073
|
+
});
|
|
45074
|
+
}
|
|
45075
|
+
const response = await client.requestBinary(input.method, input.path);
|
|
45076
|
+
return {
|
|
45077
|
+
ok: response.ok,
|
|
45078
|
+
status: response.status,
|
|
45079
|
+
data: response.ok ? response.body : null,
|
|
45080
|
+
error: response.error
|
|
45081
|
+
};
|
|
45082
|
+
}
|
|
45083
|
+
return client.request(input.method, input.path, input.body);
|
|
45084
|
+
}
|
|
44498
45085
|
};
|
|
44499
45086
|
}
|
|
44500
|
-
function cliErrorFromRawFailure(
|
|
44501
|
-
switch (
|
|
45087
|
+
function cliErrorFromRawFailure(failure3) {
|
|
45088
|
+
switch (failure3.reason) {
|
|
44502
45089
|
case "missing_path_param":
|
|
44503
45090
|
case "request_contract_mismatch":
|
|
44504
45091
|
return new CliError({
|
|
44505
45092
|
code: "INVALID_ARG",
|
|
44506
|
-
message:
|
|
44507
|
-
cause:
|
|
45093
|
+
message: failure3.message,
|
|
45094
|
+
cause: failure3.cause
|
|
44508
45095
|
});
|
|
44509
45096
|
case "empty_response":
|
|
44510
45097
|
case "response_contract_mismatch":
|
|
44511
45098
|
case "missing_route":
|
|
44512
45099
|
return new CliError({
|
|
44513
45100
|
code: "INVALID_JSON_RESPONSE",
|
|
44514
|
-
message:
|
|
44515
|
-
cause:
|
|
45101
|
+
message: failure3.message,
|
|
45102
|
+
cause: failure3.cause
|
|
44516
45103
|
});
|
|
44517
45104
|
case "transport_error":
|
|
44518
45105
|
case "http_error":
|
|
44519
45106
|
return new CliError({
|
|
44520
45107
|
code: "CHECK_FAILED",
|
|
44521
|
-
message:
|
|
44522
|
-
cause:
|
|
45108
|
+
message: failure3.message,
|
|
45109
|
+
cause: failure3.cause
|
|
44523
45110
|
});
|
|
44524
45111
|
}
|
|
44525
45112
|
}
|
|
44526
|
-
function cliErrorFromClientFailure(
|
|
44527
|
-
switch (
|
|
45113
|
+
function cliErrorFromClientFailure(failure3) {
|
|
45114
|
+
switch (failure3.error.kind) {
|
|
44528
45115
|
case "validation":
|
|
44529
|
-
switch (
|
|
45116
|
+
switch (failure3.error.reason) {
|
|
44530
45117
|
case "missing_path_param":
|
|
44531
45118
|
case "request_contract_mismatch":
|
|
44532
45119
|
return new CliError({
|
|
44533
45120
|
code: "INVALID_ARG",
|
|
44534
|
-
message:
|
|
44535
|
-
cause:
|
|
45121
|
+
message: failure3.error.message,
|
|
45122
|
+
cause: failure3.error.cause
|
|
44536
45123
|
});
|
|
44537
45124
|
case "empty_response":
|
|
44538
45125
|
case "response_contract_mismatch":
|
|
44539
45126
|
case "missing_route":
|
|
44540
45127
|
return new CliError({
|
|
44541
45128
|
code: "INVALID_JSON_RESPONSE",
|
|
44542
|
-
message:
|
|
44543
|
-
cause:
|
|
45129
|
+
message: failure3.error.message,
|
|
45130
|
+
cause: failure3.error.cause
|
|
44544
45131
|
});
|
|
44545
45132
|
}
|
|
44546
45133
|
break;
|
|
44547
45134
|
case "transport":
|
|
44548
45135
|
return new CliError({
|
|
44549
45136
|
code: "CHECK_FAILED",
|
|
44550
|
-
message:
|
|
44551
|
-
cause:
|
|
45137
|
+
message: failure3.error.message,
|
|
45138
|
+
cause: failure3.error.cause
|
|
44552
45139
|
});
|
|
44553
45140
|
case "http":
|
|
44554
45141
|
return new CliError({
|
|
44555
45142
|
code: "CHECK_FAILED",
|
|
44556
|
-
message:
|
|
45143
|
+
message: failure3.error.message
|
|
44557
45144
|
});
|
|
44558
45145
|
}
|
|
44559
45146
|
}
|
|
@@ -44615,38 +45202,20 @@ async function requestMultipartContractAgentApiRoute(client, routeKey, form) {
|
|
|
44615
45202
|
});
|
|
44616
45203
|
}
|
|
44617
45204
|
}
|
|
44618
|
-
function
|
|
44619
|
-
const agentApi = createAgentApiClient(rawTransportForClient(client)
|
|
44620
|
-
pathPrefix: buildLegacyAgentApiPath(agentId, "")
|
|
44621
|
-
});
|
|
45205
|
+
function createAgentApiSurfaceClient(client) {
|
|
45206
|
+
const agentApi = createAgentApiClient(rawTransportForClient(client));
|
|
44622
45207
|
return {
|
|
44623
45208
|
server: {
|
|
44624
45209
|
info: () => requestClientAsApiResponse(agentApi.server.info())
|
|
44625
45210
|
},
|
|
45211
|
+
events: {
|
|
45212
|
+
get: (query) => requestClientAsApiResponse(agentApi.events.get(query))
|
|
45213
|
+
},
|
|
44626
45214
|
history: {
|
|
44627
45215
|
read: (query) => requestClientAsApiResponse(agentApi.history.read(query))
|
|
44628
45216
|
},
|
|
44629
|
-
|
|
44630
|
-
|
|
44631
|
-
resolve: (params) => requestClientAsApiResponse(agentApi.messages.resolve(params)),
|
|
44632
|
-
addReaction: (params, body) => requestClientAsApiResponse(agentApi.messages.addReaction(params, body)),
|
|
44633
|
-
removeReaction: (params, body) => requestClientAsApiResponse(agentApi.messages.removeReaction(params, body))
|
|
44634
|
-
},
|
|
44635
|
-
channels: {
|
|
44636
|
-
join: (params) => requestClientAsApiResponse(agentApi.channels.join(params)),
|
|
44637
|
-
leave: (params) => requestClientAsApiResponse(agentApi.channels.leave(params))
|
|
44638
|
-
},
|
|
44639
|
-
mentions: {
|
|
44640
|
-
pendingActions: (query) => requestClientAsApiResponse(agentApi.mentions.pendingActions(query ?? {})),
|
|
44641
|
-
executeAction: (body) => requestClientAsApiResponse(agentApi.mentions.executeAction(body))
|
|
44642
|
-
}
|
|
44643
|
-
};
|
|
44644
|
-
}
|
|
44645
|
-
function createAgentApiSurfaceClient(client) {
|
|
44646
|
-
const agentApi = createAgentApiClient(rawTransportForClient(client));
|
|
44647
|
-
return {
|
|
44648
|
-
events: {
|
|
44649
|
-
get: (query) => requestClientAsApiResponse(agentApi.events.get(query))
|
|
45217
|
+
knowledge: {
|
|
45218
|
+
get: (query) => requestClientAsApiResponse(agentApi.knowledge.get(query))
|
|
44650
45219
|
},
|
|
44651
45220
|
tasks: {
|
|
44652
45221
|
list: (query) => requestClientAsApiResponse(agentApi.tasks.list(query)),
|
|
@@ -44664,9 +45233,17 @@ function createAgentApiSurfaceClient(client) {
|
|
|
44664
45233
|
log: (params) => requestClientAsApiResponse(agentApi.reminders.log(params))
|
|
44665
45234
|
},
|
|
44666
45235
|
messages: {
|
|
44667
|
-
|
|
45236
|
+
send: (body) => requestClientAsApiResponse(agentApi.messages.send(body)),
|
|
45237
|
+
resolve: (params) => requestClientAsApiResponse(agentApi.messages.resolve(params)),
|
|
45238
|
+
search: (query) => requestClientAsApiResponse(agentApi.messages.search(query)),
|
|
45239
|
+
addReaction: (params, body) => requestClientAsApiResponse(agentApi.messages.addReaction(params, body)),
|
|
45240
|
+
removeReaction: (params, body) => requestClientAsApiResponse(agentApi.messages.removeReaction(params, body))
|
|
44668
45241
|
},
|
|
44669
45242
|
channels: {
|
|
45243
|
+
join: (params) => requestClientAsApiResponse(agentApi.channels.join(params)),
|
|
45244
|
+
leave: (params) => requestClientAsApiResponse(agentApi.channels.leave(params)),
|
|
45245
|
+
mute: (params) => requestClientAsApiResponse(agentApi.channels.mute(params)),
|
|
45246
|
+
unmute: (params) => requestClientAsApiResponse(agentApi.channels.unmute(params)),
|
|
44670
45247
|
members: (query) => requestClientAsApiResponse(agentApi.channels.members(query)),
|
|
44671
45248
|
resolve: (body) => requestClientAsApiResponse(agentApi.channels.resolve(body))
|
|
44672
45249
|
},
|
|
@@ -44675,18 +45252,27 @@ function createAgentApiSurfaceClient(client) {
|
|
|
44675
45252
|
},
|
|
44676
45253
|
profile: {
|
|
44677
45254
|
show: (query) => requestClientAsApiResponse(agentApi.profile.show(query)),
|
|
44678
|
-
update: (body) => requestClientAsApiResponse(agentApi.profile.update(body))
|
|
45255
|
+
update: (body) => requestClientAsApiResponse(agentApi.profile.update(body)),
|
|
45256
|
+
updateAvatar: (form) => requestMultipartContractAgentApiRoute(client, "profileAvatarUpdate", form)
|
|
44679
45257
|
},
|
|
44680
45258
|
integrations: {
|
|
44681
45259
|
list: () => requestClientAsApiResponse(agentApi.integrations.list()),
|
|
44682
45260
|
login: (body) => requestClientAsApiResponse(agentApi.integrations.login(body)),
|
|
44683
|
-
prepareApp: (body) => requestClientAsApiResponse(agentApi.integrations.prepareApp(body))
|
|
45261
|
+
prepareApp: (body) => requestClientAsApiResponse(agentApi.integrations.prepareApp(body)),
|
|
45262
|
+
rotateAppSecret: (body) => requestClientAsApiResponse(agentApi.integrations.rotateAppSecret(body))
|
|
44684
45263
|
},
|
|
44685
45264
|
actions: {
|
|
44686
45265
|
prepare: (body) => requestClientAsApiResponse(agentApi.actions.prepare(body))
|
|
44687
45266
|
},
|
|
45267
|
+
mentions: {
|
|
45268
|
+
pendingActions: (query) => requestClientAsApiResponse(agentApi.mentions.pendingActions(query ?? {})),
|
|
45269
|
+
executeAction: (body) => requestClientAsApiResponse(agentApi.mentions.executeAction(body))
|
|
45270
|
+
},
|
|
44688
45271
|
attachments: {
|
|
44689
|
-
upload: (form) => requestMultipartContractAgentApiRoute(client, "attachmentUpload", form)
|
|
45272
|
+
upload: (form) => requestMultipartContractAgentApiRoute(client, "attachmentUpload", form),
|
|
45273
|
+
download: (params) => requestClientAsApiResponse(agentApi.attachments.download(params)),
|
|
45274
|
+
view: (params) => requestClientAsApiResponse(agentApi.attachments.download(params)),
|
|
45275
|
+
comments: (params, query = {}) => requestClientAsApiResponse(agentApi.attachments.comments(params, query))
|
|
44690
45276
|
}
|
|
44691
45277
|
};
|
|
44692
45278
|
}
|
|
@@ -44782,7 +45368,6 @@ function routeFamilyForPath(pathname) {
|
|
|
44782
45368
|
if (normalized === "/internal/agent-api/activity") return "agent-api/activity";
|
|
44783
45369
|
if (normalized === "/internal/agent-api/events") return "agent-api/events";
|
|
44784
45370
|
if (normalized === "/internal/agent-api/inbox") return "agent-api/inbox";
|
|
44785
|
-
if (normalized === "/internal/agent-api/receive-ack") return "agent-api/events";
|
|
44786
45371
|
if (normalized === "/internal/agent-api/tasks/claim") return "tasks/claim";
|
|
44787
45372
|
if (normalized === "/internal/agent-api/tasks/update-status") return "tasks/update";
|
|
44788
45373
|
if (normalized === "/internal/agent-api/tasks" || normalized.startsWith("/internal/agent-api/tasks/")) {
|
|
@@ -44812,7 +45397,7 @@ function routeFamilyForPath(pathname) {
|
|
|
44812
45397
|
const firstAfterAgentId = parts[3] ?? "unknown";
|
|
44813
45398
|
if (firstAfterAgentId === "server") return "server";
|
|
44814
45399
|
if (firstAfterAgentId === "send") return "agent-api/send";
|
|
44815
|
-
if (firstAfterAgentId === "history" || firstAfterAgentId === "search" || firstAfterAgentId === "receive"
|
|
45400
|
+
if (firstAfterAgentId === "history" || firstAfterAgentId === "search" || firstAfterAgentId === "receive") {
|
|
44816
45401
|
return "agent-api/events";
|
|
44817
45402
|
}
|
|
44818
45403
|
if (firstAfterAgentId === "channel-members") return "channel-members";
|
|
@@ -44917,6 +45502,7 @@ var ApiClient = class {
|
|
|
44917
45502
|
if (!pathname.startsWith(agentPrefix)) return pathname;
|
|
44918
45503
|
const suffix = pathname.slice(agentPrefix.length);
|
|
44919
45504
|
if (suffix === "/server") return "/internal/agent-api/server";
|
|
45505
|
+
if (suffix === "/server/avatar") return "/internal/agent-api/server/avatar";
|
|
44920
45506
|
if (suffix === "/send") return "/internal/agent-api/send";
|
|
44921
45507
|
if (suffix.startsWith("/history")) return `/internal/agent-api/history${suffix.slice("/history".length)}`;
|
|
44922
45508
|
if (suffix.startsWith("/search")) return `/internal/agent-api/search${suffix.slice("/search".length)}`;
|
|
@@ -44934,6 +45520,7 @@ var ApiClient = class {
|
|
|
44934
45520
|
if (suffix === "/resolve-channel") return "/internal/agent-api/resolve-channel";
|
|
44935
45521
|
if (suffix === "/threads/unfollow") return "/internal/agent-api/threads/unfollow";
|
|
44936
45522
|
if (suffix === "/prepare-action") return "/internal/agent-api/prepare-action";
|
|
45523
|
+
if (suffix === "/channels") return "/internal/agent-api/channels";
|
|
44937
45524
|
if (suffix === "/tasks" || suffix.startsWith("/tasks?") || suffix.startsWith("/tasks/")) {
|
|
44938
45525
|
return `/internal/agent-api${suffix}`;
|
|
44939
45526
|
}
|
|
@@ -44954,6 +45541,14 @@ var ApiClient = class {
|
|
|
44954
45541
|
if (channelMembership) {
|
|
44955
45542
|
return `/internal/agent-api/channels/${channelMembership[1]}/${channelMembership[2]}`;
|
|
44956
45543
|
}
|
|
45544
|
+
const channelUpdate = /^\/channels\/([^/]+)$/.exec(suffix);
|
|
45545
|
+
if (channelUpdate) {
|
|
45546
|
+
return `/internal/agent-api/channels/${channelUpdate[1]}`;
|
|
45547
|
+
}
|
|
45548
|
+
const channelAddMember = /^\/channels\/([^/]+)\/members$/.exec(suffix);
|
|
45549
|
+
if (channelAddMember) {
|
|
45550
|
+
return `/internal/agent-api/channels/${channelAddMember[1]}/members`;
|
|
45551
|
+
}
|
|
44957
45552
|
return pathname;
|
|
44958
45553
|
}
|
|
44959
45554
|
normalizeAgentCredentialResponse(pathname, data) {
|
|
@@ -45093,10 +45688,7 @@ var ApiClient = class {
|
|
|
45093
45688
|
const res = await this.fetchWithTransportTrace(url2, pathname, init);
|
|
45094
45689
|
return this.parseJsonResponse(res);
|
|
45095
45690
|
}
|
|
45096
|
-
|
|
45097
|
-
// For non-JSON downloads (binary attachments). Caller is responsible for
|
|
45098
|
-
// consuming the body. On non-2xx, attempts to surface a JSON error.
|
|
45099
|
-
async requestRaw(method, pathname) {
|
|
45691
|
+
async requestBody(method, pathname) {
|
|
45100
45692
|
pathname = this.rewriteAgentCredentialPath(pathname);
|
|
45101
45693
|
const url2 = new URL(pathname, this.ctx.serverUrl);
|
|
45102
45694
|
const dispatcher = buildFetchDispatcher(url2.toString());
|
|
@@ -45123,6 +45715,21 @@ var ApiClient = class {
|
|
|
45123
45715
|
}
|
|
45124
45716
|
return { ok: res.ok, status: res.status, response: res, error: error48 };
|
|
45125
45717
|
}
|
|
45718
|
+
async requestBinary(method, pathname) {
|
|
45719
|
+
const res = await this.requestBody(method, pathname);
|
|
45720
|
+
if (!res.ok) {
|
|
45721
|
+
return { ok: false, status: res.status, body: new Uint8Array(), error: res.error };
|
|
45722
|
+
}
|
|
45723
|
+
return {
|
|
45724
|
+
ok: true,
|
|
45725
|
+
status: res.status,
|
|
45726
|
+
body: new Uint8Array(await res.response.arrayBuffer()),
|
|
45727
|
+
error: null
|
|
45728
|
+
};
|
|
45729
|
+
}
|
|
45730
|
+
async streamWakeHints(query) {
|
|
45731
|
+
return this.requestBody("GET", `/internal/agent-api/wake-hints/stream?${query.toString()}`);
|
|
45732
|
+
}
|
|
45126
45733
|
};
|
|
45127
45734
|
|
|
45128
45735
|
// src/auth/env.ts
|
|
@@ -45196,21 +45803,21 @@ function readProfileCredential(slug, env) {
|
|
|
45196
45803
|
}
|
|
45197
45804
|
return { filePath, data: parsed };
|
|
45198
45805
|
}
|
|
45199
|
-
function readTokenFromFile(filePath) {
|
|
45806
|
+
function readTokenFromFile(filePath, envName) {
|
|
45200
45807
|
let raw;
|
|
45201
45808
|
try {
|
|
45202
45809
|
raw = fs.readFileSync(filePath, "utf-8");
|
|
45203
45810
|
} catch (err) {
|
|
45204
45811
|
throw new AgentBootstrapError(
|
|
45205
45812
|
"TOKEN_FILE_UNREADABLE",
|
|
45206
|
-
|
|
45813
|
+
`${envName}=${filePath} could not be read: ${err.message}`
|
|
45207
45814
|
);
|
|
45208
45815
|
}
|
|
45209
45816
|
const token = raw.trim();
|
|
45210
45817
|
if (!token) {
|
|
45211
45818
|
throw new AgentBootstrapError(
|
|
45212
45819
|
"TOKEN_FILE_EMPTY",
|
|
45213
|
-
|
|
45820
|
+
`${envName}=${filePath} is empty`
|
|
45214
45821
|
);
|
|
45215
45822
|
}
|
|
45216
45823
|
return token;
|
|
@@ -45263,7 +45870,7 @@ function loadAgentContext(env = process.env) {
|
|
|
45263
45870
|
"Set only one of SLOCK_AGENT_PROXY_TOKEN or SLOCK_AGENT_PROXY_TOKEN_FILE"
|
|
45264
45871
|
);
|
|
45265
45872
|
}
|
|
45266
|
-
const token = agentProxyToken ?? (agentProxyTokenFile ? readTokenFromFile(agentProxyTokenFile) : null);
|
|
45873
|
+
const token = agentProxyToken ?? (agentProxyTokenFile ? readTokenFromFile(agentProxyTokenFile, "SLOCK_AGENT_PROXY_TOKEN_FILE") : null);
|
|
45267
45874
|
if (!token) {
|
|
45268
45875
|
throw new AgentBootstrapError(
|
|
45269
45876
|
"MISSING_AGENT_PROXY_TOKEN",
|
|
@@ -45281,32 +45888,16 @@ function loadAgentContext(env = process.env) {
|
|
|
45281
45888
|
};
|
|
45282
45889
|
}
|
|
45283
45890
|
const tokenFile = env.SLOCK_AGENT_TOKEN_FILE;
|
|
45284
|
-
if (tokenFile) {
|
|
45285
|
-
return {
|
|
45286
|
-
agentId,
|
|
45287
|
-
serverUrl,
|
|
45288
|
-
serverId,
|
|
45289
|
-
token: readTokenFromFile(tokenFile),
|
|
45290
|
-
clientMode: "legacy-machine",
|
|
45291
|
-
secretSource: "legacy-token-file",
|
|
45292
|
-
activeCapabilities
|
|
45293
|
-
};
|
|
45294
|
-
}
|
|
45295
45891
|
const tokenLiteral = env.SLOCK_AGENT_TOKEN;
|
|
45296
|
-
if (tokenLiteral) {
|
|
45297
|
-
|
|
45298
|
-
|
|
45299
|
-
|
|
45300
|
-
|
|
45301
|
-
token: tokenLiteral,
|
|
45302
|
-
clientMode: "legacy-machine",
|
|
45303
|
-
secretSource: "legacy-token-env",
|
|
45304
|
-
activeCapabilities
|
|
45305
|
-
};
|
|
45892
|
+
if (tokenFile || tokenLiteral) {
|
|
45893
|
+
throw new AgentBootstrapError(
|
|
45894
|
+
"LEGACY_MACHINE_UNSUPPORTED",
|
|
45895
|
+
"SLOCK_AGENT_TOKEN_FILE/SLOCK_AGENT_TOKEN machine-token bootstrap is no longer supported by this CLI. Upgrade or restart the daemon so it injects SLOCK_AGENT_PROXY_URL plus SLOCK_AGENT_PROXY_TOKEN_FILE, or use RAFT_PROFILE with a credential from `raft agent login`."
|
|
45896
|
+
);
|
|
45306
45897
|
}
|
|
45307
45898
|
throw new AgentBootstrapError(
|
|
45308
45899
|
"MISSING_TOKEN",
|
|
45309
|
-
"Neither SLOCK_AGENT_PROXY_TOKEN_FILE
|
|
45900
|
+
"Neither SLOCK_AGENT_PROXY_TOKEN_FILE nor SLOCK_AGENT_PROXY_TOKEN is set. The daemon should inject proxy credentials when spawning the agent process, or use RAFT_PROFILE with a credential from `raft agent login`."
|
|
45310
45901
|
);
|
|
45311
45902
|
}
|
|
45312
45903
|
|
|
@@ -46184,6 +46775,84 @@ function describeMintError(code, serverUrl) {
|
|
|
46184
46775
|
// src/commands/agent/bridge.ts
|
|
46185
46776
|
init_esm_shims();
|
|
46186
46777
|
|
|
46778
|
+
// src/daemonApiPath.ts
|
|
46779
|
+
init_esm_shims();
|
|
46780
|
+
function rawTransportForClient2(client) {
|
|
46781
|
+
return {
|
|
46782
|
+
request: (input) => client.request(input.method, input.path, input.body)
|
|
46783
|
+
};
|
|
46784
|
+
}
|
|
46785
|
+
function cliErrorFromClientFailure2(failure3) {
|
|
46786
|
+
switch (failure3.error.kind) {
|
|
46787
|
+
case "validation":
|
|
46788
|
+
switch (failure3.error.reason) {
|
|
46789
|
+
case "request_contract_mismatch":
|
|
46790
|
+
return new CliError({
|
|
46791
|
+
code: "INVALID_ARG",
|
|
46792
|
+
message: failure3.error.message,
|
|
46793
|
+
cause: failure3.error.cause
|
|
46794
|
+
});
|
|
46795
|
+
case "empty_response":
|
|
46796
|
+
case "response_contract_mismatch":
|
|
46797
|
+
return new CliError({
|
|
46798
|
+
code: "INVALID_JSON_RESPONSE",
|
|
46799
|
+
message: failure3.error.message,
|
|
46800
|
+
cause: failure3.error.cause
|
|
46801
|
+
});
|
|
46802
|
+
}
|
|
46803
|
+
break;
|
|
46804
|
+
case "transport":
|
|
46805
|
+
return new CliError({
|
|
46806
|
+
code: "CHECK_FAILED",
|
|
46807
|
+
message: failure3.error.message,
|
|
46808
|
+
cause: failure3.error.cause
|
|
46809
|
+
});
|
|
46810
|
+
case "http":
|
|
46811
|
+
return new CliError({
|
|
46812
|
+
code: "CHECK_FAILED",
|
|
46813
|
+
message: failure3.error.message
|
|
46814
|
+
});
|
|
46815
|
+
}
|
|
46816
|
+
}
|
|
46817
|
+
function apiResponseFromClientResult2(result2) {
|
|
46818
|
+
if (result2.ok) {
|
|
46819
|
+
return {
|
|
46820
|
+
ok: true,
|
|
46821
|
+
status: result2.status,
|
|
46822
|
+
data: result2.data,
|
|
46823
|
+
error: null
|
|
46824
|
+
};
|
|
46825
|
+
}
|
|
46826
|
+
if (result2.error.kind === "http") {
|
|
46827
|
+
return {
|
|
46828
|
+
ok: false,
|
|
46829
|
+
status: result2.error.status,
|
|
46830
|
+
data: null,
|
|
46831
|
+
error: result2.error.message,
|
|
46832
|
+
errorCode: result2.error.errorCode,
|
|
46833
|
+
suggestedNextAction: result2.error.suggestedNextAction
|
|
46834
|
+
};
|
|
46835
|
+
}
|
|
46836
|
+
throw cliErrorFromClientFailure2(result2);
|
|
46837
|
+
}
|
|
46838
|
+
async function requestClientAsApiResponse2(result2) {
|
|
46839
|
+
return apiResponseFromClientResult2(await result2);
|
|
46840
|
+
}
|
|
46841
|
+
function createDaemonApiSurfaceClient(client) {
|
|
46842
|
+
const daemonApi = createDaemonApiClient(rawTransportForClient2(client));
|
|
46843
|
+
return {
|
|
46844
|
+
inbox: {
|
|
46845
|
+
check: () => requestClientAsApiResponse2(daemonApi.inbox.check())
|
|
46846
|
+
},
|
|
46847
|
+
wakeHints: {
|
|
46848
|
+
fetch: (query) => requestClientAsApiResponse2(daemonApi.wakeHints.fetch(query))
|
|
46849
|
+
},
|
|
46850
|
+
activity: {
|
|
46851
|
+
forward: (body) => requestClientAsApiResponse2(daemonApi.activity.forward(body))
|
|
46852
|
+
}
|
|
46853
|
+
};
|
|
46854
|
+
}
|
|
46855
|
+
|
|
46187
46856
|
// src/agentCommsCore/bridge.ts
|
|
46188
46857
|
init_esm_shims();
|
|
46189
46858
|
import fs2 from "fs";
|
|
@@ -46994,17 +47663,17 @@ function statusFailureClass(status) {
|
|
|
46994
47663
|
if (status === 404 || status === 410) return "no_session";
|
|
46995
47664
|
return "injection_failed";
|
|
46996
47665
|
}
|
|
46997
|
-
function buildRaftChannelWakeFailedEvent(input,
|
|
47666
|
+
function buildRaftChannelWakeFailedEvent(input, failure3) {
|
|
46998
47667
|
return validateExternalAgentWakeEventEnvelope({
|
|
46999
47668
|
...input,
|
|
47000
47669
|
schema: "slock-external-agent-wake-event.v1",
|
|
47001
47670
|
kind: "wake_attempt",
|
|
47002
47671
|
outcome: "failed",
|
|
47003
47672
|
failureMeta: {
|
|
47004
|
-
failureClass:
|
|
47005
|
-
...
|
|
47673
|
+
failureClass: failure3.failureClass,
|
|
47674
|
+
...failure3.retryAfterMs ? { retryAfterMs: failure3.retryAfterMs } : {}
|
|
47006
47675
|
},
|
|
47007
|
-
reason:
|
|
47676
|
+
reason: failure3.reason,
|
|
47008
47677
|
lifecycleState: "degraded_backoff",
|
|
47009
47678
|
authority: {
|
|
47010
47679
|
source: "wake_adapter",
|
|
@@ -47049,11 +47718,12 @@ var agentBridgeCommand = defineCommand(
|
|
|
47049
47718
|
const limit = parsePositiveInt(options.limit, 50, "limit");
|
|
47050
47719
|
const activityDrainLimit = parsePositiveInt(options.activityDrainLimit, 50, "activity-drain-limit");
|
|
47051
47720
|
const client = ctx.createApiClient(agentContext);
|
|
47052
|
-
const
|
|
47053
|
-
const
|
|
47721
|
+
const daemonApi = createDaemonApiSurfaceClient(client);
|
|
47722
|
+
const pollSource = createDaemonApiWakeHintSource(daemonApi);
|
|
47723
|
+
const streamSource = options.once ? null : createDaemonApiWakeHintStreamSource(client, ctx.env);
|
|
47054
47724
|
const wakeAdapter = createWakeAdapter(options, ctx.env);
|
|
47055
47725
|
const activitySource = createActivityDrainSource(options, ctx.env);
|
|
47056
|
-
const activitySink = activitySource ?
|
|
47726
|
+
const activitySink = activitySource ? createDaemonApiActivitySink(daemonApi) : void 0;
|
|
47057
47727
|
let bridgeLock;
|
|
47058
47728
|
try {
|
|
47059
47729
|
bridgeLock = acquireAgentCommsBridgeLock({
|
|
@@ -47212,14 +47882,13 @@ var agentBridgeCommand = defineCommand(
|
|
|
47212
47882
|
function registerAgentBridgeCommand(parent, runtimeOptions) {
|
|
47213
47883
|
registerCliCommand(parent, agentBridgeCommand, runtimeOptions);
|
|
47214
47884
|
}
|
|
47215
|
-
function
|
|
47885
|
+
function createDaemonApiWakeHintSource(client) {
|
|
47216
47886
|
return {
|
|
47217
47887
|
async fetchWakeHints(input) {
|
|
47218
|
-
const
|
|
47219
|
-
since:
|
|
47220
|
-
limit:
|
|
47888
|
+
const response = await client.wakeHints.fetch({
|
|
47889
|
+
since: input.since,
|
|
47890
|
+
limit: input.limit
|
|
47221
47891
|
});
|
|
47222
|
-
const response = await client.request("GET", `/internal/agent-api/wake-hints?${query.toString()}`);
|
|
47223
47892
|
if (!response.ok) {
|
|
47224
47893
|
throw new CliError({
|
|
47225
47894
|
code: response.status >= 500 ? "SERVER_5XX" : "BRIDGE_WAKE_HINTS_FAILED",
|
|
@@ -47234,8 +47903,8 @@ function createAgentApiWakeHintSource(client) {
|
|
|
47234
47903
|
}
|
|
47235
47904
|
};
|
|
47236
47905
|
}
|
|
47237
|
-
function
|
|
47238
|
-
if (!client.
|
|
47906
|
+
function createDaemonApiWakeHintStreamSource(client, env = process.env) {
|
|
47907
|
+
if (!client.streamWakeHints) return null;
|
|
47239
47908
|
let reader = null;
|
|
47240
47909
|
let bufferedText = "";
|
|
47241
47910
|
let pendingEvent = {};
|
|
@@ -47250,7 +47919,7 @@ function createAgentApiWakeHintStreamSource(client, env = process.env) {
|
|
|
47250
47919
|
async function ensureReader(since) {
|
|
47251
47920
|
if (reader) return reader;
|
|
47252
47921
|
const query = new URLSearchParams({ since: String(since) });
|
|
47253
|
-
const response = await client.
|
|
47922
|
+
const response = await client.streamWakeHints(query);
|
|
47254
47923
|
if (!response.ok) {
|
|
47255
47924
|
throw new CliError({
|
|
47256
47925
|
code: response.status === 404 || response.status === 405 || response.status === 501 ? "BRIDGE_WAKE_STREAM_UNAVAILABLE" : response.status >= 500 ? "SERVER_5XX" : "BRIDGE_WAKE_STREAM_FAILED",
|
|
@@ -47435,10 +48104,10 @@ function createActivityDrainSource(options, env = process.env) {
|
|
|
47435
48104
|
}
|
|
47436
48105
|
};
|
|
47437
48106
|
}
|
|
47438
|
-
function
|
|
48107
|
+
function createDaemonApiActivitySink(client) {
|
|
47439
48108
|
return {
|
|
47440
48109
|
async forwardActivity(input) {
|
|
47441
|
-
const response = await client.
|
|
48110
|
+
const response = await client.activity.forward(input);
|
|
47442
48111
|
if (!response.ok) {
|
|
47443
48112
|
throw new CliError({
|
|
47444
48113
|
code: response.status >= 500 ? "SERVER_5XX" : "BRIDGE_ACTIVITY_FORWARD_FAILED",
|
|
@@ -47576,6 +48245,9 @@ function formatRuntimeContext(ctx) {
|
|
|
47576
48245
|
"Authoritative context for this agent process. Do not infer computer identity from hostname or cwd when this section is present."
|
|
47577
48246
|
];
|
|
47578
48247
|
if (ctx.agentId) lines.push(`- Agent ID: ${ctx.agentId}`);
|
|
48248
|
+
if (ctx.runtime) lines.push(`- Runtime: ${ctx.runtime}`);
|
|
48249
|
+
if (ctx.model) lines.push(`- Model: ${ctx.model}`);
|
|
48250
|
+
if (ctx.reasoningEffort) lines.push(`- Reasoning: ${ctx.reasoningEffort}`);
|
|
47579
48251
|
if (ctx.serverId) lines.push(`- Server ID: ${ctx.serverId}`);
|
|
47580
48252
|
if (ctx.machineName || ctx.machineId) {
|
|
47581
48253
|
const label = ctx.machineName && ctx.machineId ? `${ctx.machineName} (${ctx.machineId})` : ctx.machineName || ctx.machineId;
|
|
@@ -47589,14 +48261,26 @@ function formatRuntimeContext(ctx) {
|
|
|
47589
48261
|
|
|
47590
48262
|
` : "";
|
|
47591
48263
|
}
|
|
48264
|
+
function roleLabel(role) {
|
|
48265
|
+
return role && role !== "member" ? ` (${role})` : "";
|
|
48266
|
+
}
|
|
48267
|
+
function formatCurrentAgent(data) {
|
|
48268
|
+
if (!data.serverRole) return "";
|
|
48269
|
+
const lines = ["### Current Agent"];
|
|
48270
|
+
lines.push(`- Role: ${data.serverRole}`);
|
|
48271
|
+
return `${lines.join("\n")}
|
|
48272
|
+
|
|
48273
|
+
`;
|
|
48274
|
+
}
|
|
47592
48275
|
function formatServerInfo(data) {
|
|
47593
48276
|
let text = "## Server\n\n";
|
|
47594
48277
|
const channels = data.channels ?? [];
|
|
47595
48278
|
const agents = data.agents ?? [];
|
|
47596
48279
|
const humans = data.humans ?? [];
|
|
47597
48280
|
text += formatRuntimeContext(data.runtimeContext);
|
|
48281
|
+
text += formatCurrentAgent(data);
|
|
47598
48282
|
text += "### Channels\n";
|
|
47599
|
-
text +=
|
|
48283
|
+
text += "Visible public channels may appear even when `joined=false`. Private channels are shown only when you are a member; do not disclose private-channel names, membership, or content outside that channel. Use channel attention commands (`raft channel join`, `leave`, `mute`, `unmute`; `raft thread unfollow`) for your own delivery state. Admin agents can manage regular channels (`raft channel create`, `update`, `add-member`, `remove-member`) and server profile (`raft server update`). Run any subcommand with `--help` for syntax.\n";
|
|
47600
48284
|
if (channels.length > 0) {
|
|
47601
48285
|
for (const t of channels) {
|
|
47602
48286
|
const visibility = t.type === "private" ? "private" : "public";
|
|
@@ -47610,10 +48294,12 @@ function formatServerInfo(data) {
|
|
|
47610
48294
|
}
|
|
47611
48295
|
text += "\n### Agents\n";
|
|
47612
48296
|
text += "Other AI agents in this server.\n";
|
|
48297
|
+
text += "Role labels show server-level owner/admin authority; no role label means ordinary member.\n";
|
|
47613
48298
|
if (agents.length > 0) {
|
|
47614
48299
|
for (const a of agents) {
|
|
47615
|
-
|
|
47616
|
-
|
|
48300
|
+
const role = roleLabel(a.role);
|
|
48301
|
+
text += a.description ? ` - @${a.name} (${a.status})${role} \u2014 ${a.description}
|
|
48302
|
+
` : ` - @${a.name} (${a.status})${role}
|
|
47617
48303
|
`;
|
|
47618
48304
|
}
|
|
47619
48305
|
} else {
|
|
@@ -47622,10 +48308,12 @@ function formatServerInfo(data) {
|
|
|
47622
48308
|
text += "\n### Humans\n";
|
|
47623
48309
|
text += `To start a new DM: raft message send --target "dm:@name" <<'SLOCKMSG' followed by the message body and SLOCKMSG. To reply in an existing DM: reuse the target from received messages.
|
|
47624
48310
|
`;
|
|
48311
|
+
text += "Role labels show server-level owner/admin authority; no role label means ordinary member.\n";
|
|
47625
48312
|
if (humans.length > 0) {
|
|
47626
48313
|
for (const u of humans) {
|
|
47627
|
-
|
|
47628
|
-
|
|
48314
|
+
const role = roleLabel(u.role);
|
|
48315
|
+
text += u.description ? ` - @${u.name}${role} \u2014 ${u.description}
|
|
48316
|
+
` : ` - @${u.name}${role}
|
|
47629
48317
|
`;
|
|
47630
48318
|
}
|
|
47631
48319
|
} else {
|
|
@@ -47643,10 +48331,12 @@ function formatChannelMembers(data) {
|
|
|
47643
48331
|
`;
|
|
47644
48332
|
text += "Members means join/post authority for this surface.\n\n";
|
|
47645
48333
|
text += "### Agents\n";
|
|
48334
|
+
text += "Role labels show server-level owner/admin authority; no role label means ordinary member.\n";
|
|
47646
48335
|
if (agents.length > 0) {
|
|
47647
48336
|
for (const a of agents) {
|
|
47648
|
-
|
|
47649
|
-
|
|
48337
|
+
const role = roleLabel(a.role);
|
|
48338
|
+
text += a.description ? ` - @${a.name} (${a.status})${role} \u2014 ${a.description}
|
|
48339
|
+
` : ` - @${a.name} (${a.status})${role}
|
|
47650
48340
|
`;
|
|
47651
48341
|
}
|
|
47652
48342
|
} else {
|
|
@@ -47656,7 +48346,7 @@ function formatChannelMembers(data) {
|
|
|
47656
48346
|
text += "Role labels show server-level owner/admin authority; no role label means ordinary member.\n";
|
|
47657
48347
|
if (humans.length > 0) {
|
|
47658
48348
|
for (const u of humans) {
|
|
47659
|
-
const role =
|
|
48349
|
+
const role = roleLabel(u.role);
|
|
47660
48350
|
text += u.description ? ` - @${u.name}${role} \u2014 ${u.description}
|
|
47661
48351
|
` : ` - @${u.name}${role}
|
|
47662
48352
|
`;
|
|
@@ -47699,7 +48389,68 @@ function registerChannelMembersCommand(parent, runtimeOptions) {
|
|
|
47699
48389
|
registerCliCommand(parent, channelMembersCommand, runtimeOptions);
|
|
47700
48390
|
}
|
|
47701
48391
|
|
|
47702
|
-
// src/commands/channel/
|
|
48392
|
+
// src/commands/channel/create.ts
|
|
48393
|
+
init_esm_shims();
|
|
48394
|
+
function normalizeChannelName(raw) {
|
|
48395
|
+
return (raw ?? "").trim().replace(/^#/, "");
|
|
48396
|
+
}
|
|
48397
|
+
function formatCreateChannelResult(channel) {
|
|
48398
|
+
const target = `#${channel.name}`;
|
|
48399
|
+
const visibility = channel.type === "private" ? "private" : "public";
|
|
48400
|
+
return `Created ${target} (${visibility}). You are joined and can send messages there.`;
|
|
48401
|
+
}
|
|
48402
|
+
var channelCreateCommand = defineCommand(
|
|
48403
|
+
{
|
|
48404
|
+
name: "create",
|
|
48405
|
+
description: "Create a public or private channel when this agent has server admin authority",
|
|
48406
|
+
options: [
|
|
48407
|
+
{
|
|
48408
|
+
flags: "--name <name>",
|
|
48409
|
+
description: "Channel name, with or without a leading '#'"
|
|
48410
|
+
},
|
|
48411
|
+
{
|
|
48412
|
+
flags: "--description <description>",
|
|
48413
|
+
description: "Optional channel description"
|
|
48414
|
+
},
|
|
48415
|
+
{
|
|
48416
|
+
flags: "--private",
|
|
48417
|
+
description: "Create a private channel instead of a public channel"
|
|
48418
|
+
}
|
|
48419
|
+
]
|
|
48420
|
+
},
|
|
48421
|
+
async (ctx, opts) => {
|
|
48422
|
+
const name = normalizeChannelName(opts.name);
|
|
48423
|
+
if (!name) {
|
|
48424
|
+
throw new CliError({
|
|
48425
|
+
code: "INVALID_ARG",
|
|
48426
|
+
message: "--name is required"
|
|
48427
|
+
});
|
|
48428
|
+
}
|
|
48429
|
+
const agentContext = ctx.loadAgentContext();
|
|
48430
|
+
const client = ctx.createApiClient(agentContext);
|
|
48431
|
+
const res = await client.request(
|
|
48432
|
+
"POST",
|
|
48433
|
+
`/internal/agent/${encodeURIComponent(agentContext.agentId)}/channels`,
|
|
48434
|
+
{
|
|
48435
|
+
name,
|
|
48436
|
+
description: opts.description,
|
|
48437
|
+
visibility: opts.private ? "private" : "public"
|
|
48438
|
+
}
|
|
48439
|
+
);
|
|
48440
|
+
if (!res.ok || !res.data) {
|
|
48441
|
+
throw new CliError({
|
|
48442
|
+
code: res.status >= 500 ? "SERVER_5XX" : "CREATE_FAILED",
|
|
48443
|
+
message: res.error ?? `HTTP ${res.status}`
|
|
48444
|
+
});
|
|
48445
|
+
}
|
|
48446
|
+
writeText(ctx.io, formatCreateChannelResult(res.data) + "\n");
|
|
48447
|
+
}
|
|
48448
|
+
);
|
|
48449
|
+
function registerChannelCreateCommand(parent, runtimeOptions) {
|
|
48450
|
+
registerCliCommand(parent, channelCreateCommand, runtimeOptions);
|
|
48451
|
+
}
|
|
48452
|
+
|
|
48453
|
+
// src/commands/channel/update.ts
|
|
47703
48454
|
init_esm_shims();
|
|
47704
48455
|
|
|
47705
48456
|
// src/commands/channel/leave.ts
|
|
@@ -47738,7 +48489,8 @@ var channelLeaveCommand = defineCommand(
|
|
|
47738
48489
|
}
|
|
47739
48490
|
const agentContext = ctx.loadAgentContext();
|
|
47740
48491
|
const client = ctx.createApiClient(agentContext);
|
|
47741
|
-
const
|
|
48492
|
+
const agentApi = createAgentApiSurfaceClient(client);
|
|
48493
|
+
const infoRes = await agentApi.server.info();
|
|
47742
48494
|
if (!infoRes.ok) {
|
|
47743
48495
|
throw new CliError({
|
|
47744
48496
|
code: infoRes.status >= 500 ? "SERVER_5XX" : "INFO_FAILED",
|
|
@@ -47756,7 +48508,7 @@ var channelLeaveCommand = defineCommand(
|
|
|
47756
48508
|
writeText(ctx.io, formatAlreadyNotJoined(target) + "\n");
|
|
47757
48509
|
return;
|
|
47758
48510
|
}
|
|
47759
|
-
const leaveRes = await
|
|
48511
|
+
const leaveRes = await agentApi.channels.leave({
|
|
47760
48512
|
channelId: channel.id
|
|
47761
48513
|
});
|
|
47762
48514
|
if (!leaveRes.ok) {
|
|
@@ -47772,7 +48524,278 @@ function registerChannelLeaveCommand(parent, runtimeOptions) {
|
|
|
47772
48524
|
registerCliCommand(parent, channelLeaveCommand, runtimeOptions);
|
|
47773
48525
|
}
|
|
47774
48526
|
|
|
48527
|
+
// src/commands/channel/update.ts
|
|
48528
|
+
function normalizeChannelName2(raw) {
|
|
48529
|
+
return (raw ?? "").trim().replace(/^#/, "");
|
|
48530
|
+
}
|
|
48531
|
+
function formatUpdateChannelResult(channel) {
|
|
48532
|
+
const visibility = channel.type === "private" ? "private" : "public";
|
|
48533
|
+
return `Updated #${channel.name} (${visibility}).`;
|
|
48534
|
+
}
|
|
48535
|
+
var channelUpdateCommand = defineCommand(
|
|
48536
|
+
{
|
|
48537
|
+
name: "update",
|
|
48538
|
+
description: "Edit a regular channel when this agent has server admin authority",
|
|
48539
|
+
options: [
|
|
48540
|
+
{
|
|
48541
|
+
flags: "--target <target>",
|
|
48542
|
+
description: "Regular channel to edit, e.g. '#engineering'"
|
|
48543
|
+
},
|
|
48544
|
+
{
|
|
48545
|
+
flags: "--name <name>",
|
|
48546
|
+
description: "New channel name, with or without a leading '#'"
|
|
48547
|
+
},
|
|
48548
|
+
{
|
|
48549
|
+
flags: "--description <description>",
|
|
48550
|
+
description: "New channel description"
|
|
48551
|
+
},
|
|
48552
|
+
{
|
|
48553
|
+
flags: "--public",
|
|
48554
|
+
description: "Make the channel public"
|
|
48555
|
+
},
|
|
48556
|
+
{
|
|
48557
|
+
flags: "--private",
|
|
48558
|
+
description: "Make the channel private"
|
|
48559
|
+
}
|
|
48560
|
+
]
|
|
48561
|
+
},
|
|
48562
|
+
async (ctx, opts) => {
|
|
48563
|
+
const target = opts.target ?? "";
|
|
48564
|
+
const channelName = parseRegularChannelTarget(target);
|
|
48565
|
+
if (!channelName) {
|
|
48566
|
+
throw new CliError({
|
|
48567
|
+
code: "INVALID_TARGET",
|
|
48568
|
+
message: "Target must be a regular channel in the form '#channel-name'. DMs and thread targets are not supported."
|
|
48569
|
+
});
|
|
48570
|
+
}
|
|
48571
|
+
if (opts.public && opts.private) {
|
|
48572
|
+
throw new CliError({
|
|
48573
|
+
code: "INVALID_ARG",
|
|
48574
|
+
message: "Use either --public or --private, not both."
|
|
48575
|
+
});
|
|
48576
|
+
}
|
|
48577
|
+
const body = {};
|
|
48578
|
+
if (opts.name !== void 0) body.name = normalizeChannelName2(opts.name);
|
|
48579
|
+
if (opts.description !== void 0) body.description = opts.description;
|
|
48580
|
+
if (opts.public) body.visibility = "public";
|
|
48581
|
+
if (opts.private) body.visibility = "private";
|
|
48582
|
+
if (body.name === void 0 && body.description === void 0 && body.visibility === void 0) {
|
|
48583
|
+
throw new CliError({
|
|
48584
|
+
code: "INVALID_ARG",
|
|
48585
|
+
message: "Provide at least one of --name, --description, --public, or --private."
|
|
48586
|
+
});
|
|
48587
|
+
}
|
|
48588
|
+
const agentContext = ctx.loadAgentContext();
|
|
48589
|
+
const client = ctx.createApiClient(agentContext);
|
|
48590
|
+
const infoRes = await client.request(
|
|
48591
|
+
"GET",
|
|
48592
|
+
`/internal/agent/${encodeURIComponent(agentContext.agentId)}/server`
|
|
48593
|
+
);
|
|
48594
|
+
if (!infoRes.ok) {
|
|
48595
|
+
throw new CliError({
|
|
48596
|
+
code: infoRes.status >= 500 ? "SERVER_5XX" : "INFO_FAILED",
|
|
48597
|
+
message: infoRes.error ?? `HTTP ${infoRes.status}`
|
|
48598
|
+
});
|
|
48599
|
+
}
|
|
48600
|
+
const channel = (infoRes.data?.channels ?? []).find((candidate) => candidate.name === channelName);
|
|
48601
|
+
if (!channel) {
|
|
48602
|
+
throw new CliError({
|
|
48603
|
+
code: "NOT_FOUND",
|
|
48604
|
+
message: `Channel not found: ${target}`
|
|
48605
|
+
});
|
|
48606
|
+
}
|
|
48607
|
+
const updateRes = await client.request(
|
|
48608
|
+
"PATCH",
|
|
48609
|
+
`/internal/agent/${encodeURIComponent(agentContext.agentId)}/channels/${encodeURIComponent(channel.id)}`,
|
|
48610
|
+
body
|
|
48611
|
+
);
|
|
48612
|
+
if (!updateRes.ok || !updateRes.data) {
|
|
48613
|
+
throw new CliError({
|
|
48614
|
+
code: updateRes.status >= 500 ? "SERVER_5XX" : "UPDATE_FAILED",
|
|
48615
|
+
message: updateRes.error ?? `HTTP ${updateRes.status}`
|
|
48616
|
+
});
|
|
48617
|
+
}
|
|
48618
|
+
writeText(ctx.io, formatUpdateChannelResult(updateRes.data) + "\n");
|
|
48619
|
+
}
|
|
48620
|
+
);
|
|
48621
|
+
function registerChannelUpdateCommand(parent, runtimeOptions) {
|
|
48622
|
+
registerCliCommand(parent, channelUpdateCommand, runtimeOptions);
|
|
48623
|
+
}
|
|
48624
|
+
|
|
48625
|
+
// src/commands/channel/add-member.ts
|
|
48626
|
+
init_esm_shims();
|
|
48627
|
+
function normalizeHandle(raw) {
|
|
48628
|
+
return (raw ?? "").trim().replace(/^@/, "");
|
|
48629
|
+
}
|
|
48630
|
+
function formatAddMemberResult(target, memberType, memberName, alreadyMember) {
|
|
48631
|
+
const member = `@${memberName}`;
|
|
48632
|
+
if (alreadyMember) {
|
|
48633
|
+
return `${member} is already in ${target}.`;
|
|
48634
|
+
}
|
|
48635
|
+
return `Added ${member} to ${target} as ${memberType === "agent" ? "an agent" : "a user"}.`;
|
|
48636
|
+
}
|
|
48637
|
+
var channelAddMemberCommand = defineCommand(
|
|
48638
|
+
{
|
|
48639
|
+
name: "add-member",
|
|
48640
|
+
description: "Add a human or agent to a regular channel when this agent has server admin authority",
|
|
48641
|
+
options: [
|
|
48642
|
+
{
|
|
48643
|
+
flags: "--target <target>",
|
|
48644
|
+
description: "Regular channel to add a member to, e.g. '#engineering'"
|
|
48645
|
+
},
|
|
48646
|
+
{
|
|
48647
|
+
flags: "--user <handle>",
|
|
48648
|
+
description: "Human handle to add, e.g. '@alice'"
|
|
48649
|
+
},
|
|
48650
|
+
{
|
|
48651
|
+
flags: "--agent <handle>",
|
|
48652
|
+
description: "Agent handle to add, e.g. '@assistant'"
|
|
48653
|
+
}
|
|
48654
|
+
]
|
|
48655
|
+
},
|
|
48656
|
+
async (ctx, opts) => {
|
|
48657
|
+
const target = opts.target ?? "";
|
|
48658
|
+
const channelName = parseRegularChannelTarget(target);
|
|
48659
|
+
if (!channelName) {
|
|
48660
|
+
throw new CliError({
|
|
48661
|
+
code: "INVALID_TARGET",
|
|
48662
|
+
message: "Target must be a regular channel in the form '#channel-name'. DMs and thread targets are not supported."
|
|
48663
|
+
});
|
|
48664
|
+
}
|
|
48665
|
+
const user = normalizeHandle(opts.user);
|
|
48666
|
+
const agent = normalizeHandle(opts.agent);
|
|
48667
|
+
if ((user ? 1 : 0) + (agent ? 1 : 0) !== 1) {
|
|
48668
|
+
throw new CliError({
|
|
48669
|
+
code: "INVALID_ARG",
|
|
48670
|
+
message: "Provide exactly one of --user or --agent."
|
|
48671
|
+
});
|
|
48672
|
+
}
|
|
48673
|
+
const agentContext = ctx.loadAgentContext();
|
|
48674
|
+
const client = ctx.createApiClient(agentContext);
|
|
48675
|
+
const infoRes = await client.request(
|
|
48676
|
+
"GET",
|
|
48677
|
+
`/internal/agent/${encodeURIComponent(agentContext.agentId)}/server`
|
|
48678
|
+
);
|
|
48679
|
+
if (!infoRes.ok) {
|
|
48680
|
+
throw new CliError({
|
|
48681
|
+
code: infoRes.status >= 500 ? "SERVER_5XX" : "INFO_FAILED",
|
|
48682
|
+
message: infoRes.error ?? `HTTP ${infoRes.status}`
|
|
48683
|
+
});
|
|
48684
|
+
}
|
|
48685
|
+
const channel = (infoRes.data?.channels ?? []).find((candidate) => candidate.name === channelName);
|
|
48686
|
+
if (!channel) {
|
|
48687
|
+
throw new CliError({
|
|
48688
|
+
code: "NOT_FOUND",
|
|
48689
|
+
message: `Channel not found: ${target}`
|
|
48690
|
+
});
|
|
48691
|
+
}
|
|
48692
|
+
const body = user ? { user } : { agent };
|
|
48693
|
+
const addRes = await client.request(
|
|
48694
|
+
"POST",
|
|
48695
|
+
`/internal/agent/${encodeURIComponent(agentContext.agentId)}/channels/${encodeURIComponent(channel.id)}/members`,
|
|
48696
|
+
body
|
|
48697
|
+
);
|
|
48698
|
+
if (!addRes.ok) {
|
|
48699
|
+
throw new CliError({
|
|
48700
|
+
code: addRes.status >= 500 ? "SERVER_5XX" : "MEMBERS_FAILED",
|
|
48701
|
+
message: addRes.error ?? `HTTP ${addRes.status}`
|
|
48702
|
+
});
|
|
48703
|
+
}
|
|
48704
|
+
const memberName = addRes.data?.member?.name ?? (user || agent);
|
|
48705
|
+
const memberType = addRes.data?.member?.type === "agent" ? "agent" : "user";
|
|
48706
|
+
writeText(ctx.io, formatAddMemberResult(target, memberType, memberName, addRes.data?.alreadyMember === true) + "\n");
|
|
48707
|
+
}
|
|
48708
|
+
);
|
|
48709
|
+
function registerChannelAddMemberCommand(parent, runtimeOptions) {
|
|
48710
|
+
registerCliCommand(parent, channelAddMemberCommand, runtimeOptions);
|
|
48711
|
+
}
|
|
48712
|
+
|
|
48713
|
+
// src/commands/channel/remove-member.ts
|
|
48714
|
+
init_esm_shims();
|
|
48715
|
+
function normalizeHandle2(raw) {
|
|
48716
|
+
return (raw ?? "").trim().replace(/^@/, "");
|
|
48717
|
+
}
|
|
48718
|
+
function formatRemoveMemberResult(target, memberName, wasMember) {
|
|
48719
|
+
const member = `@${memberName}`;
|
|
48720
|
+
return wasMember ? `Removed ${member} from ${target}.` : `${member} was not in ${target}.`;
|
|
48721
|
+
}
|
|
48722
|
+
var channelRemoveMemberCommand = defineCommand(
|
|
48723
|
+
{
|
|
48724
|
+
name: "remove-member",
|
|
48725
|
+
description: "Remove a human or agent from a regular channel when this agent has server admin authority",
|
|
48726
|
+
options: [
|
|
48727
|
+
{
|
|
48728
|
+
flags: "--target <target>",
|
|
48729
|
+
description: "Regular channel to remove a member from, e.g. '#engineering'"
|
|
48730
|
+
},
|
|
48731
|
+
{
|
|
48732
|
+
flags: "--user <handle>",
|
|
48733
|
+
description: "Human handle to remove, e.g. '@alice'"
|
|
48734
|
+
},
|
|
48735
|
+
{
|
|
48736
|
+
flags: "--agent <handle>",
|
|
48737
|
+
description: "Agent handle to remove, e.g. '@assistant'"
|
|
48738
|
+
}
|
|
48739
|
+
]
|
|
48740
|
+
},
|
|
48741
|
+
async (ctx, opts) => {
|
|
48742
|
+
const target = opts.target ?? "";
|
|
48743
|
+
const channelName = parseRegularChannelTarget(target);
|
|
48744
|
+
if (!channelName) {
|
|
48745
|
+
throw new CliError({
|
|
48746
|
+
code: "INVALID_TARGET",
|
|
48747
|
+
message: "Target must be a regular channel in the form '#channel-name'. DMs and thread targets are not supported."
|
|
48748
|
+
});
|
|
48749
|
+
}
|
|
48750
|
+
const user = normalizeHandle2(opts.user);
|
|
48751
|
+
const agent = normalizeHandle2(opts.agent);
|
|
48752
|
+
if ((user ? 1 : 0) + (agent ? 1 : 0) !== 1) {
|
|
48753
|
+
throw new CliError({
|
|
48754
|
+
code: "INVALID_ARG",
|
|
48755
|
+
message: "Provide exactly one of --user or --agent."
|
|
48756
|
+
});
|
|
48757
|
+
}
|
|
48758
|
+
const agentContext = ctx.loadAgentContext();
|
|
48759
|
+
const client = ctx.createApiClient(agentContext);
|
|
48760
|
+
const infoRes = await client.request(
|
|
48761
|
+
"GET",
|
|
48762
|
+
`/internal/agent/${encodeURIComponent(agentContext.agentId)}/server`
|
|
48763
|
+
);
|
|
48764
|
+
if (!infoRes.ok) {
|
|
48765
|
+
throw new CliError({
|
|
48766
|
+
code: infoRes.status >= 500 ? "SERVER_5XX" : "INFO_FAILED",
|
|
48767
|
+
message: infoRes.error ?? `HTTP ${infoRes.status}`
|
|
48768
|
+
});
|
|
48769
|
+
}
|
|
48770
|
+
const channel = (infoRes.data?.channels ?? []).find((candidate) => candidate.name === channelName);
|
|
48771
|
+
if (!channel) {
|
|
48772
|
+
throw new CliError({
|
|
48773
|
+
code: "NOT_FOUND",
|
|
48774
|
+
message: `Channel not found: ${target}`
|
|
48775
|
+
});
|
|
48776
|
+
}
|
|
48777
|
+
const body = user ? { user } : { agent };
|
|
48778
|
+
const removeRes = await client.request(
|
|
48779
|
+
"DELETE",
|
|
48780
|
+
`/internal/agent/${encodeURIComponent(agentContext.agentId)}/channels/${encodeURIComponent(channel.id)}/members`,
|
|
48781
|
+
body
|
|
48782
|
+
);
|
|
48783
|
+
if (!removeRes.ok) {
|
|
48784
|
+
throw new CliError({
|
|
48785
|
+
code: removeRes.status >= 500 ? "SERVER_5XX" : "MEMBERS_FAILED",
|
|
48786
|
+
message: removeRes.error ?? `HTTP ${removeRes.status}`
|
|
48787
|
+
});
|
|
48788
|
+
}
|
|
48789
|
+
const memberName = removeRes.data?.member?.name ?? (user || agent);
|
|
48790
|
+
writeText(ctx.io, formatRemoveMemberResult(target, memberName, removeRes.data?.wasMember === true) + "\n");
|
|
48791
|
+
}
|
|
48792
|
+
);
|
|
48793
|
+
function registerChannelRemoveMemberCommand(parent, runtimeOptions) {
|
|
48794
|
+
registerCliCommand(parent, channelRemoveMemberCommand, runtimeOptions);
|
|
48795
|
+
}
|
|
48796
|
+
|
|
47775
48797
|
// src/commands/channel/join.ts
|
|
48798
|
+
init_esm_shims();
|
|
47776
48799
|
function formatJoinChannelResult(target) {
|
|
47777
48800
|
return `Joined ${target}. You can now send messages there and receive ordinary channel delivery.`;
|
|
47778
48801
|
}
|
|
@@ -47801,7 +48824,8 @@ var channelJoinCommand = defineCommand(
|
|
|
47801
48824
|
}
|
|
47802
48825
|
const agentContext = ctx.loadAgentContext();
|
|
47803
48826
|
const client = ctx.createApiClient(agentContext);
|
|
47804
|
-
const
|
|
48827
|
+
const agentApi = createAgentApiSurfaceClient(client);
|
|
48828
|
+
const infoRes = await agentApi.server.info();
|
|
47805
48829
|
if (!infoRes.ok) {
|
|
47806
48830
|
throw new CliError({
|
|
47807
48831
|
code: infoRes.status >= 500 ? "SERVER_5XX" : "INFO_FAILED",
|
|
@@ -47819,7 +48843,7 @@ var channelJoinCommand = defineCommand(
|
|
|
47819
48843
|
writeText(ctx.io, formatAlreadyJoined(target) + "\n");
|
|
47820
48844
|
return;
|
|
47821
48845
|
}
|
|
47822
|
-
const joinRes = await
|
|
48846
|
+
const joinRes = await agentApi.channels.join({
|
|
47823
48847
|
channelId: channel.id
|
|
47824
48848
|
});
|
|
47825
48849
|
if (!joinRes.ok) {
|
|
@@ -47877,7 +48901,8 @@ function makeChannelMuteCommand(action) {
|
|
|
47877
48901
|
}
|
|
47878
48902
|
const agentContext = ctx.loadAgentContext();
|
|
47879
48903
|
const client = ctx.createApiClient(agentContext);
|
|
47880
|
-
const
|
|
48904
|
+
const agentApi = createAgentApiSurfaceClient(client);
|
|
48905
|
+
const infoRes = await agentApi.server.info();
|
|
47881
48906
|
if (!infoRes.ok) {
|
|
47882
48907
|
throw new CliError({
|
|
47883
48908
|
code: infoRes.status >= 500 ? "SERVER_5XX" : "INFO_FAILED",
|
|
@@ -47891,10 +48916,7 @@ function makeChannelMuteCommand(action) {
|
|
|
47891
48916
|
message: `Channel not found: ${target}`
|
|
47892
48917
|
});
|
|
47893
48918
|
}
|
|
47894
|
-
const res = await
|
|
47895
|
-
"POST",
|
|
47896
|
-
`/internal/agent/${encodeURIComponent(agentContext.agentId)}/channels/${encodeURIComponent(channel.id)}/${action}`
|
|
47897
|
-
);
|
|
48919
|
+
const res = action === "mute" ? await agentApi.channels.mute({ channelId: channel.id }) : await agentApi.channels.unmute({ channelId: channel.id });
|
|
47898
48920
|
if (!res.ok) {
|
|
47899
48921
|
throw new CliError({
|
|
47900
48922
|
code: res.status >= 500 ? "SERVER_5XX" : action === "mute" ? "MUTE_FAILED" : "UNMUTE_FAILED",
|
|
@@ -47925,7 +48947,7 @@ var serverInfoCommand = defineCommand(
|
|
|
47925
48947
|
async (ctx) => {
|
|
47926
48948
|
const agentContext = ctx.loadAgentContext();
|
|
47927
48949
|
const client = ctx.createApiClient(agentContext);
|
|
47928
|
-
const res = await
|
|
48950
|
+
const res = await createAgentApiSurfaceClient(client).server.info();
|
|
47929
48951
|
if (!res.ok) {
|
|
47930
48952
|
const code = res.status >= 500 ? "SERVER_5XX" : "INFO_FAILED";
|
|
47931
48953
|
throw new CliError({
|
|
@@ -47947,16 +48969,341 @@ function registerServerInfoCommand(parent, runtimeOptions) {
|
|
|
47947
48969
|
registerCliCommand(parent, serverInfoCommand, runtimeOptions);
|
|
47948
48970
|
}
|
|
47949
48971
|
|
|
47950
|
-
// src/commands/
|
|
48972
|
+
// src/commands/server/update.ts
|
|
47951
48973
|
init_esm_shims();
|
|
47952
|
-
|
|
47953
|
-
|
|
47954
|
-
|
|
47955
|
-
|
|
47956
|
-
|
|
47957
|
-
|
|
47958
|
-
|
|
48974
|
+
|
|
48975
|
+
// src/commands/profile/update.ts
|
|
48976
|
+
init_esm_shims();
|
|
48977
|
+
import { basename } from "path";
|
|
48978
|
+
import { existsSync, readFileSync as readFileSync2, statSync } from "fs";
|
|
48979
|
+
|
|
48980
|
+
// src/commands/profile/_format.ts
|
|
48981
|
+
init_esm_shims();
|
|
48982
|
+
function formatCreatedAgents(createdAgents) {
|
|
48983
|
+
if (createdAgents.length === 0) {
|
|
48984
|
+
return ["- Created Agents: none"];
|
|
48985
|
+
}
|
|
48986
|
+
return [
|
|
48987
|
+
`- Created Agents (${createdAgents.length}):`,
|
|
48988
|
+
...createdAgents.map((createdAgent) => ` - @${createdAgent.name} (${getRuntimeDisplayName(createdAgent.runtime)}, ${createdAgent.status})`)
|
|
48989
|
+
];
|
|
48990
|
+
}
|
|
48991
|
+
function formatHumanProfile(profile) {
|
|
48992
|
+
const lines = [
|
|
48993
|
+
"## Profile",
|
|
48994
|
+
"",
|
|
48995
|
+
"- Type: human",
|
|
48996
|
+
`- Handle: @${profile.name}`,
|
|
48997
|
+
`- Display Name: ${profile.displayName ?? "(none)"}`,
|
|
48998
|
+
`- Description: ${profile.description ?? "(none)"}`,
|
|
48999
|
+
`- Membership: ${profile.membershipStatus}`
|
|
49000
|
+
];
|
|
49001
|
+
if (profile.role) lines.push(`- Role: ${profile.role}`);
|
|
49002
|
+
if (profile.joinedAt) lines.push(`- Joined: ${profile.joinedAt}`);
|
|
49003
|
+
if (profile.email) lines.push(`- Email: ${profile.email}`);
|
|
49004
|
+
return [...lines, ...formatCreatedAgents(profile.createdAgents)].join("\n");
|
|
49005
|
+
}
|
|
49006
|
+
function formatCreator(profile) {
|
|
49007
|
+
if (!profile.creator) return null;
|
|
49008
|
+
return profile.creator.displayName ? `${profile.creator.displayName} (@${profile.creator.name})` : `@${profile.creator.name}`;
|
|
49009
|
+
}
|
|
49010
|
+
function formatAgentProfile(profile) {
|
|
49011
|
+
const lines = [
|
|
49012
|
+
"## Profile",
|
|
49013
|
+
"",
|
|
49014
|
+
"- Type: agent",
|
|
49015
|
+
`- Handle: @${profile.name}`,
|
|
49016
|
+
`- Display Name: ${profile.displayName ?? "(none)"}`,
|
|
49017
|
+
`- Description: ${profile.description ?? "(none)"}`,
|
|
49018
|
+
`- Status: ${profile.status}`,
|
|
49019
|
+
`- Role: ${profile.serverRole}`,
|
|
49020
|
+
`- Runtime: ${getRuntimeDisplayName(profile.runtime)}`,
|
|
49021
|
+
`- Model: ${profile.model}`,
|
|
49022
|
+
`- Reasoning: ${profile.reasoningEffort ?? "medium"}`
|
|
49023
|
+
];
|
|
49024
|
+
if (profile.executionMode) lines.push(`- Execution: ${profile.executionMode}`);
|
|
49025
|
+
if (profile.computerName || profile.computerId) {
|
|
49026
|
+
const label = profile.computerName && profile.computerId ? `${profile.computerName} (${profile.computerId})` : profile.computerName ?? profile.computerId;
|
|
49027
|
+
lines.push(`- Computer: ${label}`);
|
|
49028
|
+
}
|
|
49029
|
+
if (profile.computerHostname) lines.push(`- Hostname: ${profile.computerHostname}`);
|
|
49030
|
+
if (profile.daemonVersion) lines.push(`- Daemon: v${profile.daemonVersion}`);
|
|
49031
|
+
lines.push(`- Created: ${profile.createdAt}`);
|
|
49032
|
+
if (profile.deletedAt) lines.push(`- Deleted At: ${profile.deletedAt}`);
|
|
49033
|
+
const creator = formatCreator(profile);
|
|
49034
|
+
if (creator) lines.push(`- Creator: ${creator}`);
|
|
49035
|
+
return [...lines, ...formatCreatedAgents(profile.createdAgents)].join("\n");
|
|
49036
|
+
}
|
|
49037
|
+
function formatProfile(profile) {
|
|
49038
|
+
return profile.kind === "human" ? formatHumanProfile(profile) : formatAgentProfile(profile);
|
|
49039
|
+
}
|
|
49040
|
+
|
|
49041
|
+
// src/commands/profile/update.ts
|
|
49042
|
+
var MAX_PROFILE_AVATAR_BYTES = 2 * 1024 * 1024;
|
|
49043
|
+
var PROFILE_AVATAR_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
49044
|
+
"image/jpeg",
|
|
49045
|
+
"image/png",
|
|
49046
|
+
"image/gif",
|
|
49047
|
+
"image/webp"
|
|
49048
|
+
]);
|
|
49049
|
+
var FILENAME_MIME_MAP = {
|
|
49050
|
+
".jpg": "image/jpeg",
|
|
49051
|
+
".jpeg": "image/jpeg",
|
|
49052
|
+
".png": "image/png",
|
|
49053
|
+
".gif": "image/gif",
|
|
49054
|
+
".webp": "image/webp"
|
|
49055
|
+
};
|
|
49056
|
+
var MAX_PROFILE_DESCRIPTION_LENGTH = 3e3;
|
|
49057
|
+
var MAX_PROFILE_DISPLAY_NAME_LENGTH = 80;
|
|
49058
|
+
function inferImageMimeType(filename, buffer) {
|
|
49059
|
+
const lowerFilename = filename.toLowerCase();
|
|
49060
|
+
if (buffer.length >= 8 && buffer.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]))) {
|
|
49061
|
+
return "image/png";
|
|
49062
|
+
}
|
|
49063
|
+
if (buffer.length >= 3 && buffer.subarray(0, 3).equals(Buffer.from([255, 216, 255]))) {
|
|
49064
|
+
return "image/jpeg";
|
|
49065
|
+
}
|
|
49066
|
+
if (buffer.length >= 6) {
|
|
49067
|
+
const header = buffer.subarray(0, 6).toString("ascii");
|
|
49068
|
+
if (header === "GIF87a" || header === "GIF89a") return "image/gif";
|
|
49069
|
+
}
|
|
49070
|
+
if (buffer.length >= 12 && buffer.subarray(0, 4).toString("ascii") === "RIFF" && buffer.subarray(8, 12).toString("ascii") === "WEBP") {
|
|
49071
|
+
return "image/webp";
|
|
49072
|
+
}
|
|
49073
|
+
const dot = lowerFilename.lastIndexOf(".");
|
|
49074
|
+
return dot >= 0 ? FILENAME_MIME_MAP[lowerFilename.slice(dot)] ?? null : null;
|
|
49075
|
+
}
|
|
49076
|
+
function readAvatarFile(avatarFile) {
|
|
49077
|
+
if (!existsSync(avatarFile)) {
|
|
49078
|
+
throw cliError("PROFILE_FILE_NOT_FOUND", `Avatar file does not exist: ${avatarFile}`);
|
|
49079
|
+
}
|
|
49080
|
+
const stat2 = statSync(avatarFile);
|
|
49081
|
+
if (!stat2.isFile()) {
|
|
49082
|
+
throw cliError("PROFILE_FILE_NOT_FOUND", `Avatar file is not a regular file: ${avatarFile}`);
|
|
49083
|
+
}
|
|
49084
|
+
if (stat2.size > MAX_PROFILE_AVATAR_BYTES) {
|
|
49085
|
+
throw cliError(
|
|
49086
|
+
"PROFILE_AVATAR_TOO_LARGE",
|
|
49087
|
+
`Avatar file is ${stat2.size} bytes; max size is ${MAX_PROFILE_AVATAR_BYTES} bytes`
|
|
49088
|
+
);
|
|
49089
|
+
}
|
|
49090
|
+
const buffer = readFileSync2(avatarFile);
|
|
49091
|
+
const filename = basename(avatarFile);
|
|
49092
|
+
const mimeType = inferImageMimeType(filename, buffer);
|
|
49093
|
+
if (!mimeType || !PROFILE_AVATAR_MIME_TYPES.has(mimeType)) {
|
|
49094
|
+
throw cliError(
|
|
49095
|
+
"PROFILE_AVATAR_BAD_FORMAT",
|
|
49096
|
+
"Avatar must be a JPEG, PNG, GIF, or WebP image"
|
|
49097
|
+
);
|
|
49098
|
+
}
|
|
49099
|
+
return { filename, buffer, mimeType };
|
|
47959
49100
|
}
|
|
49101
|
+
function normalizeAvatarUrl(avatarUrl) {
|
|
49102
|
+
const trimmed = avatarUrl.trim();
|
|
49103
|
+
if (trimmed.length === 0) {
|
|
49104
|
+
throw cliError("INVALID_ARG", "--avatar-url must not be empty");
|
|
49105
|
+
}
|
|
49106
|
+
if (!trimmed.startsWith("pixel:")) {
|
|
49107
|
+
throw cliError("INVALID_ARG", "--avatar-url currently supports only pixel avatar URLs; use --avatar-file for image uploads");
|
|
49108
|
+
}
|
|
49109
|
+
return trimmed;
|
|
49110
|
+
}
|
|
49111
|
+
var profileUpdateCommand = defineCommand(
|
|
49112
|
+
{
|
|
49113
|
+
name: "update",
|
|
49114
|
+
description: "Update your own profile",
|
|
49115
|
+
options: [
|
|
49116
|
+
{ flags: "--avatar-file <path>", description: "Path to a local image file to use as your avatar" },
|
|
49117
|
+
{ flags: "--avatar-url <value>", description: "Set a pixel avatar URL such as pixel:random:<seed>" },
|
|
49118
|
+
{ flags: "--display-name <name>", description: "Set your display name (non-empty)" },
|
|
49119
|
+
{ flags: "--description <text>", description: "Set your profile description (non-empty)" },
|
|
49120
|
+
{ flags: "--json", description: "Emit machine-readable JSON" }
|
|
49121
|
+
]
|
|
49122
|
+
},
|
|
49123
|
+
async (ctx, opts) => {
|
|
49124
|
+
const hasAvatar = opts.avatarFile !== void 0;
|
|
49125
|
+
const hasAvatarUrl = opts.avatarUrl !== void 0;
|
|
49126
|
+
const hasDisplayName = opts.displayName !== void 0;
|
|
49127
|
+
const hasDescription = opts.description !== void 0;
|
|
49128
|
+
if (!hasAvatar && !hasAvatarUrl && !hasDisplayName && !hasDescription) {
|
|
49129
|
+
throw cliError("INVALID_ARG", "Provide at least one of --avatar-file, --avatar-url, --display-name, or --description");
|
|
49130
|
+
}
|
|
49131
|
+
if (hasAvatar && hasAvatarUrl) {
|
|
49132
|
+
throw cliError("INVALID_ARG", "Use either --avatar-file or --avatar-url, not both");
|
|
49133
|
+
}
|
|
49134
|
+
let normalizedAvatarUrl;
|
|
49135
|
+
if (hasAvatarUrl) {
|
|
49136
|
+
normalizedAvatarUrl = normalizeAvatarUrl(opts.avatarUrl);
|
|
49137
|
+
}
|
|
49138
|
+
let trimmedDisplayName;
|
|
49139
|
+
if (hasDisplayName) {
|
|
49140
|
+
trimmedDisplayName = opts.displayName.trim();
|
|
49141
|
+
if (trimmedDisplayName.length === 0) {
|
|
49142
|
+
throw cliError("INVALID_ARG", "--display-name must not be empty");
|
|
49143
|
+
}
|
|
49144
|
+
if (trimmedDisplayName.length > MAX_PROFILE_DISPLAY_NAME_LENGTH) {
|
|
49145
|
+
throw cliError("INVALID_ARG", `--display-name must be at most ${MAX_PROFILE_DISPLAY_NAME_LENGTH} characters`);
|
|
49146
|
+
}
|
|
49147
|
+
}
|
|
49148
|
+
if (hasDescription) {
|
|
49149
|
+
if (opts.description.length === 0) {
|
|
49150
|
+
throw cliError("INVALID_ARG", "--description must not be empty");
|
|
49151
|
+
}
|
|
49152
|
+
if (opts.description.length > MAX_PROFILE_DESCRIPTION_LENGTH) {
|
|
49153
|
+
throw cliError("INVALID_ARG", `--description must be at most ${MAX_PROFILE_DESCRIPTION_LENGTH} characters`);
|
|
49154
|
+
}
|
|
49155
|
+
}
|
|
49156
|
+
const avatar = hasAvatar ? readAvatarFile(opts.avatarFile) : null;
|
|
49157
|
+
const agentContext = ctx.loadAgentContext();
|
|
49158
|
+
const client = ctx.createApiClient(agentContext);
|
|
49159
|
+
const agentApi = createAgentApiSurfaceClient(client);
|
|
49160
|
+
let latestProfile = null;
|
|
49161
|
+
if (hasAvatarUrl || hasDisplayName || hasDescription) {
|
|
49162
|
+
const body = {};
|
|
49163
|
+
if (hasAvatarUrl) {
|
|
49164
|
+
body.avatarUrl = normalizedAvatarUrl;
|
|
49165
|
+
}
|
|
49166
|
+
if (hasDisplayName) {
|
|
49167
|
+
body.displayName = trimmedDisplayName;
|
|
49168
|
+
}
|
|
49169
|
+
if (hasDescription) {
|
|
49170
|
+
body.description = opts.description;
|
|
49171
|
+
}
|
|
49172
|
+
const res = await agentApi.profile.update(body);
|
|
49173
|
+
if (!res.ok || !res.data) {
|
|
49174
|
+
const code = res.errorCode ?? (res.status >= 500 ? "SERVER_5XX" : "PROFILE_UPDATE_FAILED");
|
|
49175
|
+
throw cliError(code, res.error ?? `HTTP ${res.status}`);
|
|
49176
|
+
}
|
|
49177
|
+
latestProfile = res.data;
|
|
49178
|
+
}
|
|
49179
|
+
if (hasAvatar) {
|
|
49180
|
+
const form = new FormData();
|
|
49181
|
+
const avatarBytes = Uint8Array.from(avatar.buffer);
|
|
49182
|
+
form.append("avatar", new Blob([avatarBytes], { type: avatar.mimeType }), avatar.filename);
|
|
49183
|
+
const res = await agentApi.profile.updateAvatar(form);
|
|
49184
|
+
if (!res.ok || !res.data) {
|
|
49185
|
+
const code = res.errorCode ?? (res.status >= 500 ? "SERVER_5XX" : "PROFILE_UPDATE_FAILED");
|
|
49186
|
+
throw cliError(code, res.error ?? `HTTP ${res.status}`);
|
|
49187
|
+
}
|
|
49188
|
+
latestProfile = res.data;
|
|
49189
|
+
}
|
|
49190
|
+
if (!latestProfile) {
|
|
49191
|
+
throw cliError("PROFILE_UPDATE_FAILED", "No profile returned from server");
|
|
49192
|
+
}
|
|
49193
|
+
if (opts.json) {
|
|
49194
|
+
writeJson(ctx.io, { ok: true, data: latestProfile });
|
|
49195
|
+
return;
|
|
49196
|
+
}
|
|
49197
|
+
writeText(ctx.io, `${formatProfile(latestProfile)}
|
|
49198
|
+
`);
|
|
49199
|
+
}
|
|
49200
|
+
);
|
|
49201
|
+
function registerProfileUpdateCommand(parent, runtimeOptions = {}) {
|
|
49202
|
+
registerCliCommand(parent, profileUpdateCommand, runtimeOptions);
|
|
49203
|
+
}
|
|
49204
|
+
|
|
49205
|
+
// src/commands/server/update.ts
|
|
49206
|
+
function formatServerUpdateResult(server) {
|
|
49207
|
+
return `Updated server ${server.name ?? server.id ?? "profile"}.`;
|
|
49208
|
+
}
|
|
49209
|
+
var serverUpdateCommand = defineCommand(
|
|
49210
|
+
{
|
|
49211
|
+
name: "update",
|
|
49212
|
+
description: "Update the current server profile when this agent has server admin authority",
|
|
49213
|
+
options: [
|
|
49214
|
+
{
|
|
49215
|
+
flags: "--name <name>",
|
|
49216
|
+
description: "Set the server name"
|
|
49217
|
+
},
|
|
49218
|
+
{
|
|
49219
|
+
flags: "--avatar-file <path>",
|
|
49220
|
+
description: "Path to a local image file to use as the server avatar"
|
|
49221
|
+
},
|
|
49222
|
+
{
|
|
49223
|
+
flags: "--json",
|
|
49224
|
+
description: "Emit machine-readable JSON"
|
|
49225
|
+
}
|
|
49226
|
+
]
|
|
49227
|
+
},
|
|
49228
|
+
async (ctx, opts) => {
|
|
49229
|
+
const hasName = opts.name !== void 0;
|
|
49230
|
+
const hasAvatar = opts.avatarFile !== void 0;
|
|
49231
|
+
if (!hasName && !hasAvatar) {
|
|
49232
|
+
throw new CliError({
|
|
49233
|
+
code: "INVALID_ARG",
|
|
49234
|
+
message: "Provide at least one of --name or --avatar-file."
|
|
49235
|
+
});
|
|
49236
|
+
}
|
|
49237
|
+
let trimmedName;
|
|
49238
|
+
if (hasName) {
|
|
49239
|
+
trimmedName = opts.name.trim();
|
|
49240
|
+
if (!trimmedName) {
|
|
49241
|
+
throw new CliError({
|
|
49242
|
+
code: "INVALID_ARG",
|
|
49243
|
+
message: "--name must not be empty"
|
|
49244
|
+
});
|
|
49245
|
+
}
|
|
49246
|
+
if (trimmedName.length > 100) {
|
|
49247
|
+
throw new CliError({
|
|
49248
|
+
code: "INVALID_ARG",
|
|
49249
|
+
message: "--name must be 100 characters or fewer"
|
|
49250
|
+
});
|
|
49251
|
+
}
|
|
49252
|
+
}
|
|
49253
|
+
const avatar = hasAvatar ? readAvatarFile(opts.avatarFile) : null;
|
|
49254
|
+
const agentContext = ctx.loadAgentContext();
|
|
49255
|
+
const client = ctx.createApiClient(agentContext);
|
|
49256
|
+
let latestServer = null;
|
|
49257
|
+
if (hasName) {
|
|
49258
|
+
const res = await client.request(
|
|
49259
|
+
"PATCH",
|
|
49260
|
+
`/internal/agent/${encodeURIComponent(agentContext.agentId)}/server`,
|
|
49261
|
+
{ name: trimmedName }
|
|
49262
|
+
);
|
|
49263
|
+
if (!res.ok || !res.data) {
|
|
49264
|
+
throw new CliError({
|
|
49265
|
+
code: res.status >= 500 ? "SERVER_5XX" : "UPDATE_FAILED",
|
|
49266
|
+
message: res.error ?? `HTTP ${res.status}`
|
|
49267
|
+
});
|
|
49268
|
+
}
|
|
49269
|
+
latestServer = res.data;
|
|
49270
|
+
}
|
|
49271
|
+
if (hasAvatar) {
|
|
49272
|
+
const form = new FormData();
|
|
49273
|
+
const avatarBytes = Uint8Array.from(avatar.buffer);
|
|
49274
|
+
form.append("avatar", new Blob([avatarBytes], { type: avatar.mimeType }), avatar.filename);
|
|
49275
|
+
const res = await client.requestMultipart(
|
|
49276
|
+
"POST",
|
|
49277
|
+
`/internal/agent/${encodeURIComponent(agentContext.agentId)}/server/avatar`,
|
|
49278
|
+
form
|
|
49279
|
+
);
|
|
49280
|
+
if (!res.ok || !res.data) {
|
|
49281
|
+
throw new CliError({
|
|
49282
|
+
code: res.status >= 500 ? "SERVER_5XX" : "UPDATE_FAILED",
|
|
49283
|
+
message: res.error ?? `HTTP ${res.status}`
|
|
49284
|
+
});
|
|
49285
|
+
}
|
|
49286
|
+
latestServer = res.data;
|
|
49287
|
+
}
|
|
49288
|
+
if (!latestServer) {
|
|
49289
|
+
throw new CliError({
|
|
49290
|
+
code: "UPDATE_FAILED",
|
|
49291
|
+
message: "No server profile returned from server"
|
|
49292
|
+
});
|
|
49293
|
+
}
|
|
49294
|
+
if (opts.json) {
|
|
49295
|
+
writeJson(ctx.io, { ok: true, data: latestServer });
|
|
49296
|
+
return;
|
|
49297
|
+
}
|
|
49298
|
+
writeText(ctx.io, formatServerUpdateResult(latestServer) + "\n");
|
|
49299
|
+
}
|
|
49300
|
+
);
|
|
49301
|
+
function registerServerUpdateCommand(parent, runtimeOptions) {
|
|
49302
|
+
registerCliCommand(parent, serverUpdateCommand, runtimeOptions);
|
|
49303
|
+
}
|
|
49304
|
+
|
|
49305
|
+
// src/commands/knowledge/get.ts
|
|
49306
|
+
init_esm_shims();
|
|
47960
49307
|
function formatKnowledgeStdout(content) {
|
|
47961
49308
|
return content.endsWith("\n") ? content : `${content}
|
|
47962
49309
|
`;
|
|
@@ -48003,10 +49350,12 @@ var knowledgeGetCommand = defineCommand(
|
|
|
48003
49350
|
async (ctx, topic, opts) => {
|
|
48004
49351
|
const agentContext = ctx.loadAgentContext();
|
|
48005
49352
|
const client = ctx.createApiClient(agentContext);
|
|
48006
|
-
const res = await client.
|
|
48007
|
-
|
|
48008
|
-
|
|
48009
|
-
|
|
49353
|
+
const res = await createAgentApiSurfaceClient(client).knowledge.get({
|
|
49354
|
+
topic,
|
|
49355
|
+
reason: opts.reason,
|
|
49356
|
+
turn_id: opts.turnId,
|
|
49357
|
+
trace_id: opts.traceId
|
|
49358
|
+
});
|
|
48010
49359
|
if (!res.ok) {
|
|
48011
49360
|
throw new CliError({
|
|
48012
49361
|
code: toKnowledgeErrorCode(res.errorCode, res.status),
|
|
@@ -48050,7 +49399,7 @@ var inboxCheckCommand = defineCommand(
|
|
|
48050
49399
|
});
|
|
48051
49400
|
}
|
|
48052
49401
|
const client = ctx.createApiClient(agentContext);
|
|
48053
|
-
const response = await client.
|
|
49402
|
+
const response = await createDaemonApiSurfaceClient(client).inbox.check();
|
|
48054
49403
|
if (!response.ok) {
|
|
48055
49404
|
throw new CliError({
|
|
48056
49405
|
code: response.status >= 500 ? "SERVER_5XX" : "INBOX_CHECK_FAILED",
|
|
@@ -48412,6 +49761,7 @@ function renderSearchPreview(content, query) {
|
|
|
48412
49761
|
}
|
|
48413
49762
|
function formatSearchResults(query, data) {
|
|
48414
49763
|
if (!data.results || data.results.length === 0) return "No search results.";
|
|
49764
|
+
const trimmedQuery = query.trim();
|
|
48415
49765
|
const formatted = data.results.map((result2, index) => {
|
|
48416
49766
|
const ref = `msg:${result2.id}`;
|
|
48417
49767
|
const content = result2.content ?? result2.snippet ?? "";
|
|
@@ -48424,14 +49774,14 @@ function formatSearchResults(query, data) {
|
|
|
48424
49774
|
`Time: ${result2.createdAt ? toLocalTime(result2.createdAt) : "-"}`,
|
|
48425
49775
|
"",
|
|
48426
49776
|
"<preview>",
|
|
48427
|
-
renderSearchPreview(content,
|
|
49777
|
+
renderSearchPreview(content, trimmedQuery),
|
|
48428
49778
|
"</preview>",
|
|
48429
49779
|
"</result>"
|
|
48430
49780
|
].join("\n");
|
|
48431
49781
|
}).join("\n\n");
|
|
48432
49782
|
const resultLabel = data.results.length === 1 ? "result" : "results";
|
|
48433
49783
|
return [
|
|
48434
|
-
`Search results for: "${
|
|
49784
|
+
trimmedQuery ? `Search results for: "${trimmedQuery}" (${data.results.length} ${resultLabel})` : `Filtered message results (${data.results.length} ${resultLabel})`,
|
|
48435
49785
|
"",
|
|
48436
49786
|
formatted,
|
|
48437
49787
|
"",
|
|
@@ -48824,7 +50174,7 @@ var messageSendCommand = defineCommand(
|
|
|
48824
50174
|
if (outgoingAttachmentIds.length > 0) {
|
|
48825
50175
|
body.attachmentIds = outgoingAttachmentIds;
|
|
48826
50176
|
}
|
|
48827
|
-
const agentApi =
|
|
50177
|
+
const agentApi = createAgentApiSurfaceClient(client);
|
|
48828
50178
|
const res = await agentApi.messages.send(body);
|
|
48829
50179
|
if (!res.ok) {
|
|
48830
50180
|
const code = res.status >= 500 ? "SERVER_5XX" : "SEND_FAILED";
|
|
@@ -48886,47 +50236,18 @@ function sortedMessages(messages) {
|
|
|
48886
50236
|
function result(messages, opts = {}) {
|
|
48887
50237
|
return {
|
|
48888
50238
|
messages: sortedMessages(messages),
|
|
48889
|
-
...opts.ackFailure ? { ackFailure: opts.ackFailure } : {},
|
|
48890
50239
|
...opts.drainedMore ? { drainedMore: true } : {},
|
|
48891
50240
|
...opts.hasMore ? { hasMore: true } : {},
|
|
48892
50241
|
...opts.drainComplete ? { drainComplete: true } : {}
|
|
48893
50242
|
};
|
|
48894
50243
|
}
|
|
48895
|
-
function hasMoreField(data) {
|
|
48896
|
-
if (!data) return false;
|
|
48897
|
-
return Object.prototype.hasOwnProperty.call(data, "has_more") || Object.prototype.hasOwnProperty.call(data, "hasMore");
|
|
48898
|
-
}
|
|
48899
50244
|
async function drainInbox(ctx, opts, client = new ApiClient(ctx)) {
|
|
48900
|
-
const agentPath = `/internal/agent/${encodeURIComponent(ctx.agentId)}`;
|
|
48901
50245
|
const failCode = opts.block ? "WAIT_FAILED" : "CHECK_FAILED";
|
|
48902
|
-
const
|
|
48903
|
-
if (opts.block) query.push("block=true");
|
|
48904
|
-
if (opts.block && opts.timeoutMs !== void 0) query.push(`timeout=${opts.timeoutMs}`);
|
|
48905
|
-
const usesAgentApiSurface = ctx.clientMode === "managed-runner" || ctx.clientMode === "self-hosted-runner";
|
|
48906
|
-
const path9 = query.length > 0 ? `${agentPath}/receive?${query.join("&")}` : `${agentPath}/receive`;
|
|
50246
|
+
const agentApi = createAgentApiSurfaceClient(client);
|
|
48907
50247
|
const allMessages = [];
|
|
48908
50248
|
let sawHasMore = false;
|
|
48909
50249
|
for (let round = 0; round < MAX_DRAIN_ROUNDS; round += 1) {
|
|
48910
|
-
|
|
48911
|
-
const res2 = await createAgentApiSurfaceClient(client).events.get({ since: "latest" });
|
|
48912
|
-
if (!res2.ok) {
|
|
48913
|
-
if (allMessages.length > 0) {
|
|
48914
|
-
return result(allMessages, { drainedMore: sawHasMore, hasMore: true });
|
|
48915
|
-
}
|
|
48916
|
-
throw new CliError({
|
|
48917
|
-
code: res2.status >= 500 ? "SERVER_5XX" : failCode,
|
|
48918
|
-
message: res2.error ?? `HTTP ${res2.status}`
|
|
48919
|
-
});
|
|
48920
|
-
}
|
|
48921
|
-
const messages2 = res2.data?.events ?? [];
|
|
48922
|
-
allMessages.push(...messages2);
|
|
48923
|
-
const hasMore2 = res2.data?.has_more === true;
|
|
48924
|
-
const drainComplete2 = !hasMore2 && allMessages.length > 0;
|
|
48925
|
-
sawHasMore = sawHasMore || hasMore2;
|
|
48926
|
-
if (hasMore2 && messages2.length > 0) continue;
|
|
48927
|
-
return result(allMessages, { drainedMore: sawHasMore, hasMore: hasMore2, drainComplete: drainComplete2 });
|
|
48928
|
-
}
|
|
48929
|
-
const res = await client.request("GET", path9);
|
|
50250
|
+
const res = await agentApi.events.get({ since: "latest" });
|
|
48930
50251
|
if (!res.ok) {
|
|
48931
50252
|
if (allMessages.length > 0) {
|
|
48932
50253
|
return result(allMessages, { drainedMore: sawHasMore, hasMore: true });
|
|
@@ -48936,25 +50257,13 @@ async function drainInbox(ctx, opts, client = new ApiClient(ctx)) {
|
|
|
48936
50257
|
message: res.error ?? `HTTP ${res.status}`
|
|
48937
50258
|
});
|
|
48938
50259
|
}
|
|
48939
|
-
const messages = res.data?.
|
|
50260
|
+
const messages = res.data?.events ?? [];
|
|
48940
50261
|
allMessages.push(...messages);
|
|
48941
|
-
const hasMore = res.data?.has_more === true
|
|
48942
|
-
const
|
|
48943
|
-
const drainComplete = hasExplicitHasMore && !hasMore && allMessages.length > 0;
|
|
50262
|
+
const hasMore = res.data?.has_more === true;
|
|
50263
|
+
const drainComplete = !hasMore && allMessages.length > 0;
|
|
48944
50264
|
sawHasMore = sawHasMore || hasMore;
|
|
48945
|
-
|
|
48946
|
-
|
|
48947
|
-
const ack = await client.request("POST", `${agentPath}/receive-ack`, { seqs });
|
|
48948
|
-
if (!ack.ok) {
|
|
48949
|
-
const ackCode = ack.status >= 500 ? "SERVER_5XX" : "ACK_FAILED";
|
|
48950
|
-
const ackMessage = ack.error ?? `HTTP ${ack.status}`;
|
|
48951
|
-
return result(allMessages, {
|
|
48952
|
-
ackFailure: { code: ackCode, message: ackMessage },
|
|
48953
|
-
drainedMore: sawHasMore,
|
|
48954
|
-
hasMore
|
|
48955
|
-
});
|
|
48956
|
-
}
|
|
48957
|
-
if (!hasMore) return result(allMessages, { drainedMore: sawHasMore, drainComplete });
|
|
50265
|
+
if (hasMore && messages.length > 0) continue;
|
|
50266
|
+
return result(allMessages, { drainedMore: sawHasMore, hasMore, drainComplete });
|
|
48958
50267
|
}
|
|
48959
50268
|
return result(allMessages, { drainedMore: sawHasMore, hasMore: true });
|
|
48960
50269
|
}
|
|
@@ -49062,7 +50371,7 @@ var messageReadCommand = defineCommand(
|
|
|
49062
50371
|
const readOpts = validateReadOpts(opts);
|
|
49063
50372
|
const agentContext = ctx.loadAgentContext();
|
|
49064
50373
|
const client = ctx.createApiClient(agentContext);
|
|
49065
|
-
const agentApi =
|
|
50374
|
+
const agentApi = createAgentApiSurfaceClient(client);
|
|
49066
50375
|
const res = await agentApi.history.read({
|
|
49067
50376
|
channel: readOpts.channel,
|
|
49068
50377
|
...readOpts.before !== void 0 ? { before: readOpts.before } : {},
|
|
@@ -49137,29 +50446,53 @@ function parsePositiveInt3(name, raw) {
|
|
|
49137
50446
|
}
|
|
49138
50447
|
return n;
|
|
49139
50448
|
}
|
|
49140
|
-
function
|
|
49141
|
-
|
|
49142
|
-
|
|
50449
|
+
function parseNonNegativeInt(name, raw) {
|
|
50450
|
+
if (raw === void 0) return void 0;
|
|
50451
|
+
const n = Number(raw);
|
|
50452
|
+
if (!Number.isFinite(n) || !Number.isInteger(n) || n < 0) {
|
|
49143
50453
|
throw new CliError({
|
|
49144
50454
|
code: "INVALID_ARG",
|
|
49145
|
-
message:
|
|
50455
|
+
message: `--${name} must be a non-negative integer; got ${raw}`
|
|
49146
50456
|
});
|
|
49147
50457
|
}
|
|
50458
|
+
return n;
|
|
50459
|
+
}
|
|
50460
|
+
function normalizeSearchOpts(opts) {
|
|
50461
|
+
const query = opts.query?.trim();
|
|
49148
50462
|
if (opts.sort !== void 0 && opts.sort !== "relevance" && opts.sort !== "recent") {
|
|
49149
50463
|
throw new CliError({
|
|
49150
50464
|
code: "INVALID_ARG",
|
|
49151
50465
|
message: `--sort must be "relevance" or "recent"; got ${opts.sort}`
|
|
49152
50466
|
});
|
|
49153
50467
|
}
|
|
50468
|
+
const channel = opts.channel?.trim();
|
|
50469
|
+
const sender = opts.sender ? normalizeMemberHandleRef(opts.sender) : void 0;
|
|
50470
|
+
const hasFilter = Boolean(channel || sender || opts.before || opts.after);
|
|
50471
|
+
if (!query && !hasFilter) {
|
|
50472
|
+
throw new CliError({
|
|
50473
|
+
code: "INVALID_ARG",
|
|
50474
|
+
message: "--query is required unless --sender, --channel, --before, or --after is provided"
|
|
50475
|
+
});
|
|
50476
|
+
}
|
|
50477
|
+
if (!query && opts.sort === "relevance") {
|
|
50478
|
+
throw new CliError({
|
|
50479
|
+
code: "INVALID_ARG",
|
|
50480
|
+
message: "--sort relevance requires --query; filter-only search is sorted by recent"
|
|
50481
|
+
});
|
|
50482
|
+
}
|
|
49154
50483
|
const limit = parsePositiveInt3("limit", opts.limit);
|
|
50484
|
+
const offset = parseNonNegativeInt("offset", opts.offset);
|
|
50485
|
+
const sort = opts.sort ?? (query ? void 0 : "recent");
|
|
49155
50486
|
return {
|
|
49156
|
-
query,
|
|
49157
|
-
|
|
49158
|
-
...
|
|
49159
|
-
...
|
|
50487
|
+
...query ? { query } : {},
|
|
50488
|
+
displayQuery: query ?? "",
|
|
50489
|
+
...channel ? { channel } : {},
|
|
50490
|
+
...sender ? { sender } : {},
|
|
50491
|
+
...sort ? { sort } : {},
|
|
49160
50492
|
...opts.before ? { before: opts.before } : {},
|
|
49161
50493
|
...opts.after ? { after: opts.after } : {},
|
|
49162
|
-
...limit !== void 0 ? { limit } : {}
|
|
50494
|
+
...limit !== void 0 ? { limit } : {},
|
|
50495
|
+
...offset !== void 0 ? { offset } : {}
|
|
49163
50496
|
};
|
|
49164
50497
|
}
|
|
49165
50498
|
function toSearchErrorCode(errorCode2, status) {
|
|
@@ -49176,13 +50509,14 @@ var messageSearchCommand = defineCommand(
|
|
|
49176
50509
|
name: "search",
|
|
49177
50510
|
description: "Search messages across channels the agent can see",
|
|
49178
50511
|
options: [
|
|
49179
|
-
{ flags: "--query <q>", description: "Search query string" },
|
|
50512
|
+
{ flags: "--query <q>", description: "Search query string (optional when filters are provided)" },
|
|
49180
50513
|
{ flags: "--channel <target>", description: "Restrict to a single channel/DM/thread" },
|
|
49181
50514
|
{ flags: "--sender <handle>", description: "Restrict to messages by sender handle, e.g. @alice" },
|
|
49182
|
-
{ flags: "--sort <mode>", description: "Sort results by relevance or recent (default: relevance)" },
|
|
50515
|
+
{ flags: "--sort <mode>", description: "Sort results by relevance or recent (default: relevance; filter-only searches use recent)" },
|
|
49183
50516
|
{ flags: "--before <iso>", description: "Only messages before this ISO datetime" },
|
|
49184
50517
|
{ flags: "--after <iso>", description: "Only messages after this ISO datetime" },
|
|
49185
|
-
{ flags: "--limit <n>", description: "Max results (server default applies if omitted)" }
|
|
50518
|
+
{ flags: "--limit <n>", description: "Max results (server default applies if omitted)" },
|
|
50519
|
+
{ flags: "--offset <n>", description: "Skip this many results (server default applies if omitted)" }
|
|
49186
50520
|
]
|
|
49187
50521
|
},
|
|
49188
50522
|
async (ctx, opts) => {
|
|
@@ -49191,13 +50525,14 @@ var messageSearchCommand = defineCommand(
|
|
|
49191
50525
|
const client = ctx.createApiClient(agentContext);
|
|
49192
50526
|
const agentApi = createAgentApiSurfaceClient(client);
|
|
49193
50527
|
const res = await agentApi.messages.search({
|
|
49194
|
-
q: searchOpts.query,
|
|
50528
|
+
...searchOpts.query ? { q: searchOpts.query } : {},
|
|
49195
50529
|
...searchOpts.channel ? { channel: searchOpts.channel } : {},
|
|
49196
50530
|
...searchOpts.sender ? { sender: searchOpts.sender } : {},
|
|
49197
50531
|
...searchOpts.sort ? { sort: searchOpts.sort } : {},
|
|
49198
50532
|
...searchOpts.before ? { before: searchOpts.before } : {},
|
|
49199
50533
|
...searchOpts.after ? { after: searchOpts.after } : {},
|
|
49200
|
-
...searchOpts.limit !== void 0 ? { limit: String(searchOpts.limit) } : {}
|
|
50534
|
+
...searchOpts.limit !== void 0 ? { limit: String(searchOpts.limit) } : {},
|
|
50535
|
+
...searchOpts.offset !== void 0 ? { offset: String(searchOpts.offset) } : {}
|
|
49201
50536
|
});
|
|
49202
50537
|
if (!res.ok) {
|
|
49203
50538
|
throw new CliError({
|
|
@@ -49205,7 +50540,7 @@ var messageSearchCommand = defineCommand(
|
|
|
49205
50540
|
message: res.error ?? `HTTP ${res.status}`
|
|
49206
50541
|
});
|
|
49207
50542
|
}
|
|
49208
|
-
writeText(ctx.io, `${formatSearchResults(searchOpts.
|
|
50543
|
+
writeText(ctx.io, `${formatSearchResults(searchOpts.displayQuery, res.data)}
|
|
49209
50544
|
`);
|
|
49210
50545
|
}
|
|
49211
50546
|
);
|
|
@@ -49255,7 +50590,7 @@ var messageResolveCommand = defineCommand(
|
|
|
49255
50590
|
}
|
|
49256
50591
|
const agentContext = ctx.loadAgentContext();
|
|
49257
50592
|
const client = ctx.createApiClient(agentContext);
|
|
49258
|
-
const res = await
|
|
50593
|
+
const res = await createAgentApiSurfaceClient(client).messages.resolve({ msgId: asMessageId(id) });
|
|
49259
50594
|
if (!res.ok) {
|
|
49260
50595
|
const mapped = mapResolveError(res);
|
|
49261
50596
|
throw new CliError(mapped);
|
|
@@ -49314,7 +50649,7 @@ var messageReactCommand = defineCommand(
|
|
|
49314
50649
|
}
|
|
49315
50650
|
const agentContext = ctx.loadAgentContext();
|
|
49316
50651
|
const client = ctx.createApiClient(agentContext);
|
|
49317
|
-
const agentApi =
|
|
50652
|
+
const agentApi = createAgentApiSurfaceClient(client);
|
|
49318
50653
|
const messageId = asMessageId(opts.messageId.trim());
|
|
49319
50654
|
const res = opts.remove ? await agentApi.messages.removeReaction({ msgId: messageId }, { emoji: emoji3 }) : await agentApi.messages.addReaction({ msgId: messageId }, { emoji: emoji3 });
|
|
49320
50655
|
if (!res.ok) {
|
|
@@ -49332,11 +50667,11 @@ function registerReactCommand(parent, runtimeOptions = {}) {
|
|
|
49332
50667
|
|
|
49333
50668
|
// src/commands/attachment/upload.ts
|
|
49334
50669
|
init_esm_shims();
|
|
49335
|
-
import { existsSync, statSync, readFileSync as
|
|
49336
|
-
import { basename } from "path";
|
|
50670
|
+
import { existsSync as existsSync2, statSync as statSync2, readFileSync as readFileSync3 } from "fs";
|
|
50671
|
+
import { basename as basename2 } from "path";
|
|
49337
50672
|
var MAX_ATTACHMENT_UPLOAD_BYTES = 50 * 1024 * 1024;
|
|
49338
50673
|
var MAX_ATTACHMENT_UPLOAD_LABEL = "50MB";
|
|
49339
|
-
var
|
|
50674
|
+
var FILENAME_MIME_MAP2 = {
|
|
49340
50675
|
".jpg": "image/jpeg",
|
|
49341
50676
|
".jpeg": "image/jpeg",
|
|
49342
50677
|
".png": "image/png",
|
|
@@ -49359,7 +50694,7 @@ var AttachmentUploadArgError = class extends Error {
|
|
|
49359
50694
|
function inferMimeTypeFromFilename(filename) {
|
|
49360
50695
|
const index = filename.lastIndexOf(".");
|
|
49361
50696
|
const ext = index >= 0 ? filename.slice(index).toLowerCase() : "";
|
|
49362
|
-
return
|
|
50697
|
+
return FILENAME_MIME_MAP2[ext] || null;
|
|
49363
50698
|
}
|
|
49364
50699
|
function inferMimeTypeFromBuffer(buffer) {
|
|
49365
50700
|
if (buffer.length >= 8 && buffer.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]))) {
|
|
@@ -49434,10 +50769,10 @@ var attachmentUploadCommand = defineCommand(
|
|
|
49434
50769
|
if (typeof opts.path !== "string" || opts.path.length === 0) {
|
|
49435
50770
|
throw cliError("INVALID_ARG", "--path is required");
|
|
49436
50771
|
}
|
|
49437
|
-
if (!
|
|
50772
|
+
if (!existsSync2(opts.path)) {
|
|
49438
50773
|
throw cliError("INVALID_ARG", `--path does not exist: ${opts.path}`);
|
|
49439
50774
|
}
|
|
49440
|
-
const stat2 =
|
|
50775
|
+
const stat2 = statSync2(opts.path);
|
|
49441
50776
|
if (!stat2.isFile()) {
|
|
49442
50777
|
throw cliError("INVALID_ARG", `--path is not a regular file: ${opts.path}`);
|
|
49443
50778
|
}
|
|
@@ -49453,8 +50788,8 @@ var attachmentUploadCommand = defineCommand(
|
|
|
49453
50788
|
"v0 server requires a channel to attach the upload to. Pass --channel '#name', 'dm:@peer', or a thread target."
|
|
49454
50789
|
);
|
|
49455
50790
|
}
|
|
49456
|
-
const buffer =
|
|
49457
|
-
const filename =
|
|
50791
|
+
const buffer = readFileSync3(opts.path);
|
|
50792
|
+
const filename = basename2(opts.path);
|
|
49458
50793
|
let explicitMimeType;
|
|
49459
50794
|
try {
|
|
49460
50795
|
explicitMimeType = normalizeExplicitMimeType(opts.mimeType);
|
|
@@ -49531,17 +50866,20 @@ var attachmentViewCommand = defineCommand(
|
|
|
49531
50866
|
const { id, output } = validateViewOpts(opts);
|
|
49532
50867
|
const agentContext = ctx.loadAgentContext();
|
|
49533
50868
|
const client = ctx.createApiClient(agentContext);
|
|
49534
|
-
const res = await client.
|
|
49535
|
-
"GET",
|
|
49536
|
-
`/api/attachments/${encodeURIComponent(id)}`
|
|
49537
|
-
);
|
|
50869
|
+
const res = await createAgentApiSurfaceClient(client).attachments.view({ attachmentId: id });
|
|
49538
50870
|
if (!res.ok) {
|
|
49539
50871
|
throw new CliError({
|
|
49540
50872
|
code: res.status >= 500 ? "SERVER_5XX" : "VIEW_FAILED",
|
|
49541
50873
|
message: res.error ?? `HTTP ${res.status}`
|
|
49542
50874
|
});
|
|
49543
50875
|
}
|
|
49544
|
-
|
|
50876
|
+
if (res.data === null) {
|
|
50877
|
+
throw new CliError({
|
|
50878
|
+
code: "VIEW_FAILED",
|
|
50879
|
+
message: "Attachment download returned no bytes"
|
|
50880
|
+
});
|
|
50881
|
+
}
|
|
50882
|
+
const buffer = Buffer.from(res.data);
|
|
49545
50883
|
writeFileSync(output, buffer);
|
|
49546
50884
|
writeText(ctx.io, `Downloaded to: ${output}
|
|
49547
50885
|
`);
|
|
@@ -49591,11 +50929,9 @@ var attachmentCommentsCommand = defineCommand(
|
|
|
49591
50929
|
}
|
|
49592
50930
|
const agentContext = ctx.loadAgentContext();
|
|
49593
50931
|
const client = ctx.createApiClient(agentContext);
|
|
49594
|
-
const
|
|
49595
|
-
const
|
|
49596
|
-
|
|
49597
|
-
`/api/attachments/${encodeURIComponent(id)}/comments${limitParam}`
|
|
49598
|
-
);
|
|
50932
|
+
const agentApi = createAgentApiSurfaceClient(client);
|
|
50933
|
+
const limit = opts.limit && Number.isFinite(Number(opts.limit)) ? String(Number(opts.limit)) : void 0;
|
|
50934
|
+
const res = await agentApi.attachments.comments({ attachmentId: id }, limit ? { limit } : {});
|
|
49599
50935
|
if (!res.ok || !res.data) {
|
|
49600
50936
|
const code = res.status >= 500 ? "SERVER_5XX" : "COMMENTS_FAILED";
|
|
49601
50937
|
throw new CliError({ code, message: res.error ?? `HTTP ${res.status}` });
|
|
@@ -49658,7 +50994,7 @@ function formatClaimResults(channel, data) {
|
|
|
49658
50994
|
const msgShort = r.messageId ? r.messageId.slice(0, 8) : "";
|
|
49659
50995
|
return `${label} (msg:${msgShort}): claimed`;
|
|
49660
50996
|
}
|
|
49661
|
-
return `${label}: FAILED \u2014 ${r.reason || "already claimed"}. Do not
|
|
50997
|
+
return `${label}: FAILED \u2014 ${r.reason || "already claimed"}. Do not work on this task unless an owner/admin explicitly redirects it to you.`;
|
|
49662
50998
|
});
|
|
49663
50999
|
const succeeded = data.results.filter((r) => r.success).length;
|
|
49664
51000
|
const failed = data.results.length - succeeded;
|
|
@@ -50011,7 +51347,7 @@ function buildMentionExecuteCommand(action) {
|
|
|
50011
51347
|
const ids = normalizeResolutionIds(resolutionIds);
|
|
50012
51348
|
const agentContext = ctx.loadAgentContext();
|
|
50013
51349
|
const client = ctx.createApiClient(agentContext);
|
|
50014
|
-
const res = await
|
|
51350
|
+
const res = await createAgentApiSurfaceClient(client).mentions.executeAction({
|
|
50015
51351
|
action,
|
|
50016
51352
|
resolutionIds: ids
|
|
50017
51353
|
});
|
|
@@ -50043,7 +51379,7 @@ var mentionPendingCommand = defineCommand(
|
|
|
50043
51379
|
async (ctx, opts = {}) => {
|
|
50044
51380
|
const agentContext = ctx.loadAgentContext();
|
|
50045
51381
|
const client = ctx.createApiClient(agentContext);
|
|
50046
|
-
const res = await
|
|
51382
|
+
const res = await createAgentApiSurfaceClient(client).mentions.pendingActions();
|
|
50047
51383
|
if (!res.ok || !res.data) {
|
|
50048
51384
|
throw cliError(res.status >= 500 ? "SERVER_5XX" : "MENTION_PENDING_FAILED", res.error ?? `HTTP ${res.status}`);
|
|
50049
51385
|
}
|
|
@@ -50067,69 +51403,6 @@ function registerMentionCommands(parent, runtimeOptions = {}) {
|
|
|
50067
51403
|
|
|
50068
51404
|
// src/commands/profile/show.ts
|
|
50069
51405
|
init_esm_shims();
|
|
50070
|
-
|
|
50071
|
-
// src/commands/profile/_format.ts
|
|
50072
|
-
init_esm_shims();
|
|
50073
|
-
function formatCreatedAgents(createdAgents) {
|
|
50074
|
-
if (createdAgents.length === 0) {
|
|
50075
|
-
return ["- Created Agents: none"];
|
|
50076
|
-
}
|
|
50077
|
-
return [
|
|
50078
|
-
`- Created Agents (${createdAgents.length}):`,
|
|
50079
|
-
...createdAgents.map((createdAgent) => ` - @${createdAgent.name} (${getRuntimeDisplayName(createdAgent.runtime)}, ${createdAgent.status})`)
|
|
50080
|
-
];
|
|
50081
|
-
}
|
|
50082
|
-
function formatHumanProfile(profile) {
|
|
50083
|
-
const lines = [
|
|
50084
|
-
"## Profile",
|
|
50085
|
-
"",
|
|
50086
|
-
"- Type: human",
|
|
50087
|
-
`- Handle: @${profile.name}`,
|
|
50088
|
-
`- Display Name: ${profile.displayName ?? "(none)"}`,
|
|
50089
|
-
`- Description: ${profile.description ?? "(none)"}`,
|
|
50090
|
-
`- Membership: ${profile.membershipStatus}`
|
|
50091
|
-
];
|
|
50092
|
-
if (profile.role) lines.push(`- Role: ${profile.role}`);
|
|
50093
|
-
if (profile.joinedAt) lines.push(`- Joined: ${profile.joinedAt}`);
|
|
50094
|
-
if (profile.email) lines.push(`- Email: ${profile.email}`);
|
|
50095
|
-
return [...lines, ...formatCreatedAgents(profile.createdAgents)].join("\n");
|
|
50096
|
-
}
|
|
50097
|
-
function formatCreator(profile) {
|
|
50098
|
-
if (!profile.creator) return null;
|
|
50099
|
-
return profile.creator.displayName ? `${profile.creator.displayName} (@${profile.creator.name})` : `@${profile.creator.name}`;
|
|
50100
|
-
}
|
|
50101
|
-
function formatAgentProfile(profile) {
|
|
50102
|
-
const lines = [
|
|
50103
|
-
"## Profile",
|
|
50104
|
-
"",
|
|
50105
|
-
"- Type: agent",
|
|
50106
|
-
`- Handle: @${profile.name}`,
|
|
50107
|
-
`- Display Name: ${profile.displayName ?? "(none)"}`,
|
|
50108
|
-
`- Description: ${profile.description ?? "(none)"}`,
|
|
50109
|
-
`- Status: ${profile.status}`,
|
|
50110
|
-
`- Role: ${profile.serverRole}`,
|
|
50111
|
-
`- Runtime: ${getRuntimeDisplayName(profile.runtime)}`,
|
|
50112
|
-
`- Model: ${profile.model}`,
|
|
50113
|
-
`- Reasoning: ${profile.reasoningEffort ?? "medium"}`
|
|
50114
|
-
];
|
|
50115
|
-
if (profile.executionMode) lines.push(`- Execution: ${profile.executionMode}`);
|
|
50116
|
-
if (profile.computerName || profile.computerId) {
|
|
50117
|
-
const label = profile.computerName && profile.computerId ? `${profile.computerName} (${profile.computerId})` : profile.computerName ?? profile.computerId;
|
|
50118
|
-
lines.push(`- Computer: ${label}`);
|
|
50119
|
-
}
|
|
50120
|
-
if (profile.computerHostname) lines.push(`- Hostname: ${profile.computerHostname}`);
|
|
50121
|
-
if (profile.daemonVersion) lines.push(`- Daemon: v${profile.daemonVersion}`);
|
|
50122
|
-
lines.push(`- Created: ${profile.createdAt}`);
|
|
50123
|
-
if (profile.deletedAt) lines.push(`- Deleted At: ${profile.deletedAt}`);
|
|
50124
|
-
const creator = formatCreator(profile);
|
|
50125
|
-
if (creator) lines.push(`- Creator: ${creator}`);
|
|
50126
|
-
return [...lines, ...formatCreatedAgents(profile.createdAgents)].join("\n");
|
|
50127
|
-
}
|
|
50128
|
-
function formatProfile(profile) {
|
|
50129
|
-
return profile.kind === "human" ? formatHumanProfile(profile) : formatAgentProfile(profile);
|
|
50130
|
-
}
|
|
50131
|
-
|
|
50132
|
-
// src/commands/profile/show.ts
|
|
50133
51406
|
function normalizeTarget(target) {
|
|
50134
51407
|
if (target === void 0) return null;
|
|
50135
51408
|
const trimmed = target.trim();
|
|
@@ -50179,177 +51452,6 @@ function registerProfileShowCommand(parent, runtimeOptions) {
|
|
|
50179
51452
|
registerCliCommand(parent, profileShowCommand, runtimeOptions);
|
|
50180
51453
|
}
|
|
50181
51454
|
|
|
50182
|
-
// src/commands/profile/update.ts
|
|
50183
|
-
init_esm_shims();
|
|
50184
|
-
import { basename as basename2 } from "path";
|
|
50185
|
-
import { existsSync as existsSync2, readFileSync as readFileSync3, statSync as statSync2 } from "fs";
|
|
50186
|
-
var MAX_PROFILE_AVATAR_BYTES = 2 * 1024 * 1024;
|
|
50187
|
-
var PROFILE_AVATAR_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
50188
|
-
"image/jpeg",
|
|
50189
|
-
"image/png",
|
|
50190
|
-
"image/gif",
|
|
50191
|
-
"image/webp"
|
|
50192
|
-
]);
|
|
50193
|
-
var FILENAME_MIME_MAP2 = {
|
|
50194
|
-
".jpg": "image/jpeg",
|
|
50195
|
-
".jpeg": "image/jpeg",
|
|
50196
|
-
".png": "image/png",
|
|
50197
|
-
".gif": "image/gif",
|
|
50198
|
-
".webp": "image/webp"
|
|
50199
|
-
};
|
|
50200
|
-
var MAX_PROFILE_DESCRIPTION_LENGTH = 3e3;
|
|
50201
|
-
var MAX_PROFILE_DISPLAY_NAME_LENGTH = 80;
|
|
50202
|
-
function inferImageMimeType(filename, buffer) {
|
|
50203
|
-
const lowerFilename = filename.toLowerCase();
|
|
50204
|
-
if (buffer.length >= 8 && buffer.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]))) {
|
|
50205
|
-
return "image/png";
|
|
50206
|
-
}
|
|
50207
|
-
if (buffer.length >= 3 && buffer.subarray(0, 3).equals(Buffer.from([255, 216, 255]))) {
|
|
50208
|
-
return "image/jpeg";
|
|
50209
|
-
}
|
|
50210
|
-
if (buffer.length >= 6) {
|
|
50211
|
-
const header = buffer.subarray(0, 6).toString("ascii");
|
|
50212
|
-
if (header === "GIF87a" || header === "GIF89a") return "image/gif";
|
|
50213
|
-
}
|
|
50214
|
-
if (buffer.length >= 12 && buffer.subarray(0, 4).toString("ascii") === "RIFF" && buffer.subarray(8, 12).toString("ascii") === "WEBP") {
|
|
50215
|
-
return "image/webp";
|
|
50216
|
-
}
|
|
50217
|
-
const dot = lowerFilename.lastIndexOf(".");
|
|
50218
|
-
return dot >= 0 ? FILENAME_MIME_MAP2[lowerFilename.slice(dot)] ?? null : null;
|
|
50219
|
-
}
|
|
50220
|
-
function readAvatarFile(avatarFile) {
|
|
50221
|
-
if (!existsSync2(avatarFile)) {
|
|
50222
|
-
throw cliError("PROFILE_FILE_NOT_FOUND", `Avatar file does not exist: ${avatarFile}`);
|
|
50223
|
-
}
|
|
50224
|
-
const stat2 = statSync2(avatarFile);
|
|
50225
|
-
if (!stat2.isFile()) {
|
|
50226
|
-
throw cliError("PROFILE_FILE_NOT_FOUND", `Avatar file is not a regular file: ${avatarFile}`);
|
|
50227
|
-
}
|
|
50228
|
-
if (stat2.size > MAX_PROFILE_AVATAR_BYTES) {
|
|
50229
|
-
throw cliError(
|
|
50230
|
-
"PROFILE_AVATAR_TOO_LARGE",
|
|
50231
|
-
`Avatar file is ${stat2.size} bytes; max size is ${MAX_PROFILE_AVATAR_BYTES} bytes`
|
|
50232
|
-
);
|
|
50233
|
-
}
|
|
50234
|
-
const buffer = readFileSync3(avatarFile);
|
|
50235
|
-
const filename = basename2(avatarFile);
|
|
50236
|
-
const mimeType = inferImageMimeType(filename, buffer);
|
|
50237
|
-
if (!mimeType || !PROFILE_AVATAR_MIME_TYPES.has(mimeType)) {
|
|
50238
|
-
throw cliError(
|
|
50239
|
-
"PROFILE_AVATAR_BAD_FORMAT",
|
|
50240
|
-
"Avatar must be a JPEG, PNG, GIF, or WebP image"
|
|
50241
|
-
);
|
|
50242
|
-
}
|
|
50243
|
-
return { filename, buffer, mimeType };
|
|
50244
|
-
}
|
|
50245
|
-
function normalizeAvatarUrl(avatarUrl) {
|
|
50246
|
-
const trimmed = avatarUrl.trim();
|
|
50247
|
-
if (trimmed.length === 0) {
|
|
50248
|
-
throw cliError("INVALID_ARG", "--avatar-url must not be empty");
|
|
50249
|
-
}
|
|
50250
|
-
if (!trimmed.startsWith("pixel:")) {
|
|
50251
|
-
throw cliError("INVALID_ARG", "--avatar-url currently supports only pixel avatar URLs; use --avatar-file for image uploads");
|
|
50252
|
-
}
|
|
50253
|
-
return trimmed;
|
|
50254
|
-
}
|
|
50255
|
-
var profileUpdateCommand = defineCommand(
|
|
50256
|
-
{
|
|
50257
|
-
name: "update",
|
|
50258
|
-
description: "Update your own profile",
|
|
50259
|
-
options: [
|
|
50260
|
-
{ flags: "--avatar-file <path>", description: "Path to a local image file to use as your avatar" },
|
|
50261
|
-
{ flags: "--avatar-url <value>", description: "Set a pixel avatar URL such as pixel:random:<seed>" },
|
|
50262
|
-
{ flags: "--display-name <name>", description: "Set your display name (non-empty)" },
|
|
50263
|
-
{ flags: "--description <text>", description: "Set your profile description (non-empty)" },
|
|
50264
|
-
{ flags: "--json", description: "Emit machine-readable JSON" }
|
|
50265
|
-
]
|
|
50266
|
-
},
|
|
50267
|
-
async (ctx, opts) => {
|
|
50268
|
-
const hasAvatar = opts.avatarFile !== void 0;
|
|
50269
|
-
const hasAvatarUrl = opts.avatarUrl !== void 0;
|
|
50270
|
-
const hasDisplayName = opts.displayName !== void 0;
|
|
50271
|
-
const hasDescription = opts.description !== void 0;
|
|
50272
|
-
if (!hasAvatar && !hasAvatarUrl && !hasDisplayName && !hasDescription) {
|
|
50273
|
-
throw cliError("INVALID_ARG", "Provide at least one of --avatar-file, --avatar-url, --display-name, or --description");
|
|
50274
|
-
}
|
|
50275
|
-
if (hasAvatar && hasAvatarUrl) {
|
|
50276
|
-
throw cliError("INVALID_ARG", "Use either --avatar-file or --avatar-url, not both");
|
|
50277
|
-
}
|
|
50278
|
-
let normalizedAvatarUrl;
|
|
50279
|
-
if (hasAvatarUrl) {
|
|
50280
|
-
normalizedAvatarUrl = normalizeAvatarUrl(opts.avatarUrl);
|
|
50281
|
-
}
|
|
50282
|
-
let trimmedDisplayName;
|
|
50283
|
-
if (hasDisplayName) {
|
|
50284
|
-
trimmedDisplayName = opts.displayName.trim();
|
|
50285
|
-
if (trimmedDisplayName.length === 0) {
|
|
50286
|
-
throw cliError("INVALID_ARG", "--display-name must not be empty");
|
|
50287
|
-
}
|
|
50288
|
-
if (trimmedDisplayName.length > MAX_PROFILE_DISPLAY_NAME_LENGTH) {
|
|
50289
|
-
throw cliError("INVALID_ARG", `--display-name must be at most ${MAX_PROFILE_DISPLAY_NAME_LENGTH} characters`);
|
|
50290
|
-
}
|
|
50291
|
-
}
|
|
50292
|
-
if (hasDescription) {
|
|
50293
|
-
if (opts.description.length === 0) {
|
|
50294
|
-
throw cliError("INVALID_ARG", "--description must not be empty");
|
|
50295
|
-
}
|
|
50296
|
-
if (opts.description.length > MAX_PROFILE_DESCRIPTION_LENGTH) {
|
|
50297
|
-
throw cliError("INVALID_ARG", `--description must be at most ${MAX_PROFILE_DESCRIPTION_LENGTH} characters`);
|
|
50298
|
-
}
|
|
50299
|
-
}
|
|
50300
|
-
const avatar = hasAvatar ? readAvatarFile(opts.avatarFile) : null;
|
|
50301
|
-
const agentContext = ctx.loadAgentContext();
|
|
50302
|
-
const client = ctx.createApiClient(agentContext);
|
|
50303
|
-
const agentApi = createAgentApiSurfaceClient(client);
|
|
50304
|
-
let latestProfile = null;
|
|
50305
|
-
if (hasAvatarUrl || hasDisplayName || hasDescription) {
|
|
50306
|
-
const body = {};
|
|
50307
|
-
if (hasAvatarUrl) {
|
|
50308
|
-
body.avatarUrl = normalizedAvatarUrl;
|
|
50309
|
-
}
|
|
50310
|
-
if (hasDisplayName) {
|
|
50311
|
-
body.displayName = trimmedDisplayName;
|
|
50312
|
-
}
|
|
50313
|
-
if (hasDescription) {
|
|
50314
|
-
body.description = opts.description;
|
|
50315
|
-
}
|
|
50316
|
-
const res = await agentApi.profile.update(body);
|
|
50317
|
-
if (!res.ok || !res.data) {
|
|
50318
|
-
const code = res.errorCode ?? (res.status >= 500 ? "SERVER_5XX" : "PROFILE_UPDATE_FAILED");
|
|
50319
|
-
throw cliError(code, res.error ?? `HTTP ${res.status}`);
|
|
50320
|
-
}
|
|
50321
|
-
latestProfile = res.data;
|
|
50322
|
-
}
|
|
50323
|
-
if (hasAvatar) {
|
|
50324
|
-
const form = new FormData();
|
|
50325
|
-
const avatarBytes = Uint8Array.from(avatar.buffer);
|
|
50326
|
-
form.append("avatar", new Blob([avatarBytes], { type: avatar.mimeType }), avatar.filename);
|
|
50327
|
-
const res = await client.requestMultipart(
|
|
50328
|
-
"POST",
|
|
50329
|
-
"/internal/agent-api/profile/avatar",
|
|
50330
|
-
form
|
|
50331
|
-
);
|
|
50332
|
-
if (!res.ok || !res.data) {
|
|
50333
|
-
const code = res.errorCode ?? (res.status >= 500 ? "SERVER_5XX" : "PROFILE_UPDATE_FAILED");
|
|
50334
|
-
throw cliError(code, res.error ?? `HTTP ${res.status}`);
|
|
50335
|
-
}
|
|
50336
|
-
latestProfile = res.data;
|
|
50337
|
-
}
|
|
50338
|
-
if (!latestProfile) {
|
|
50339
|
-
throw cliError("PROFILE_UPDATE_FAILED", "No profile returned from server");
|
|
50340
|
-
}
|
|
50341
|
-
if (opts.json) {
|
|
50342
|
-
writeJson(ctx.io, { ok: true, data: latestProfile });
|
|
50343
|
-
return;
|
|
50344
|
-
}
|
|
50345
|
-
writeText(ctx.io, `${formatProfile(latestProfile)}
|
|
50346
|
-
`);
|
|
50347
|
-
}
|
|
50348
|
-
);
|
|
50349
|
-
function registerProfileUpdateCommand(parent, runtimeOptions = {}) {
|
|
50350
|
-
registerCliCommand(parent, profileUpdateCommand, runtimeOptions);
|
|
50351
|
-
}
|
|
50352
|
-
|
|
50353
51455
|
// src/commands/integration/list.ts
|
|
50354
51456
|
init_esm_shims();
|
|
50355
51457
|
|
|
@@ -50378,6 +51480,7 @@ function pushServiceBlock(lines, service, active) {
|
|
|
50378
51480
|
if (service.agentManifestUrl) {
|
|
50379
51481
|
lines.push(` agent behavior manifest: ${service.agentManifestUrl}`);
|
|
50380
51482
|
lines.push(` local CLI env: raft integration env --service ${JSON.stringify(service.clientId)}`);
|
|
51483
|
+
lines.push(` if manifest exposes HTTP API actions: raft integration invoke --service ${JSON.stringify(service.clientId)} --list-actions`);
|
|
50381
51484
|
}
|
|
50382
51485
|
if (service.homepageUrl) lines.push(` homepage: ${service.homepageUrl}`);
|
|
50383
51486
|
if (service.description) lines.push(` description: ${service.description}`);
|
|
@@ -50417,6 +51520,7 @@ function formatIntegrationList(data) {
|
|
|
50417
51520
|
if (login.agentManifestUrl) {
|
|
50418
51521
|
lines.push(` agent behavior manifest: ${login.agentManifestUrl}`);
|
|
50419
51522
|
lines.push(` local CLI env: raft integration env --service ${JSON.stringify(login.clientId)}`);
|
|
51523
|
+
lines.push(` if manifest exposes HTTP API actions: raft integration invoke --service ${JSON.stringify(login.clientId)} --list-actions`);
|
|
50420
51524
|
}
|
|
50421
51525
|
lines.push(` created: ${login.createdAt}`);
|
|
50422
51526
|
}
|
|
@@ -50453,14 +51557,15 @@ function formatIntegrationLogin(data) {
|
|
|
50453
51557
|
if (data.service.agentManifestUrl) {
|
|
50454
51558
|
lines.push(`agent behavior manifest: ${data.service.agentManifestUrl}`);
|
|
50455
51559
|
lines.push(`local CLI env: raft integration env --service ${JSON.stringify(data.service.clientId)}`);
|
|
51560
|
+
lines.push(`if manifest exposes HTTP API actions: raft integration invoke --service ${JSON.stringify(data.service.clientId)} --list-actions`);
|
|
50456
51561
|
}
|
|
50457
51562
|
lines.push("complete: this agent login is configured in Slock; no human OAuth is required");
|
|
50458
51563
|
lines.push("identity: run `raft profile show` if the service or human asks for your Slock Agent identity card");
|
|
50459
51564
|
const callbackHandoffUrl = buildAgentCallbackHandoffUrl(data.service.returnUrl, data.requestId);
|
|
50460
51565
|
if (callbackHandoffUrl) {
|
|
50461
51566
|
lines.push(`service callback handoff URL: ${callbackHandoffUrl}`);
|
|
50462
|
-
lines.push("
|
|
50463
|
-
lines.push(
|
|
51567
|
+
lines.push("note: stateless Login with Raft API-action services use this callback once to create their service session");
|
|
51568
|
+
lines.push(`next: prefer \`raft integration invoke --service ${JSON.stringify(data.service.clientId)} --list-actions\` when the service manifest exposes actions`);
|
|
50464
51569
|
} else {
|
|
50465
51570
|
lines.push("next: use the service, or run `raft integration list` to confirm active login");
|
|
50466
51571
|
}
|
|
@@ -50563,7 +51668,10 @@ import os4 from "os";
|
|
|
50563
51668
|
import path8 from "path";
|
|
50564
51669
|
var AGENT_MANIFEST_MAX_BYTES = 64 * 1024;
|
|
50565
51670
|
var AGENT_MANIFEST_SCHEMA_V0 = "slock-agent-manifest.v0";
|
|
51671
|
+
var RAFT_AGENT_MANIFEST_SCHEMA_V0 = "raft-agent-manifest.v0";
|
|
50566
51672
|
var AGENT_MANIFEST_SCHEMA_V0_URL = "https://app.slock.ai/schemas/agent-manifest.v0.json";
|
|
51673
|
+
var RAFT_AGENT_MANIFEST_WELL_KNOWN_PATH = "/.well-known/raft-agent-manifest.json";
|
|
51674
|
+
var SLOCK_AGENT_MANIFEST_WELL_KNOWN_PATH = "/.well-known/slock-agent-manifest.json";
|
|
50567
51675
|
var AgentManifestFetchError = class extends Error {
|
|
50568
51676
|
constructor(message, status) {
|
|
50569
51677
|
super(message);
|
|
@@ -50608,10 +51716,125 @@ function requireCommand(value) {
|
|
|
50608
51716
|
}
|
|
50609
51717
|
return command;
|
|
50610
51718
|
}
|
|
51719
|
+
function requireName(value, field) {
|
|
51720
|
+
if (typeof value !== "string" || !value.trim()) {
|
|
51721
|
+
throw new Error(`${field} must be a non-empty string`);
|
|
51722
|
+
}
|
|
51723
|
+
const name = value.trim();
|
|
51724
|
+
if (!/^[A-Za-z0-9._:-]{1,80}$/.test(name)) {
|
|
51725
|
+
throw new Error(`${field} may only contain letters, digits, dot, underscore, colon, or dash`);
|
|
51726
|
+
}
|
|
51727
|
+
return name;
|
|
51728
|
+
}
|
|
51729
|
+
function optionalString(value) {
|
|
51730
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
51731
|
+
}
|
|
51732
|
+
function requireEndpointPath(value, field) {
|
|
51733
|
+
if (typeof value !== "string" || !value.trim()) {
|
|
51734
|
+
throw new Error(`${field} must be a non-empty path string`);
|
|
51735
|
+
}
|
|
51736
|
+
const path9 = value.trim();
|
|
51737
|
+
if (!path9.startsWith("/")) {
|
|
51738
|
+
throw new Error(`${field} must start with /`);
|
|
51739
|
+
}
|
|
51740
|
+
if (path9.startsWith("//")) {
|
|
51741
|
+
throw new Error(`${field} must be a relative service path`);
|
|
51742
|
+
}
|
|
51743
|
+
try {
|
|
51744
|
+
const parsed = new URL(path9, "https://manifest.local");
|
|
51745
|
+
if (parsed.origin !== "https://manifest.local" || parsed.username || parsed.password || parsed.hash) {
|
|
51746
|
+
throw new Error();
|
|
51747
|
+
}
|
|
51748
|
+
} catch {
|
|
51749
|
+
throw new Error(`${field} must be a relative service path`);
|
|
51750
|
+
}
|
|
51751
|
+
return path9;
|
|
51752
|
+
}
|
|
51753
|
+
function normalizeActionMethod(value) {
|
|
51754
|
+
if (typeof value !== "string") {
|
|
51755
|
+
throw new Error("actions[].endpoint.method must be a string");
|
|
51756
|
+
}
|
|
51757
|
+
const method = value.trim().toUpperCase();
|
|
51758
|
+
if (method !== "GET" && method !== "POST" && method !== "PUT" && method !== "PATCH" && method !== "DELETE") {
|
|
51759
|
+
throw new Error("actions[].endpoint.method must be GET, POST, PUT, PATCH, or DELETE");
|
|
51760
|
+
}
|
|
51761
|
+
return method;
|
|
51762
|
+
}
|
|
51763
|
+
function normalizeActionFields(value, field) {
|
|
51764
|
+
if (value === void 0) return void 0;
|
|
51765
|
+
if (!isRecord(value)) throw new Error(`${field} must be an object when present`);
|
|
51766
|
+
const fields = {};
|
|
51767
|
+
for (const [key, raw] of Object.entries(value)) {
|
|
51768
|
+
const name = requireName(key, `${field} key`);
|
|
51769
|
+
if (!isRecord(raw)) throw new Error(`${field}.${name} must be an object`);
|
|
51770
|
+
if (typeof raw.type !== "string" || !raw.type.trim()) {
|
|
51771
|
+
throw new Error(`${field}.${name}.type must be a non-empty string`);
|
|
51772
|
+
}
|
|
51773
|
+
fields[name] = {
|
|
51774
|
+
type: raw.type.trim(),
|
|
51775
|
+
description: optionalString(raw.description),
|
|
51776
|
+
required: raw.required === true
|
|
51777
|
+
};
|
|
51778
|
+
}
|
|
51779
|
+
return fields;
|
|
51780
|
+
}
|
|
51781
|
+
function normalizeActionReturns(value) {
|
|
51782
|
+
if (value === void 0) return void 0;
|
|
51783
|
+
if (!isRecord(value)) throw new Error("actions[].returns must be an object when present");
|
|
51784
|
+
const fields = {};
|
|
51785
|
+
for (const [key, raw] of Object.entries(value)) {
|
|
51786
|
+
const name = requireName(key, "actions[].returns key");
|
|
51787
|
+
if (!isRecord(raw)) throw new Error(`actions[].returns.${name} must be an object`);
|
|
51788
|
+
if (typeof raw.type !== "string" || !raw.type.trim()) {
|
|
51789
|
+
throw new Error(`actions[].returns.${name}.type must be a non-empty string`);
|
|
51790
|
+
}
|
|
51791
|
+
fields[name] = {
|
|
51792
|
+
type: raw.type.trim(),
|
|
51793
|
+
description: optionalString(raw.description)
|
|
51794
|
+
};
|
|
51795
|
+
}
|
|
51796
|
+
return fields;
|
|
51797
|
+
}
|
|
51798
|
+
function normalizeActions(value) {
|
|
51799
|
+
if (value === void 0) return void 0;
|
|
51800
|
+
if (!Array.isArray(value)) throw new Error("actions must be an array when present");
|
|
51801
|
+
const actions = value.map((raw, index) => {
|
|
51802
|
+
if (!isRecord(raw)) throw new Error(`actions[${index}] must be an object`);
|
|
51803
|
+
const endpoint = raw.endpoint;
|
|
51804
|
+
if (!isRecord(endpoint)) throw new Error(`actions[${index}].endpoint must be an object`);
|
|
51805
|
+
return {
|
|
51806
|
+
name: requireName(raw.name, `actions[${index}].name`),
|
|
51807
|
+
description: optionalString(raw.description),
|
|
51808
|
+
endpoint: {
|
|
51809
|
+
method: normalizeActionMethod(endpoint.method),
|
|
51810
|
+
path: requireEndpointPath(endpoint.path, `actions[${index}].endpoint.path`)
|
|
51811
|
+
},
|
|
51812
|
+
parameters: normalizeActionFields(raw.parameters, `actions[${index}].parameters`),
|
|
51813
|
+
returns: normalizeActionReturns(raw.returns)
|
|
51814
|
+
};
|
|
51815
|
+
});
|
|
51816
|
+
const seen = /* @__PURE__ */ new Set();
|
|
51817
|
+
for (const action of actions) {
|
|
51818
|
+
if (seen.has(action.name)) throw new Error(`duplicate action name: ${action.name}`);
|
|
51819
|
+
seen.add(action.name);
|
|
51820
|
+
}
|
|
51821
|
+
return actions;
|
|
51822
|
+
}
|
|
51823
|
+
function normalizeAuth(value) {
|
|
51824
|
+
if (value === void 0) return void 0;
|
|
51825
|
+
if (!isRecord(value)) throw new Error("auth must be an object when present");
|
|
51826
|
+
if (value.type !== "login_with_raft") {
|
|
51827
|
+
throw new Error("auth.type must be login_with_raft");
|
|
51828
|
+
}
|
|
51829
|
+
return {
|
|
51830
|
+
type: "login_with_raft",
|
|
51831
|
+
login_url: value.login_url === void 0 ? void 0 : requireUrl(value.login_url, "auth.login_url")
|
|
51832
|
+
};
|
|
51833
|
+
}
|
|
50611
51834
|
function validateAgentManifestV0(value) {
|
|
50612
51835
|
if (!isRecord(value)) throw new Error("manifest must be a JSON object");
|
|
50613
|
-
if (value.schema !== AGENT_MANIFEST_SCHEMA_V0 && value.schema !== AGENT_MANIFEST_SCHEMA_V0_URL) {
|
|
50614
|
-
throw new Error(`manifest schema must be ${AGENT_MANIFEST_SCHEMA_V0}`);
|
|
51836
|
+
if (value.schema !== AGENT_MANIFEST_SCHEMA_V0 && value.schema !== RAFT_AGENT_MANIFEST_SCHEMA_V0 && value.schema !== AGENT_MANIFEST_SCHEMA_V0_URL) {
|
|
51837
|
+
throw new Error(`manifest schema must be ${AGENT_MANIFEST_SCHEMA_V0} or ${RAFT_AGENT_MANIFEST_SCHEMA_V0}`);
|
|
50615
51838
|
}
|
|
50616
51839
|
const execution = value.execution;
|
|
50617
51840
|
if (!isRecord(execution)) throw new Error("execution must be an object");
|
|
@@ -50633,12 +51856,17 @@ function validateAgentManifestV0(value) {
|
|
|
50633
51856
|
return {
|
|
50634
51857
|
schema: AGENT_MANIFEST_SCHEMA_V0,
|
|
50635
51858
|
service: typeof value.service === "string" && value.service.trim() ? value.service.trim() : void 0,
|
|
51859
|
+
name: optionalString(value.name),
|
|
51860
|
+
description: optionalString(value.description),
|
|
50636
51861
|
docs_url: value.docs_url === void 0 ? void 0 : requireUrl(value.docs_url, "docs_url"),
|
|
51862
|
+
app_origin: value.app_origin === void 0 ? void 0 : requireUrl(value.app_origin, "app_origin"),
|
|
50637
51863
|
execution: {
|
|
50638
51864
|
mode: execution.mode,
|
|
50639
51865
|
command: execution.mode === "local_cli" ? requireCommand(execution.command) : void 0,
|
|
50640
51866
|
base_url: execution.base_url === void 0 ? void 0 : requireUrl(execution.base_url, "execution.base_url")
|
|
50641
51867
|
},
|
|
51868
|
+
auth: normalizeAuth(value.auth),
|
|
51869
|
+
actions: normalizeActions(value.actions),
|
|
50642
51870
|
credential_boundary: credentialStorage ? {
|
|
50643
51871
|
storage: credentialStorage,
|
|
50644
51872
|
forbid_user_home: forbidUserHome
|
|
@@ -50686,13 +51914,45 @@ async function fetchAgentManifest(url2) {
|
|
|
50686
51914
|
}
|
|
50687
51915
|
return validateAgentManifestV0(parsedJson);
|
|
50688
51916
|
}
|
|
51917
|
+
function wellKnownAliasUrl(url2) {
|
|
51918
|
+
const parsed = new URL(url2);
|
|
51919
|
+
if (parsed.pathname === RAFT_AGENT_MANIFEST_WELL_KNOWN_PATH) {
|
|
51920
|
+
parsed.pathname = SLOCK_AGENT_MANIFEST_WELL_KNOWN_PATH;
|
|
51921
|
+
return parsed.toString();
|
|
51922
|
+
}
|
|
51923
|
+
if (parsed.pathname === SLOCK_AGENT_MANIFEST_WELL_KNOWN_PATH) {
|
|
51924
|
+
parsed.pathname = RAFT_AGENT_MANIFEST_WELL_KNOWN_PATH;
|
|
51925
|
+
return parsed.toString();
|
|
51926
|
+
}
|
|
51927
|
+
return null;
|
|
51928
|
+
}
|
|
51929
|
+
function shouldTryWellKnownAlias(err) {
|
|
51930
|
+
if (err instanceof AgentManifestFetchError) return err.status === 404 || err.status === 410;
|
|
51931
|
+
return err instanceof AgentManifestResponseFormatError;
|
|
51932
|
+
}
|
|
51933
|
+
async function fetchAgentManifestWithWellKnownAliases(url2, fetchManifestImpl = fetchAgentManifest) {
|
|
51934
|
+
try {
|
|
51935
|
+
return await fetchManifestImpl(url2);
|
|
51936
|
+
} catch (err) {
|
|
51937
|
+
if (!shouldTryWellKnownAlias(err)) throw err;
|
|
51938
|
+
const alias = wellKnownAliasUrl(url2);
|
|
51939
|
+
if (!alias) throw err;
|
|
51940
|
+
return await fetchManifestImpl(alias);
|
|
51941
|
+
}
|
|
51942
|
+
}
|
|
50689
51943
|
function sanitizePathSegment(value) {
|
|
50690
51944
|
const segment = value.trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
50691
51945
|
return segment || "service";
|
|
50692
51946
|
}
|
|
50693
|
-
function resolveSlockHome(env) {
|
|
50694
|
-
|
|
50695
|
-
|
|
51947
|
+
function resolveSlockHome(env, homeDir = os4.homedir()) {
|
|
51948
|
+
const configured = env.SLOCK_HOME?.trim() || env.RAFT_HOME?.trim();
|
|
51949
|
+
const raw = configured && configured.length > 0 ? configured : path8.join(homeDir, ".slock");
|
|
51950
|
+
return path8.resolve(expandHome(raw, homeDir));
|
|
51951
|
+
}
|
|
51952
|
+
function expandHome(input, homeDir) {
|
|
51953
|
+
if (input === "~") return homeDir;
|
|
51954
|
+
if (input.startsWith("~/")) return path8.join(homeDir, input.slice(2));
|
|
51955
|
+
return input;
|
|
50696
51956
|
}
|
|
50697
51957
|
function buildLocalCliProfileEnv(input) {
|
|
50698
51958
|
if (input.manifest.execution.mode !== "local_cli" || !input.manifest.execution.command) {
|
|
@@ -50704,7 +51964,7 @@ function buildLocalCliProfileEnv(input) {
|
|
|
50704
51964
|
if (input.manifest.credential_boundary.forbid_user_home !== true) {
|
|
50705
51965
|
throw new Error("manifest must set credential_boundary.forbid_user_home=true for local_cli isolation");
|
|
50706
51966
|
}
|
|
50707
|
-
const root = resolveSlockHome(input.env ?? process.env);
|
|
51967
|
+
const root = resolveSlockHome(input.env ?? process.env, input.homeDir);
|
|
50708
51968
|
const profileHome = path8.join(
|
|
50709
51969
|
root,
|
|
50710
51970
|
"integration-profiles",
|
|
@@ -50758,7 +52018,10 @@ function findService(data, service) {
|
|
|
50758
52018
|
}
|
|
50759
52019
|
function describeNoLocalEnv(manifest) {
|
|
50760
52020
|
if (manifest.execution.mode !== "local_cli") {
|
|
50761
|
-
|
|
52021
|
+
if (manifest.actions && manifest.actions.length > 0) {
|
|
52022
|
+
return "manifest exposes HTTP API actions; no local CLI env is required";
|
|
52023
|
+
}
|
|
52024
|
+
return "manifest execution mode is http_api; no local CLI env is required";
|
|
50762
52025
|
}
|
|
50763
52026
|
if (!manifest.credential_boundary) {
|
|
50764
52027
|
return "manifest does not request a Slock-managed local environment";
|
|
@@ -50803,7 +52066,7 @@ async function resolveIntegrationEnv(input) {
|
|
|
50803
52066
|
message: describeMissingManifest({ service: input.service })
|
|
50804
52067
|
};
|
|
50805
52068
|
}
|
|
50806
|
-
const fetchManifestImpl = input.fetchManifest ?? fetchAgentManifest;
|
|
52069
|
+
const fetchManifestImpl = input.fetchManifest ?? (isInferredWellKnownManifest(input.service) ? fetchAgentManifestWithWellKnownAliases : fetchAgentManifest);
|
|
50807
52070
|
let manifest;
|
|
50808
52071
|
try {
|
|
50809
52072
|
manifest = await fetchManifestImpl(input.service.agentManifestUrl);
|
|
@@ -50842,13 +52105,19 @@ async function resolveIntegrationEnv(input) {
|
|
|
50842
52105
|
}
|
|
50843
52106
|
}
|
|
50844
52107
|
function formatNoLocalEnv(input) {
|
|
50845
|
-
|
|
52108
|
+
const lines = [
|
|
50846
52109
|
`# Slock integration profile for ${input.service}`,
|
|
50847
52110
|
input.manifestUrl ? `# manifest: ${input.manifestUrl}` : "# manifest: none declared",
|
|
50848
52111
|
"# No local CLI environment exports are required for this service.",
|
|
50849
|
-
`# ${input.message}
|
|
50850
|
-
|
|
50851
|
-
|
|
52112
|
+
`# ${input.message}`
|
|
52113
|
+
];
|
|
52114
|
+
if (input.actions && input.actions.length > 0) {
|
|
52115
|
+
lines.push(`# API actions: ${input.actions.join(", ")}`);
|
|
52116
|
+
lines.push(`# list actions: raft integration invoke --service ${JSON.stringify(input.service)} --list-actions`);
|
|
52117
|
+
lines.push(`# invoke action: raft integration invoke --service ${JSON.stringify(input.service)} --action <name>`);
|
|
52118
|
+
}
|
|
52119
|
+
lines.push("# Slock did not set HOME/XDG exports and did not execute manifest commands.");
|
|
52120
|
+
return lines.join("\n");
|
|
50852
52121
|
}
|
|
50853
52122
|
var integrationEnvCommand = defineCommand(
|
|
50854
52123
|
{
|
|
@@ -50892,6 +52161,7 @@ var integrationEnvCommand = defineCommand(
|
|
|
50892
52161
|
manifestUrl: resolution.manifestUrl,
|
|
50893
52162
|
requiresLocalEnv: false,
|
|
50894
52163
|
command: resolution.manifest?.execution.command ?? null,
|
|
52164
|
+
actions: resolution.manifest?.actions?.map((action) => action.name) ?? [],
|
|
50895
52165
|
env: {},
|
|
50896
52166
|
message: resolution.message
|
|
50897
52167
|
}
|
|
@@ -50901,7 +52171,8 @@ var integrationEnvCommand = defineCommand(
|
|
|
50901
52171
|
writeText(cmdCtx.io, `${formatNoLocalEnv({
|
|
50902
52172
|
service: resolution.service.clientId,
|
|
50903
52173
|
manifestUrl: resolution.manifestUrl,
|
|
50904
|
-
message: resolution.message
|
|
52174
|
+
message: resolution.message,
|
|
52175
|
+
actions: resolution.manifest?.actions?.map((action) => action.name) ?? []
|
|
50905
52176
|
})}
|
|
50906
52177
|
`);
|
|
50907
52178
|
return;
|
|
@@ -50928,8 +52199,19 @@ function registerIntegrationEnvCommand(parent, runtimeOptions = {}) {
|
|
|
50928
52199
|
registerCliCommand(parent, integrationEnvCommand, runtimeOptions);
|
|
50929
52200
|
}
|
|
50930
52201
|
|
|
50931
|
-
// src/commands/integration/
|
|
52202
|
+
// src/commands/integration/invoke.ts
|
|
50932
52203
|
init_esm_shims();
|
|
52204
|
+
import fs6 from "fs";
|
|
52205
|
+
function normalizeService2(value) {
|
|
52206
|
+
return value.trim().toLowerCase();
|
|
52207
|
+
}
|
|
52208
|
+
function findService2(data, service) {
|
|
52209
|
+
const normalized = normalizeService2(service);
|
|
52210
|
+
if (!normalized) return null;
|
|
52211
|
+
return data.services.find(
|
|
52212
|
+
(candidate) => candidate.id === service || normalizeService2(candidate.clientId) === normalized || normalizeService2(candidate.name) === normalized
|
|
52213
|
+
) ?? null;
|
|
52214
|
+
}
|
|
50933
52215
|
function normalizeScopes2(raw) {
|
|
50934
52216
|
if (!raw || raw.length === 0) return void 0;
|
|
50935
52217
|
const scopes = Array.from(new Set(
|
|
@@ -50940,6 +52222,343 @@ function normalizeScopes2(raw) {
|
|
|
50940
52222
|
}
|
|
50941
52223
|
return scopes;
|
|
50942
52224
|
}
|
|
52225
|
+
function parseHandlerArgs(serviceArgOrOpts, actionArgOrOpts, maybeOpts) {
|
|
52226
|
+
if (typeof serviceArgOrOpts === "object" && serviceArgOrOpts !== null) {
|
|
52227
|
+
return { opts: serviceArgOrOpts };
|
|
52228
|
+
}
|
|
52229
|
+
if (typeof actionArgOrOpts === "object" && actionArgOrOpts !== null) {
|
|
52230
|
+
return { serviceArg: serviceArgOrOpts, opts: actionArgOrOpts };
|
|
52231
|
+
}
|
|
52232
|
+
return { serviceArg: serviceArgOrOpts, actionArg: actionArgOrOpts, opts: maybeOpts ?? {} };
|
|
52233
|
+
}
|
|
52234
|
+
function readTextReference(value) {
|
|
52235
|
+
if (!value.startsWith("@")) return value;
|
|
52236
|
+
const path9 = value.slice(1);
|
|
52237
|
+
if (!path9) throw cliError("INVALID_ARG", "@ file references must include a path");
|
|
52238
|
+
if (path9 === "-") return fs6.readFileSync(0, "utf8");
|
|
52239
|
+
return fs6.readFileSync(path9, "utf8");
|
|
52240
|
+
}
|
|
52241
|
+
function parseJsonObject(raw, label) {
|
|
52242
|
+
let parsed;
|
|
52243
|
+
try {
|
|
52244
|
+
parsed = JSON.parse(raw);
|
|
52245
|
+
} catch (err) {
|
|
52246
|
+
throw cliError("INVALID_ARG", `${label} is not valid JSON: ${err.message}`);
|
|
52247
|
+
}
|
|
52248
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
52249
|
+
throw cliError("INVALID_ARG", `${label} must be a JSON object`);
|
|
52250
|
+
}
|
|
52251
|
+
return parsed;
|
|
52252
|
+
}
|
|
52253
|
+
function parseActionPayload(opts) {
|
|
52254
|
+
if (opts.dataJson && opts.dataFile) {
|
|
52255
|
+
throw cliError("INVALID_ARG", "use only one of --data-json or --data-file");
|
|
52256
|
+
}
|
|
52257
|
+
const payload = {};
|
|
52258
|
+
if (opts.dataJson) {
|
|
52259
|
+
Object.assign(payload, parseJsonObject(opts.dataJson, "--data-json"));
|
|
52260
|
+
}
|
|
52261
|
+
if (opts.dataFile) {
|
|
52262
|
+
const raw = opts.dataFile === "-" ? fs6.readFileSync(0, "utf8") : fs6.readFileSync(opts.dataFile, "utf8");
|
|
52263
|
+
Object.assign(payload, parseJsonObject(raw, "--data-file"));
|
|
52264
|
+
}
|
|
52265
|
+
for (const rawParam of opts.param ?? []) {
|
|
52266
|
+
const separator = rawParam.indexOf("=");
|
|
52267
|
+
if (separator <= 0) {
|
|
52268
|
+
throw cliError("INVALID_ARG", "--param values must use key=value");
|
|
52269
|
+
}
|
|
52270
|
+
const key = rawParam.slice(0, separator).trim();
|
|
52271
|
+
if (!key) throw cliError("INVALID_ARG", "--param keys must not be empty");
|
|
52272
|
+
payload[key] = readTextReference(rawParam.slice(separator + 1));
|
|
52273
|
+
}
|
|
52274
|
+
return payload;
|
|
52275
|
+
}
|
|
52276
|
+
function validateRequiredParams(action, payload) {
|
|
52277
|
+
for (const [name, spec] of Object.entries(action.parameters ?? {})) {
|
|
52278
|
+
if (!spec.required) continue;
|
|
52279
|
+
if (payload[name] === void 0 || payload[name] === null || payload[name] === "") {
|
|
52280
|
+
throw cliError("INVALID_ARG", `missing required parameter ${name}`);
|
|
52281
|
+
}
|
|
52282
|
+
}
|
|
52283
|
+
}
|
|
52284
|
+
function safeUrl(value, label) {
|
|
52285
|
+
let url2;
|
|
52286
|
+
try {
|
|
52287
|
+
url2 = new URL(value);
|
|
52288
|
+
} catch {
|
|
52289
|
+
throw cliError("INVALID_ARG", `${label} must be a valid URL`);
|
|
52290
|
+
}
|
|
52291
|
+
if (url2.protocol !== "https:" && url2.protocol !== "http:") {
|
|
52292
|
+
throw cliError("INVALID_ARG", `${label} must use http or https`);
|
|
52293
|
+
}
|
|
52294
|
+
if (url2.username || url2.password) {
|
|
52295
|
+
throw cliError("INVALID_ARG", `${label} must not include credentials`);
|
|
52296
|
+
}
|
|
52297
|
+
return url2;
|
|
52298
|
+
}
|
|
52299
|
+
function resolveActionUrl(input) {
|
|
52300
|
+
const base = input.manifest.execution.base_url ?? input.manifest.app_origin ?? input.service.homepageUrl ?? (input.service.returnUrl ? safeUrl(input.service.returnUrl, "service return URL").origin : null);
|
|
52301
|
+
if (!base) {
|
|
52302
|
+
throw cliError(
|
|
52303
|
+
"INVALID_ARG",
|
|
52304
|
+
"manifest must provide execution.base_url or app_origin, or the service must provide a homepage/return URL"
|
|
52305
|
+
);
|
|
52306
|
+
}
|
|
52307
|
+
const baseUrl = safeUrl(base, "action base URL");
|
|
52308
|
+
return new URL(input.action.endpoint.path, baseUrl);
|
|
52309
|
+
}
|
|
52310
|
+
function cookieHeaderFromSetCookie(headers) {
|
|
52311
|
+
const getSetCookie = headers.getSetCookie;
|
|
52312
|
+
const values = typeof getSetCookie === "function" ? getSetCookie.call(headers) : [headers.get("set-cookie")].filter((value) => Boolean(value));
|
|
52313
|
+
const cookies = values.map((value) => value.split(";")[0]?.trim()).filter((value) => Boolean(value));
|
|
52314
|
+
return cookies.length > 0 ? cookies.join("; ") : null;
|
|
52315
|
+
}
|
|
52316
|
+
async function establishServiceSession(input) {
|
|
52317
|
+
const callbackUrl = buildAgentCallbackHandoffUrl(input.service.returnUrl, input.login.requestId);
|
|
52318
|
+
if (!callbackUrl) {
|
|
52319
|
+
throw cliError("INTEGRATION_INVOKE_FAILED", "service return URL cannot be used for Agent Login callback handoff");
|
|
52320
|
+
}
|
|
52321
|
+
const response = await fetch(callbackUrl, {
|
|
52322
|
+
method: "GET",
|
|
52323
|
+
redirect: "manual",
|
|
52324
|
+
headers: { accept: "text/html,application/json" }
|
|
52325
|
+
});
|
|
52326
|
+
if (response.status < 200 || response.status >= 400) {
|
|
52327
|
+
throw cliError("INTEGRATION_INVOKE_FAILED", `service callback handoff failed with HTTP ${response.status}`);
|
|
52328
|
+
}
|
|
52329
|
+
const cookie = cookieHeaderFromSetCookie(response.headers);
|
|
52330
|
+
if (!cookie) {
|
|
52331
|
+
throw cliError(
|
|
52332
|
+
"INTEGRATION_INVOKE_FAILED",
|
|
52333
|
+
"service callback handoff did not set a session cookie; the service may not support stateless Agent Login API actions yet"
|
|
52334
|
+
);
|
|
52335
|
+
}
|
|
52336
|
+
return cookie;
|
|
52337
|
+
}
|
|
52338
|
+
function appendPayloadAsQuery(url2, payload) {
|
|
52339
|
+
for (const [key, value] of Object.entries(payload)) {
|
|
52340
|
+
if (value === void 0 || value === null) continue;
|
|
52341
|
+
url2.searchParams.set(key, typeof value === "string" ? value : JSON.stringify(value));
|
|
52342
|
+
}
|
|
52343
|
+
}
|
|
52344
|
+
async function invokeHttpAction(input) {
|
|
52345
|
+
const url2 = new URL(input.url);
|
|
52346
|
+
const headers = {
|
|
52347
|
+
accept: "application/json,text/plain,*/*",
|
|
52348
|
+
cookie: input.cookie
|
|
52349
|
+
};
|
|
52350
|
+
const init = {
|
|
52351
|
+
method: input.action.endpoint.method,
|
|
52352
|
+
headers,
|
|
52353
|
+
redirect: "follow"
|
|
52354
|
+
};
|
|
52355
|
+
if (input.action.endpoint.method === "GET") {
|
|
52356
|
+
appendPayloadAsQuery(url2, input.payload);
|
|
52357
|
+
} else {
|
|
52358
|
+
headers["content-type"] = "application/json";
|
|
52359
|
+
init.body = JSON.stringify(input.payload);
|
|
52360
|
+
}
|
|
52361
|
+
const response = await fetch(url2, init);
|
|
52362
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
52363
|
+
if (contentType.includes("application/json")) {
|
|
52364
|
+
const value2 = await response.json().catch(() => {
|
|
52365
|
+
throw cliError("INVALID_JSON_RESPONSE", `service action returned invalid JSON (HTTP ${response.status})`);
|
|
52366
|
+
});
|
|
52367
|
+
if (!response.ok) {
|
|
52368
|
+
const message = value2 && typeof value2 === "object" && "error" in value2 ? String(value2.error) : `service action failed with HTTP ${response.status}`;
|
|
52369
|
+
throw cliError("INTEGRATION_INVOKE_FAILED", message);
|
|
52370
|
+
}
|
|
52371
|
+
return { kind: "json", status: response.status, value: value2 };
|
|
52372
|
+
}
|
|
52373
|
+
const value = await response.text();
|
|
52374
|
+
if (!response.ok) {
|
|
52375
|
+
throw cliError("INTEGRATION_INVOKE_FAILED", value || `service action failed with HTTP ${response.status}`);
|
|
52376
|
+
}
|
|
52377
|
+
return { kind: "text", status: response.status, value };
|
|
52378
|
+
}
|
|
52379
|
+
function formatActions(input) {
|
|
52380
|
+
const actions = input.manifest.actions ?? [];
|
|
52381
|
+
const lines = [
|
|
52382
|
+
`Actions for ${input.service.name}`,
|
|
52383
|
+
`service: ${input.service.clientId}`,
|
|
52384
|
+
`manifest: ${input.manifestUrl}`
|
|
52385
|
+
];
|
|
52386
|
+
if (actions.length === 0) {
|
|
52387
|
+
lines.push("- none");
|
|
52388
|
+
return lines.join("\n");
|
|
52389
|
+
}
|
|
52390
|
+
for (const action of actions) {
|
|
52391
|
+
const required2 = Object.entries(action.parameters ?? {}).filter(([, param]) => param.required).map(([name]) => name);
|
|
52392
|
+
lines.push(`- ${action.name}`);
|
|
52393
|
+
lines.push(` endpoint: ${action.endpoint.method} ${action.endpoint.path}`);
|
|
52394
|
+
if (action.description) lines.push(` description: ${action.description}`);
|
|
52395
|
+
if (required2.length > 0) lines.push(` required params: ${required2.join(", ")}`);
|
|
52396
|
+
}
|
|
52397
|
+
lines.push(`next: raft integration invoke --service ${JSON.stringify(input.service.clientId)} --action ${JSON.stringify(actions[0]?.name ?? "<name>")}`);
|
|
52398
|
+
return lines.join("\n");
|
|
52399
|
+
}
|
|
52400
|
+
function pickViewerUrl(value) {
|
|
52401
|
+
return value && typeof value === "object" && typeof value.viewerUrl === "string" ? value.viewerUrl : null;
|
|
52402
|
+
}
|
|
52403
|
+
function formatActionResult(input) {
|
|
52404
|
+
const lines = [
|
|
52405
|
+
`Action invoked: ${input.action.name}`,
|
|
52406
|
+
`service: ${input.service.clientId}`,
|
|
52407
|
+
`status: HTTP ${input.result.status}`
|
|
52408
|
+
];
|
|
52409
|
+
if (input.result.kind === "json") {
|
|
52410
|
+
const viewerUrl = pickViewerUrl(input.result.value);
|
|
52411
|
+
if (viewerUrl) lines.push(`viewer URL: ${viewerUrl}`);
|
|
52412
|
+
lines.push("result:");
|
|
52413
|
+
lines.push(JSON.stringify(input.result.value, null, 2));
|
|
52414
|
+
} else if (input.result.value) {
|
|
52415
|
+
lines.push("result:");
|
|
52416
|
+
lines.push(input.result.value);
|
|
52417
|
+
}
|
|
52418
|
+
return lines.join("\n");
|
|
52419
|
+
}
|
|
52420
|
+
async function fetchManifestForInvoke(service) {
|
|
52421
|
+
if (!service.agentManifestUrl) {
|
|
52422
|
+
throw cliError("INTEGRATION_MANIFEST_MISSING", `${service.name} does not expose an agent behavior manifest`);
|
|
52423
|
+
}
|
|
52424
|
+
try {
|
|
52425
|
+
const fetchManifest = service.agentManifestUrlSource === "well_known" ? fetchAgentManifestWithWellKnownAliases : fetchAgentManifest;
|
|
52426
|
+
return await fetchManifest(service.agentManifestUrl);
|
|
52427
|
+
} catch (err) {
|
|
52428
|
+
if (err instanceof AgentManifestFetchError && (err.status === 404 || err.status === 410)) {
|
|
52429
|
+
throw cliError("INTEGRATION_MANIFEST_MISSING", "agent behavior manifest was not found", { cause: err });
|
|
52430
|
+
}
|
|
52431
|
+
if (err instanceof AgentManifestResponseFormatError) {
|
|
52432
|
+
throw cliError("INTEGRATION_MANIFEST_INVALID", err.message, { cause: err });
|
|
52433
|
+
}
|
|
52434
|
+
throw cliError("INTEGRATION_MANIFEST_INVALID", err.message, { cause: err });
|
|
52435
|
+
}
|
|
52436
|
+
}
|
|
52437
|
+
var integrationInvokeCommand = defineCommand(
|
|
52438
|
+
{
|
|
52439
|
+
name: "invoke",
|
|
52440
|
+
description: "Invoke a manifest-backed HTTP API action for a registered integration",
|
|
52441
|
+
arguments: ["[service]", "[action]"],
|
|
52442
|
+
options: [
|
|
52443
|
+
{ flags: "--service <id>", description: "Registered service id, client id, or exact service name" },
|
|
52444
|
+
{ flags: "--action <name>", description: "Manifest action name to invoke" },
|
|
52445
|
+
{ flags: "--list-actions", description: "List manifest actions instead of invoking one" },
|
|
52446
|
+
{
|
|
52447
|
+
flags: "--param <key=value>",
|
|
52448
|
+
description: "Action parameter; repeatable. Use key=@file or key=@- to read text",
|
|
52449
|
+
parse: (value, previous = []) => {
|
|
52450
|
+
previous.push(value);
|
|
52451
|
+
return previous;
|
|
52452
|
+
}
|
|
52453
|
+
},
|
|
52454
|
+
{ flags: "--data-json <json>", description: "JSON object request body for the action" },
|
|
52455
|
+
{ flags: "--data-file <path>", description: "JSON object request body file, or - for stdin" },
|
|
52456
|
+
{
|
|
52457
|
+
flags: "--scope <scope>",
|
|
52458
|
+
description: "Login scope to request before invoking; can be repeated or comma-separated",
|
|
52459
|
+
parse: (value, previous = []) => {
|
|
52460
|
+
previous.push(value);
|
|
52461
|
+
return previous;
|
|
52462
|
+
}
|
|
52463
|
+
},
|
|
52464
|
+
{ flags: "--target <target>", description: "Conversation target to post a human approval card when approval is required" },
|
|
52465
|
+
{ flags: "--json", description: "Emit machine-readable JSON" }
|
|
52466
|
+
]
|
|
52467
|
+
},
|
|
52468
|
+
async (cmdCtx, serviceArgOrOpts, actionArgOrOpts, maybeOpts) => {
|
|
52469
|
+
const { serviceArg, actionArg, opts } = parseHandlerArgs(serviceArgOrOpts, actionArgOrOpts, maybeOpts);
|
|
52470
|
+
const serviceQuery = (opts.service ?? serviceArg ?? "").trim();
|
|
52471
|
+
const actionName = (opts.action ?? actionArg ?? "").trim();
|
|
52472
|
+
if (!serviceQuery) throw cliError("INVALID_ARG", "--service or service argument is required");
|
|
52473
|
+
if (!opts.listActions && !actionName) throw cliError("INVALID_ARG", "--action or action argument is required");
|
|
52474
|
+
const agentContext = cmdCtx.loadAgentContext();
|
|
52475
|
+
const client = cmdCtx.createApiClient(agentContext);
|
|
52476
|
+
const api = createAgentApiSurfaceClient(client);
|
|
52477
|
+
const listRes = await api.integrations.list();
|
|
52478
|
+
if (!listRes.ok || !listRes.data) {
|
|
52479
|
+
const code = listRes.status >= 500 ? "SERVER_5XX" : "INTEGRATION_LIST_FAILED";
|
|
52480
|
+
throw cliError(code, listRes.error ?? `HTTP ${listRes.status}`);
|
|
52481
|
+
}
|
|
52482
|
+
const service = findService2(listRes.data, serviceQuery);
|
|
52483
|
+
if (!service) {
|
|
52484
|
+
throw cliError("INTEGRATION_NOT_FOUND", `No registered integration matched ${serviceQuery}`);
|
|
52485
|
+
}
|
|
52486
|
+
const manifest = await fetchManifestForInvoke(service);
|
|
52487
|
+
if (manifest.execution.mode !== "http_api") {
|
|
52488
|
+
throw cliError("INTEGRATION_MANIFEST_UNSUPPORTED", "manifest execution mode is not http_api");
|
|
52489
|
+
}
|
|
52490
|
+
if (opts.listActions) {
|
|
52491
|
+
if (opts.json) {
|
|
52492
|
+
writeJson(cmdCtx.io, {
|
|
52493
|
+
ok: true,
|
|
52494
|
+
data: {
|
|
52495
|
+
service: service.clientId,
|
|
52496
|
+
manifestUrl: service.agentManifestUrl,
|
|
52497
|
+
actions: manifest.actions ?? []
|
|
52498
|
+
}
|
|
52499
|
+
});
|
|
52500
|
+
return;
|
|
52501
|
+
}
|
|
52502
|
+
writeText(cmdCtx.io, `${formatActions({ service, manifestUrl: service.agentManifestUrl ?? "-", manifest })}
|
|
52503
|
+
`);
|
|
52504
|
+
return;
|
|
52505
|
+
}
|
|
52506
|
+
const action = (manifest.actions ?? []).find((candidate) => candidate.name === actionName);
|
|
52507
|
+
if (!action) throw cliError("INVALID_ARG", `manifest does not define action ${actionName}`);
|
|
52508
|
+
const payload = parseActionPayload(opts);
|
|
52509
|
+
validateRequiredParams(action, payload);
|
|
52510
|
+
const scopes = normalizeScopes2(opts.scope);
|
|
52511
|
+
const loginRes = await api.integrations.login({
|
|
52512
|
+
service: service.clientId,
|
|
52513
|
+
scopes,
|
|
52514
|
+
target: opts.target?.trim() || void 0
|
|
52515
|
+
});
|
|
52516
|
+
if (!loginRes.ok || !loginRes.data) {
|
|
52517
|
+
const code = loginRes.status >= 500 ? "SERVER_5XX" : "INTEGRATION_LOGIN_FAILED";
|
|
52518
|
+
throw cliError(code, loginRes.error ?? `HTTP ${loginRes.status}`);
|
|
52519
|
+
}
|
|
52520
|
+
if (loginRes.data.status === "approval_required") {
|
|
52521
|
+
throw cliError(
|
|
52522
|
+
"INTEGRATION_APPROVAL_REQUIRED",
|
|
52523
|
+
"human approval is required before invoking this integration action",
|
|
52524
|
+
{ suggestedNextAction: "Ask a server owner/admin to approve the integration login request, then rerun the command." }
|
|
52525
|
+
);
|
|
52526
|
+
}
|
|
52527
|
+
const cookie = await establishServiceSession({ login: loginRes.data, service });
|
|
52528
|
+
const url2 = resolveActionUrl({ service, manifest, action });
|
|
52529
|
+
const result2 = await invokeHttpAction({ url: url2, action, payload, cookie });
|
|
52530
|
+
if (opts.json) {
|
|
52531
|
+
writeJson(cmdCtx.io, {
|
|
52532
|
+
ok: true,
|
|
52533
|
+
data: {
|
|
52534
|
+
service: service.clientId,
|
|
52535
|
+
action: action.name,
|
|
52536
|
+
status: result2.status,
|
|
52537
|
+
result: result2.value
|
|
52538
|
+
}
|
|
52539
|
+
});
|
|
52540
|
+
return;
|
|
52541
|
+
}
|
|
52542
|
+
writeText(cmdCtx.io, `${formatActionResult({ service, action, result: result2 })}
|
|
52543
|
+
`);
|
|
52544
|
+
}
|
|
52545
|
+
);
|
|
52546
|
+
function registerIntegrationInvokeCommand(parent, runtimeOptions = {}) {
|
|
52547
|
+
registerCliCommand(parent, integrationInvokeCommand, runtimeOptions);
|
|
52548
|
+
}
|
|
52549
|
+
|
|
52550
|
+
// src/commands/integration/app.ts
|
|
52551
|
+
init_esm_shims();
|
|
52552
|
+
function normalizeScopes3(raw) {
|
|
52553
|
+
if (!raw || raw.length === 0) return void 0;
|
|
52554
|
+
const scopes = Array.from(new Set(
|
|
52555
|
+
raw.flatMap((value) => value.split(",")).map((value) => value.trim()).filter(Boolean)
|
|
52556
|
+
)).sort();
|
|
52557
|
+
if (scopes.length === 0) {
|
|
52558
|
+
throw cliError("INVALID_ARG", "--scope must include at least one non-empty scope");
|
|
52559
|
+
}
|
|
52560
|
+
return scopes;
|
|
52561
|
+
}
|
|
50943
52562
|
function requiredTrimmed(value, flag) {
|
|
50944
52563
|
const trimmed = value?.trim() ?? "";
|
|
50945
52564
|
if (!trimmed) throw cliError("INVALID_ARG", `${flag} is required`);
|
|
@@ -50968,7 +52587,7 @@ function formatAppPrepare(data) {
|
|
|
50968
52587
|
async function prepareApp(mode, ctx, opts) {
|
|
50969
52588
|
const target = requiredTrimmed(opts.target, "--target");
|
|
50970
52589
|
const clientKey = requiredTrimmed(opts.clientKey, "--client-key");
|
|
50971
|
-
const scopes =
|
|
52590
|
+
const scopes = normalizeScopes3([...opts.scope ?? [], ...opts.scopes ?? []]);
|
|
50972
52591
|
const agentContext = ctx.loadAgentContext();
|
|
50973
52592
|
const client = ctx.createApiClient(agentContext);
|
|
50974
52593
|
const body = {
|
|
@@ -50999,6 +52618,40 @@ async function prepareApp(mode, ctx, opts) {
|
|
|
50999
52618
|
writeText(ctx.io, `${formatAppPrepare(res.data)}
|
|
51000
52619
|
`);
|
|
51001
52620
|
}
|
|
52621
|
+
function formatAppRotateSecret(data) {
|
|
52622
|
+
return [
|
|
52623
|
+
`Integration app secret regenerated for ${data.clientName} (${data.clientKey})`,
|
|
52624
|
+
`client secret: ${data.clientSecret}`,
|
|
52625
|
+
"shown once \u2014 store it now; regenerating again invalidates the previous secret"
|
|
52626
|
+
].join("\n");
|
|
52627
|
+
}
|
|
52628
|
+
async function rotateAppSecret(ctx, opts) {
|
|
52629
|
+
const clientKey = requiredTrimmed(opts.client, "--client");
|
|
52630
|
+
const agentContext = ctx.loadAgentContext();
|
|
52631
|
+
const client = ctx.createApiClient(agentContext);
|
|
52632
|
+
const res = await createAgentApiSurfaceClient(client).integrations.rotateAppSecret({ clientKey });
|
|
52633
|
+
if (!res.ok || !res.data) {
|
|
52634
|
+
const code = res.status >= 500 ? "SERVER_5XX" : "INTEGRATION_APP_ROTATE_SECRET_FAILED";
|
|
52635
|
+
throw cliError(code, res.error ?? `HTTP ${res.status}`);
|
|
52636
|
+
}
|
|
52637
|
+
if (opts.json) {
|
|
52638
|
+
writeJson(ctx.io, { ok: true, data: res.data });
|
|
52639
|
+
return;
|
|
52640
|
+
}
|
|
52641
|
+
writeText(ctx.io, `${formatAppRotateSecret(res.data)}
|
|
52642
|
+
`);
|
|
52643
|
+
}
|
|
52644
|
+
var integrationAppRotateSecretCommand = defineCommand(
|
|
52645
|
+
{
|
|
52646
|
+
name: "rotate-secret",
|
|
52647
|
+
description: "Regenerate the one-time client secret for a server-local app you registered (invalidates the previous secret)",
|
|
52648
|
+
options: [
|
|
52649
|
+
{ flags: "--client <key>", description: "App client key / OAuth client_id you registered" },
|
|
52650
|
+
{ flags: "--json", description: "Emit machine-readable JSON" }
|
|
52651
|
+
]
|
|
52652
|
+
},
|
|
52653
|
+
async (ctx, opts) => rotateAppSecret(ctx, opts)
|
|
52654
|
+
);
|
|
51002
52655
|
var sharedOptions = [
|
|
51003
52656
|
{ flags: "--client-key <key>", description: "Stable app client key / OAuth client_id to reserve or update" },
|
|
51004
52657
|
{ flags: "--name <name>", description: "App display name" },
|
|
@@ -51048,6 +52701,7 @@ function registerIntegrationAppCommands(parent, runtimeOptions = {}) {
|
|
|
51048
52701
|
const prepareCmd = appCmd.command("prepare").description("Prepare app registration/update action cards");
|
|
51049
52702
|
registerCliCommand(prepareCmd, integrationAppPrepareRegisterCommand, runtimeOptions);
|
|
51050
52703
|
registerCliCommand(prepareCmd, integrationAppPrepareUpdateCommand, runtimeOptions);
|
|
52704
|
+
registerCliCommand(appCmd, integrationAppRotateSecretCommand, runtimeOptions);
|
|
51051
52705
|
}
|
|
51052
52706
|
|
|
51053
52707
|
// src/commands/reminder/schedule.ts
|
|
@@ -51466,6 +53120,10 @@ registerAgentListCommand(agentCmd);
|
|
|
51466
53120
|
registerAgentBridgeCommand(agentCmd);
|
|
51467
53121
|
var channelCmd = program2.command("channel").description("Channel membership and attention operations");
|
|
51468
53122
|
registerChannelMembersCommand(channelCmd);
|
|
53123
|
+
registerChannelCreateCommand(channelCmd);
|
|
53124
|
+
registerChannelUpdateCommand(channelCmd);
|
|
53125
|
+
registerChannelAddMemberCommand(channelCmd);
|
|
53126
|
+
registerChannelRemoveMemberCommand(channelCmd);
|
|
51469
53127
|
registerChannelJoinCommand(channelCmd);
|
|
51470
53128
|
registerChannelLeaveCommand(channelCmd);
|
|
51471
53129
|
registerChannelMuteCommand(channelCmd);
|
|
@@ -51474,6 +53132,7 @@ var threadCmd = program2.command("thread").description("Thread attention operati
|
|
|
51474
53132
|
registerThreadUnfollowCommand(threadCmd);
|
|
51475
53133
|
var serverCmd = program2.command("server").description("Server / workspace introspection");
|
|
51476
53134
|
registerServerInfoCommand(serverCmd);
|
|
53135
|
+
registerServerUpdateCommand(serverCmd);
|
|
51477
53136
|
var manualCmd = program2.command("manual").description("Slock Manual for Agents retrieval (canonical operating topics)");
|
|
51478
53137
|
registerKnowledgeGetCommand(manualCmd);
|
|
51479
53138
|
var knowledgeCmd = program2.command("knowledge").description("Legacy alias for `raft manual`");
|
|
@@ -51506,6 +53165,7 @@ var integrationCmd = program2.command("integration").description("Third-party se
|
|
|
51506
53165
|
registerIntegrationListCommand(integrationCmd);
|
|
51507
53166
|
registerIntegrationLoginCommand(integrationCmd);
|
|
51508
53167
|
registerIntegrationEnvCommand(integrationCmd);
|
|
53168
|
+
registerIntegrationInvokeCommand(integrationCmd);
|
|
51509
53169
|
registerIntegrationAppCommands(integrationCmd);
|
|
51510
53170
|
var reminderCmd = program2.command("reminder").description("Reminder operations");
|
|
51511
53171
|
registerReminderScheduleCommand(reminderCmd);
|