@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/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 fs6 = __require("fs");
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 (fs6.existsSync(localBin)) return localBin;
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) => fs6.existsSync(`${localBin}${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 = fs6.realpathSync(this._scriptPath);
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 safeUrl(path9) {
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" ? safeUrl(basePath) : basePath;
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(safeUrl(path9)), resolvedPathWithoutTrailingSlash) : matchValue(safeUrl(path9), resolvedPath);
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 buildLegacyAgentApiPath(agentId, routePath) {
43652
- return `/internal/agent/${encodeURIComponent(agentId)}${routePath}`;
43823
+ function getAgentApiResponseKind(response) {
43824
+ return "kind" in response ? response.kind ?? "json" : "json";
43653
43825
  }
43654
43826
  function parseAgentApiResponse(key, value) {
43655
- return agentApiContract[key].response.body.parse(value);
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 route2 = agentApiContract[routeKey];
43852
+ const route3 = agentApiContract[routeKey];
43671
43853
  let parsed;
43672
43854
  try {
43673
- parsed = "params" in route2.request ? route2.request.params.parse(params ?? {}) : {};
43855
+ parsed = "params" in route3.request ? route3.request.params.parse(params ?? {}) : {};
43674
43856
  } catch (cause) {
43675
- return failure(routeKey, "request_contract_mismatch", `Agent API ${route2.key} path params did not match the shared contract`, { cause });
43857
+ return failure(routeKey, "request_contract_mismatch", `Agent API ${route3.key} path params did not match the shared contract`, { cause });
43676
43858
  }
43677
- return route2.path.replace(/:([A-Za-z][A-Za-z0-9_]*)/g, (_match, key) => {
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(route2.key, key);
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 route2 = agentApiContract[routeKey];
43876
+ const route3 = agentApiContract[routeKey];
43695
43877
  let parsed;
43696
43878
  try {
43697
- parsed = "query" in route2.request ? route2.request.query.parse(query) : {};
43879
+ parsed = "query" in route3.request ? route3.request.query.parse(query) : {};
43698
43880
  } catch (cause) {
43699
- return failure(routeKey, "request_contract_mismatch", `Agent API ${route2.key} query did not match the shared contract`, { cause });
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 route2 = agentApiContract[routeKey];
43896
+ const route3 = agentApiContract[routeKey];
43715
43897
  try {
43716
- return "body" in route2.request ? route2.request.body.parse(body) : void 0;
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 ${route2.key} body did not match the shared contract`, { cause });
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 route2 = agentApiContract[routeKey];
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: route2.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 ${route2.key} transport request failed`, { cause });
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 ${route2.key} returned an empty response body`, {
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 ${route2.key} response did not match the shared contract`, {
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 route2 = agentApiContract[routeKey];
43985
+ const route3 = agentApiContract[routeKey];
43790
43986
  let index = 0;
43791
43987
  const requestOptions = { pathPrefix };
43792
- if ("params" in route2.request) {
43988
+ if ("params" in route3.request) {
43793
43989
  requestOptions.params = args[index++];
43794
43990
  }
43795
- if ("query" in route2.request) {
43991
+ if ("query" in route3.request) {
43796
43992
  requestOptions.query = args[index++];
43797
43993
  }
43798
- if ("body" in route2.request) {
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 route2 of Object.values(agentApiContract)) {
43807
- const routeKey = route2.key;
43808
- const { resource, method } = route2.client;
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(failure2) {
43893
- if (failure2.reason === "transport_error") {
44092
+ function errorFromRawFailure(failure3) {
44093
+ if (failure3.reason === "transport_error") {
43894
44094
  return {
43895
44095
  kind: "transport",
43896
- reason: failure2.reason,
43897
- message: failure2.message,
43898
- cause: failure2.cause
44096
+ reason: failure3.reason,
44097
+ message: failure3.message,
44098
+ cause: failure3.cause
43899
44099
  };
43900
44100
  }
43901
- if (failure2.reason === "http_error") {
44101
+ if (failure3.reason === "http_error") {
43902
44102
  return {
43903
44103
  kind: "http",
43904
- reason: failure2.reason,
43905
- message: failure2.message,
43906
- status: failure2.status ?? 0,
43907
- errorCode: failure2.errorCode,
43908
- suggestedNextAction: failure2.suggestedNextAction,
43909
- response: failure2.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: failure2.reason,
43915
- message: failure2.message,
43916
- status: failure2.status,
43917
- cause: failure2.cause,
43918
- response: failure2.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) => client.request(input.method, input.path, input.body)
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(failure2) {
44501
- switch (failure2.reason) {
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: failure2.message,
44507
- cause: failure2.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: failure2.message,
44515
- cause: failure2.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: failure2.message,
44522
- cause: failure2.cause
45108
+ message: failure3.message,
45109
+ cause: failure3.cause
44523
45110
  });
44524
45111
  }
44525
45112
  }
44526
- function cliErrorFromClientFailure(failure2) {
44527
- switch (failure2.error.kind) {
45113
+ function cliErrorFromClientFailure(failure3) {
45114
+ switch (failure3.error.kind) {
44528
45115
  case "validation":
44529
- switch (failure2.error.reason) {
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: failure2.error.message,
44535
- cause: failure2.error.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: failure2.error.message,
44543
- cause: failure2.error.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: failure2.error.message,
44551
- cause: failure2.error.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: failure2.error.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 createAgentApiClient2(client, agentId) {
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
- messages: {
44630
- send: (body) => requestClientAsApiResponse(agentApi.messages.send(body)),
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
- search: (query) => requestClientAsApiResponse(agentApi.messages.search(query))
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" || firstAfterAgentId === "receive-ack") {
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
- // Returns the raw Response so the caller can stream / save the body.
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
- `SLOCK_AGENT_TOKEN_FILE=${filePath} could not be read: ${err.message}`
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
- `SLOCK_AGENT_TOKEN_FILE=${filePath} is empty`
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
- return {
45298
- agentId,
45299
- serverUrl,
45300
- serverId,
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, SLOCK_AGENT_PROXY_TOKEN, SLOCK_AGENT_TOKEN_FILE nor SLOCK_AGENT_TOKEN is set. The daemon should inject one of these when spawning the agent process."
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, failure2) {
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: failure2.failureClass,
47005
- ...failure2.retryAfterMs ? { retryAfterMs: failure2.retryAfterMs } : {}
47673
+ failureClass: failure3.failureClass,
47674
+ ...failure3.retryAfterMs ? { retryAfterMs: failure3.retryAfterMs } : {}
47006
47675
  },
47007
- reason: failure2.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 pollSource = createAgentApiWakeHintSource(client);
47053
- const streamSource = options.once ? null : createAgentApiWakeHintStreamSource(client, ctx.env);
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 ? createAgentApiActivitySink(client) : void 0;
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 createAgentApiWakeHintSource(client) {
47885
+ function createDaemonApiWakeHintSource(client) {
47216
47886
  return {
47217
47887
  async fetchWakeHints(input) {
47218
- const query = new URLSearchParams({
47219
- since: String(input.since),
47220
- limit: String(input.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 createAgentApiWakeHintStreamSource(client, env = process.env) {
47238
- if (!client.requestRaw) return null;
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.requestRaw("GET", `/internal/agent-api/wake-hints/stream?${query.toString()}`);
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 createAgentApiActivitySink(client) {
48107
+ function createDaemonApiActivitySink(client) {
47439
48108
  return {
47440
48109
  async forwardActivity(input) {
47441
- const response = await client.request("POST", "/internal/agent-api/activity", input);
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 += '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 `raft message read --channel "#name"` to inspect visible channels. When a public channel is not joined, you can join it with `raft channel join --target "#name"` before sending messages or receiving ordinary channel delivery. Private channels require a human with access to add you. To leave a channel you have joined, use `raft channel leave --target "#name"`. To stop following a thread, use `raft thread unfollow --target "#name:shortid"`.\n';
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
- text += a.description ? ` - @${a.name} (${a.status}) \u2014 ${a.description}
47616
- ` : ` - @${a.name} (${a.status})
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
- text += u.description ? ` - @${u.name} \u2014 ${u.description}
47628
- ` : ` - @${u.name}
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
- text += a.description ? ` - @${a.name} (${a.status}) \u2014 ${a.description}
47649
- ` : ` - @${a.name} (${a.status})
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 = u.role && u.role !== "member" ? ` (${u.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/join.ts
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 infoRes = await createAgentApiClient2(client, agentContext.agentId).server.info();
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 createAgentApiClient2(client, agentContext.agentId).channels.leave({
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 infoRes = await createAgentApiClient2(client, agentContext.agentId).server.info();
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 createAgentApiClient2(client, agentContext.agentId).channels.join({
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 infoRes = await createAgentApiClient2(client, agentContext.agentId).server.info();
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 client.request(
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 createAgentApiClient2(client, agentContext.agentId).server.info();
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/knowledge/get.ts
48972
+ // src/commands/server/update.ts
47951
48973
  init_esm_shims();
47952
- function buildKnowledgeGetPath(agentId, topic, opts) {
47953
- const params = new URLSearchParams();
47954
- params.set("topic", topic);
47955
- if (opts.reason) params.set("reason", opts.reason);
47956
- if (opts.turnId) params.set("turn_id", opts.turnId);
47957
- if (opts.traceId) params.set("trace_id", opts.traceId);
47958
- return `/internal/agent/${encodeURIComponent(agentId)}/knowledge?${params.toString()}`;
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.request(
48007
- "GET",
48008
- buildKnowledgeGetPath(agentContext.agentId, topic, opts)
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.request("GET", "/internal/agent-api/inbox");
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, query),
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: "${query}" (${data.results.length} ${resultLabel})`,
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 = createAgentApiClient2(client, agentContext.agentId);
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 query = [];
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
- if (usesAgentApiSurface) {
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?.messages ?? [];
50260
+ const messages = res.data?.events ?? [];
48940
50261
  allMessages.push(...messages);
48941
- const hasMore = res.data?.has_more === true || res.data?.hasMore === true;
48942
- const hasExplicitHasMore = hasMoreField(res.data);
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
- const seqs = messages.map((m) => m.seq).filter((s) => typeof s === "number" && Number.isInteger(s) && s > 0);
48946
- if (seqs.length === 0) return result(allMessages, { drainedMore: sawHasMore, hasMore, drainComplete });
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 = createAgentApiClient2(client, agentContext.agentId);
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 normalizeSearchOpts(opts) {
49141
- const query = opts.query?.trim();
49142
- if (!query) {
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: "--query is required"
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
- ...opts.channel ? { channel: opts.channel } : {},
49158
- ...opts.sender ? { sender: normalizeMemberHandleRef(opts.sender) } : {},
49159
- ...opts.sort ? { sort: opts.sort } : {},
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.query, res.data)}
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 createAgentApiClient2(client, agentContext.agentId).messages.resolve({ msgId: asMessageId(id) });
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 = createAgentApiClient2(client, agentContext.agentId);
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 readFileSync2 } from "fs";
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 FILENAME_MIME_MAP = {
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 FILENAME_MIME_MAP[ext] || null;
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 (!existsSync(opts.path)) {
50772
+ if (!existsSync2(opts.path)) {
49438
50773
  throw cliError("INVALID_ARG", `--path does not exist: ${opts.path}`);
49439
50774
  }
49440
- const stat2 = statSync(opts.path);
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 = readFileSync2(opts.path);
49457
- const filename = basename(opts.path);
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.requestRaw(
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
- const buffer = Buffer.from(await res.response.arrayBuffer());
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 limitParam = opts.limit && Number.isFinite(Number(opts.limit)) ? `?limit=${Number(opts.limit)}` : "";
49595
- const res = await client.request(
49596
- "GET",
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 reply.`;
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 createAgentApiClient2(client, agentContext.agentId).mentions.executeAction({
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 createAgentApiClient2(client, agentContext.agentId).mentions.pendingActions();
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("warning: this is the registered OAuth callback with an Agent Login request code, not a browser app URL");
50463
- lines.push("next: open it only if the service documents a stateless Agent Login callback; otherwise use the service docs, API, or manifest entry point");
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
- if (env.SLOCK_HOME?.trim()) return path8.resolve(env.SLOCK_HOME);
50695
- return path8.join(env.HOME ?? os4.homedir(), ".slock");
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
- return "manifest execution mode is not local_cli; no local CLI env is required";
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
- return [
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
- "# Slock did not set HOME/XDG exports and did not execute manifest commands."
50851
- ].join("\n");
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/app.ts
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 = normalizeScopes2([...opts.scope ?? [], ...opts.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);