@botiverse/raft-daemon 0.65.0 → 0.66.0-play.20260702142221

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}'`);
@@ -28126,427 +28126,420 @@ var PI_BUILTIN_PROVIDER_MODELS_GENERATED = {
28126
28126
  { id: "deepseek/deepseek-v4-flash", label: "DeepSeek V4 Flash" }
28127
28127
  ],
28128
28128
  "minimax": [
28129
+ { id: "minimax/MiniMax-M3", label: "MiniMax-M3" },
28129
28130
  { id: "minimax/MiniMax-M2.7", label: "MiniMax-M2.7" },
28130
- { id: "minimax/MiniMax-M2.7-highspeed", label: "MiniMax-M2.7-highspeed" },
28131
- { id: "minimax/MiniMax-M3", label: "MiniMax-M3" }
28131
+ { id: "minimax/MiniMax-M2.7-highspeed", label: "MiniMax-M2.7-highspeed" }
28132
28132
  ],
28133
28133
  "minimax-cn": [
28134
+ { id: "minimax-cn/MiniMax-M3", label: "MiniMax-M3" },
28134
28135
  { id: "minimax-cn/MiniMax-M2.7", label: "MiniMax-M2.7" },
28135
- { id: "minimax-cn/MiniMax-M2.7-highspeed", label: "MiniMax-M2.7-highspeed" },
28136
- { id: "minimax-cn/MiniMax-M3", label: "MiniMax-M3" }
28136
+ { id: "minimax-cn/MiniMax-M2.7-highspeed", label: "MiniMax-M2.7-highspeed" }
28137
28137
  ],
28138
28138
  "zai": [
28139
+ { id: "zai/glm-5.2", label: "GLM-5.2" },
28139
28140
  { id: "zai/glm-5.1", label: "GLM-5.1" },
28140
- { id: "zai/glm-4.5-air", label: "GLM-4.5-Air" },
28141
28141
  { id: "zai/glm-4.7", label: "GLM-4.7" },
28142
+ { id: "zai/glm-4.5-air", label: "GLM-4.5-Air" },
28142
28143
  { id: "zai/glm-5-turbo", label: "GLM-5-Turbo" },
28143
- { id: "zai/glm-5.2", label: "GLM-5.2" },
28144
28144
  { id: "zai/glm-5v-turbo", label: "GLM-5V-Turbo" }
28145
28145
  ],
28146
28146
  "zai-coding-cn": [
28147
+ { id: "zai-coding-cn/glm-5.2", label: "GLM-5.2" },
28147
28148
  { id: "zai-coding-cn/glm-5.1", label: "GLM-5.1" },
28148
- { id: "zai-coding-cn/glm-4.5-air", label: "GLM-4.5-Air" },
28149
28149
  { id: "zai-coding-cn/glm-4.7", label: "GLM-4.7" },
28150
+ { id: "zai-coding-cn/glm-4.5-air", label: "GLM-4.5-Air" },
28150
28151
  { id: "zai-coding-cn/glm-5-turbo", label: "GLM-5-Turbo" },
28151
- { id: "zai-coding-cn/glm-5.2", label: "GLM-5.2" },
28152
28152
  { id: "zai-coding-cn/glm-5v-turbo", label: "GLM-5V-Turbo" }
28153
28153
  ],
28154
28154
  "moonshotai": [
28155
- { id: "moonshotai/kimi-k2.6", label: "Kimi K2.6" },
28156
- { id: "moonshotai/kimi-k2-0711-preview", label: "Kimi K2 0711" },
28157
- { id: "moonshotai/kimi-k2-0905-preview", label: "Kimi K2 0905" },
28155
+ { id: "moonshotai/kimi-k2.7-code", label: "Kimi K2.7 Code" },
28158
28156
  { id: "moonshotai/kimi-k2-thinking", label: "Kimi K2 Thinking" },
28157
+ { id: "moonshotai/kimi-k2.7-code-highspeed", label: "Kimi K2.7 Code HighSpeed" },
28159
28158
  { id: "moonshotai/kimi-k2-thinking-turbo", label: "Kimi K2 Thinking Turbo" },
28160
- { id: "moonshotai/kimi-k2-turbo-preview", label: "Kimi K2 Turbo" },
28159
+ { id: "moonshotai/kimi-k2-0905-preview", label: "Kimi K2 0905" },
28160
+ { id: "moonshotai/kimi-k2-0711-preview", label: "Kimi K2 0711" },
28161
+ { id: "moonshotai/kimi-k2.6", label: "Kimi K2.6" },
28161
28162
  { id: "moonshotai/kimi-k2.5", label: "Kimi K2.5" },
28162
- { id: "moonshotai/kimi-k2.7-code", label: "Kimi K2.7 Code" },
28163
- { id: "moonshotai/kimi-k2.7-code-highspeed", label: "Kimi K2.7 Code HighSpeed" }
28163
+ { id: "moonshotai/kimi-k2-turbo-preview", label: "Kimi K2 Turbo" }
28164
28164
  ],
28165
28165
  "moonshotai-cn": [
28166
- { id: "moonshotai-cn/kimi-k2.6", label: "Kimi K2.6" },
28167
- { id: "moonshotai-cn/kimi-k2-0711-preview", label: "Kimi K2 0711" },
28168
- { id: "moonshotai-cn/kimi-k2-0905-preview", label: "Kimi K2 0905" },
28166
+ { id: "moonshotai-cn/kimi-k2.7-code", label: "Kimi K2.7 Code" },
28169
28167
  { id: "moonshotai-cn/kimi-k2-thinking", label: "Kimi K2 Thinking" },
28168
+ { id: "moonshotai-cn/kimi-k2.7-code-highspeed", label: "Kimi K2.7 Code HighSpeed" },
28170
28169
  { id: "moonshotai-cn/kimi-k2-thinking-turbo", label: "Kimi K2 Thinking Turbo" },
28171
- { id: "moonshotai-cn/kimi-k2-turbo-preview", label: "Kimi K2 Turbo" },
28170
+ { id: "moonshotai-cn/kimi-k2-0905-preview", label: "Kimi K2 0905" },
28171
+ { id: "moonshotai-cn/kimi-k2-0711-preview", label: "Kimi K2 0711" },
28172
+ { id: "moonshotai-cn/kimi-k2.6", label: "Kimi K2.6" },
28172
28173
  { id: "moonshotai-cn/kimi-k2.5", label: "Kimi K2.5" },
28173
- { id: "moonshotai-cn/kimi-k2.7-code", label: "Kimi K2.7 Code" },
28174
- { id: "moonshotai-cn/kimi-k2.7-code-highspeed", label: "Kimi K2.7 Code HighSpeed" }
28174
+ { id: "moonshotai-cn/kimi-k2-turbo-preview", label: "Kimi K2 Turbo" }
28175
28175
  ],
28176
28176
  "kimi-coding": [
28177
- { id: "kimi-coding/kimi-for-coding", label: "Kimi For Coding" },
28177
+ { id: "kimi-coding/kimi-k2-thinking", label: "Kimi K2 Thinking" },
28178
28178
  { id: "kimi-coding/k2p7", label: "Kimi K2.7 Code" },
28179
- { id: "kimi-coding/kimi-k2-thinking", label: "Kimi K2 Thinking" }
28179
+ { id: "kimi-coding/kimi-for-coding", label: "Kimi For Coding" }
28180
28180
  ],
28181
28181
  "openrouter": [
28182
- { id: "openrouter/moonshotai/kimi-k2.6", label: "MoonshotAI: Kimi K2.6" },
28183
- { id: "openrouter/ai21/jamba-large-1.7", label: "AI21: Jamba Large 1.7" },
28184
- { id: "openrouter/amazon/nova-2-lite-v1", label: "Amazon: Nova 2 Lite" },
28185
- { id: "openrouter/amazon/nova-lite-v1", label: "Amazon: Nova Lite 1.0" },
28186
- { id: "openrouter/amazon/nova-micro-v1", label: "Amazon: Nova Micro 1.0" },
28187
- { id: "openrouter/amazon/nova-premier-v1", label: "Amazon: Nova Premier 1.0" },
28188
- { id: "openrouter/amazon/nova-pro-v1", label: "Amazon: Nova Pro 1.0" },
28189
- { id: "openrouter/anthropic/claude-3-haiku", label: "Anthropic: Claude 3 Haiku" },
28190
- { id: "openrouter/anthropic/claude-3.5-haiku", label: "Anthropic: Claude 3.5 Haiku" },
28191
28182
  { id: "openrouter/anthropic/claude-fable-5", label: "Anthropic: Claude Fable 5" },
28192
- { id: "openrouter/anthropic/claude-haiku-4.5", label: "Anthropic: Claude Haiku 4.5" },
28193
- { id: "openrouter/anthropic/claude-opus-4", label: "Anthropic: Claude Opus 4" },
28194
- { id: "openrouter/anthropic/claude-opus-4.1", label: "Anthropic: Claude Opus 4.1" },
28195
- { id: "openrouter/anthropic/claude-opus-4.5", label: "Anthropic: Claude Opus 4.5" },
28196
- { id: "openrouter/anthropic/claude-opus-4.6", label: "Anthropic: Claude Opus 4.6" },
28197
- { id: "openrouter/anthropic/claude-opus-4.6-fast", label: "Anthropic: Claude Opus 4.6 (Fast)" },
28198
- { id: "openrouter/anthropic/claude-opus-4.7", label: "Anthropic: Claude Opus 4.7" },
28199
- { id: "openrouter/anthropic/claude-opus-4.7-fast", label: "Anthropic: Claude Opus 4.7 (Fast)" },
28183
+ { id: "openrouter/~anthropic/claude-fable-latest", label: "Anthropic: Claude Fable Latest" },
28200
28184
  { id: "openrouter/anthropic/claude-opus-4.8", label: "Anthropic: Claude Opus 4.8" },
28185
+ { id: "openrouter/anthropic/claude-opus-4.7", label: "Anthropic: Claude Opus 4.7" },
28186
+ { id: "openrouter/anthropic/claude-opus-4.6", label: "Anthropic: Claude Opus 4.6" },
28187
+ { id: "openrouter/anthropic/claude-opus-4.5", label: "Anthropic: Claude Opus 4.5" },
28188
+ { id: "openrouter/anthropic/claude-opus-4.1", label: "Anthropic: Claude Opus 4.1" },
28189
+ { id: "openrouter/anthropic/claude-opus-4", label: "Anthropic: Claude Opus 4" },
28190
+ { id: "openrouter/~anthropic/claude-opus-latest", label: "Anthropic: Claude Opus Latest" },
28201
28191
  { id: "openrouter/anthropic/claude-opus-4.8-fast", label: "Anthropic: Claude Opus 4.8 (Fast)" },
28202
- { id: "openrouter/anthropic/claude-sonnet-4", label: "Anthropic: Claude Sonnet 4" },
28203
- { id: "openrouter/anthropic/claude-sonnet-4.5", label: "Anthropic: Claude Sonnet 4.5" },
28192
+ { id: "openrouter/anthropic/claude-opus-4.7-fast", label: "Anthropic: Claude Opus 4.7 (Fast)" },
28193
+ { id: "openrouter/anthropic/claude-sonnet-5", label: "Anthropic: Claude Sonnet 5" },
28204
28194
  { id: "openrouter/anthropic/claude-sonnet-4.6", label: "Anthropic: Claude Sonnet 4.6" },
28205
- { id: "openrouter/arcee-ai/trinity-large-thinking", label: "Arcee AI: Trinity Large Thinking" },
28206
- { id: "openrouter/arcee-ai/trinity-mini", label: "Arcee AI: Trinity Mini" },
28207
- { id: "openrouter/arcee-ai/virtuoso-large", label: "Arcee AI: Virtuoso Large" },
28208
- { id: "openrouter/auto", label: "Auto" },
28209
- { id: "openrouter/bytedance-seed/seed-1.6", label: "ByteDance Seed: Seed 1.6" },
28210
- { id: "openrouter/bytedance-seed/seed-1.6-flash", label: "ByteDance Seed: Seed 1.6 Flash" },
28211
- { id: "openrouter/bytedance-seed/seed-2.0-lite", label: "ByteDance Seed: Seed-2.0-Lite" },
28212
- { id: "openrouter/bytedance-seed/seed-2.0-mini", label: "ByteDance Seed: Seed-2.0-Mini" },
28213
- { id: "openrouter/cohere/command-r-08-2024", label: "Cohere: Command R (08-2024)" },
28214
- { id: "openrouter/cohere/command-r-plus-08-2024", label: "Cohere: Command R+ (08-2024)" },
28215
- { id: "openrouter/cohere/north-mini-code:free", label: "Cohere: North Mini Code (free)" },
28216
- { id: "openrouter/deepseek/deepseek-chat", label: "DeepSeek: DeepSeek V3" },
28217
- { id: "openrouter/deepseek/deepseek-chat-v3-0324", label: "DeepSeek: DeepSeek V3 0324" },
28218
- { id: "openrouter/deepseek/deepseek-chat-v3.1", label: "DeepSeek: DeepSeek V3.1" },
28219
- { id: "openrouter/deepseek/deepseek-r1", label: "DeepSeek: R1" },
28220
- { id: "openrouter/deepseek/deepseek-r1-0528", label: "DeepSeek: R1 0528" },
28221
- { id: "openrouter/deepseek/deepseek-v3.1-terminus", label: "DeepSeek: DeepSeek V3.1 Terminus" },
28222
- { id: "openrouter/deepseek/deepseek-v3.2", label: "DeepSeek: DeepSeek V3.2" },
28223
- { id: "openrouter/deepseek/deepseek-v3.2-exp", label: "DeepSeek: DeepSeek V3.2 Exp" },
28224
- { id: "openrouter/deepseek/deepseek-v4-flash", label: "DeepSeek: DeepSeek V4 Flash" },
28225
- { id: "openrouter/deepseek/deepseek-v4-pro", label: "DeepSeek: DeepSeek V4 Pro" },
28226
- { id: "openrouter/essentialai/rnj-1-instruct", label: "EssentialAI: Rnj 1 Instruct" },
28227
- { id: "openrouter/google/gemini-2.5-flash", label: "Google: Gemini 2.5 Flash" },
28228
- { id: "openrouter/google/gemini-2.5-flash-lite", label: "Google: Gemini 2.5 Flash Lite" },
28229
- { id: "openrouter/google/gemini-2.5-flash-lite-preview-09-2025", label: "Google: Gemini 2.5 Flash Lite Preview 09-2025" },
28230
- { id: "openrouter/google/gemini-2.5-pro", label: "Google: Gemini 2.5 Pro" },
28195
+ { id: "openrouter/anthropic/claude-sonnet-4.5", label: "Anthropic: Claude Sonnet 4.5" },
28196
+ { id: "openrouter/anthropic/claude-sonnet-4", label: "Anthropic: Claude Sonnet 4" },
28197
+ { id: "openrouter/~anthropic/claude-sonnet-latest", label: "Anthropic Claude Sonnet Latest" },
28198
+ { id: "openrouter/anthropic/claude-haiku-4.5", label: "Anthropic: Claude Haiku 4.5" },
28199
+ { id: "openrouter/anthropic/claude-3-haiku", label: "Anthropic: Claude 3 Haiku" },
28200
+ { id: "openrouter/~anthropic/claude-haiku-latest", label: "Anthropic Claude Haiku Latest" },
28201
+ { id: "openrouter/openai/gpt-5.1-codex-max", label: "OpenAI: GPT-5.1-Codex-Max" },
28202
+ { id: "openrouter/kwaipilot/kat-coder-pro-v2", label: "Kwaipilot: KAT-Coder-Pro V2" },
28203
+ { id: "openrouter/qwen/qwen3-max-thinking", label: "Qwen: Qwen3 Max Thinking" },
28204
+ { id: "openrouter/nvidia/nemotron-3-ultra-550b-a55b", label: "NVIDIA: Nemotron 3 Ultra" },
28231
28205
  { id: "openrouter/google/gemini-2.5-pro-preview", label: "Google: Gemini 2.5 Pro Preview 06-05" },
28232
28206
  { id: "openrouter/google/gemini-2.5-pro-preview-05-06", label: "Google: Gemini 2.5 Pro Preview 05-06" },
28233
- { id: "openrouter/google/gemini-3-flash-preview", label: "Google: Gemini 3 Flash Preview" },
28234
- { id: "openrouter/google/gemini-3-pro-image", label: "Google: Nano Banana Pro (Gemini 3 Pro Image)" },
28235
- { id: "openrouter/google/gemini-3.1-flash-lite", label: "Google: Gemini 3.1 Flash Lite" },
28236
- { id: "openrouter/google/gemini-3.1-flash-lite-preview", label: "Google: Gemini 3.1 Flash Lite Preview" },
28207
+ { id: "openrouter/openai/gpt-5.5-pro", label: "OpenAI: GPT-5.5 Pro" },
28208
+ { id: "openrouter/openai/gpt-5.4-pro", label: "OpenAI: GPT-5.4 Pro" },
28209
+ { id: "openrouter/openai/gpt-5.2-pro", label: "OpenAI: GPT-5.2 Pro" },
28210
+ { id: "openrouter/openai/gpt-5-pro", label: "OpenAI: GPT-5 Pro" },
28211
+ { id: "openrouter/deepseek/deepseek-v4-pro", label: "DeepSeek: DeepSeek V4 Pro" },
28212
+ { id: "openrouter/qwen/qwen3.7-max", label: "Qwen: Qwen3.7 Max" },
28213
+ { id: "openrouter/qwen/qwen3.6-max-preview", label: "Qwen: Qwen3.6 Max Preview" },
28237
28214
  { id: "openrouter/google/gemini-3.1-pro-preview", label: "Google: Gemini 3.1 Pro Preview" },
28238
28215
  { id: "openrouter/google/gemini-3.1-pro-preview-customtools", label: "Google: Gemini 3.1 Pro Preview Custom Tools" },
28239
- { id: "openrouter/google/gemini-3.5-flash", label: "Google: Gemini 3.5 Flash" },
28240
- { id: "openrouter/google/gemma-3-12b-it", label: "Google: Gemma 3 12B" },
28216
+ { id: "openrouter/openai/o3-pro", label: "OpenAI: o3 Pro" },
28217
+ { id: "openrouter/qwen/qwen3-max", label: "Qwen: Qwen3 Max" },
28218
+ { id: "openrouter/upstage/solar-pro-3", label: "Upstage: Solar Pro 3" },
28219
+ { id: "openrouter/google/gemini-2.5-pro", label: "Google: Gemini 2.5 Pro" },
28220
+ { id: "openrouter/xiaomi/mimo-v2.5-pro", label: "Xiaomi: MiMo-V2.5-Pro" },
28221
+ { id: "openrouter/amazon/nova-premier-v1", label: "Amazon: Nova Premier 1.0" },
28222
+ { id: "openrouter/amazon/nova-pro-v1", label: "Amazon: Nova Pro 1.0" },
28223
+ { id: "openrouter/~google/gemini-pro-latest", label: "Google Gemini Pro Latest" },
28224
+ { id: "openrouter/sakana/fugu-ultra", label: "Sakana: Fugu Ultra" },
28225
+ { id: "openrouter/arcee-ai/trinity-large-thinking", label: "Arcee AI: Trinity Large Thinking" },
28226
+ { id: "openrouter/qwen/qwen3-coder", label: "Qwen: Qwen3 Coder 480B A35B" },
28227
+ { id: "openrouter/qwen/qwen3-coder-30b-a3b-instruct", label: "Qwen: Qwen3 Coder 30B A3B Instruct" },
28228
+ { id: "openrouter/openai/gpt-5.3-codex", label: "OpenAI: GPT-5.3-Codex" },
28229
+ { id: "openrouter/openai/gpt-5.2-codex", label: "OpenAI: GPT-5.2-Codex" },
28230
+ { id: "openrouter/openai/gpt-5.1-codex", label: "OpenAI: GPT-5.1-Codex" },
28231
+ { id: "openrouter/openai/gpt-5-codex", label: "OpenAI: GPT-5 Codex" },
28232
+ { id: "openrouter/qwen/qwen3-coder-next", label: "Qwen: Qwen3 Coder Next" },
28233
+ { id: "openrouter/qwen/qwen3-coder-plus", label: "Qwen: Qwen3 Coder Plus" },
28234
+ { id: "openrouter/moonshotai/kimi-k2.7-code", label: "MoonshotAI: Kimi K2.7 Code" },
28235
+ { id: "openrouter/qwen/qwen3-235b-a22b-thinking-2507", label: "Qwen: Qwen3 235B A22B Thinking 2507" },
28236
+ { id: "openrouter/qwen/qwen3-30b-a3b-thinking-2507", label: "Qwen: Qwen3 30B A3B Thinking 2507" },
28237
+ { id: "openrouter/qwen/qwen-plus-2025-07-28:thinking", label: "Qwen: Qwen Plus 0728 (thinking)" },
28238
+ { id: "openrouter/qwen/qwen3-vl-235b-a22b-thinking", label: "Qwen: Qwen3 VL 235B A22B Thinking" },
28239
+ { id: "openrouter/qwen/qwen3-next-80b-a3b-thinking", label: "Qwen: Qwen3 Next 80B A3B Thinking" },
28240
+ { id: "openrouter/qwen/qwen3-vl-30b-a3b-thinking", label: "Qwen: Qwen3 VL 30B A3B Thinking" },
28241
+ { id: "openrouter/qwen/qwen3-vl-8b-thinking", label: "Qwen: Qwen3 VL 8B Thinking" },
28242
+ { id: "openrouter/google/gemini-3-pro-image", label: "Google: Nano Banana Pro (Gemini 3 Pro Image)" },
28243
+ { id: "openrouter/moonshotai/kimi-k2-thinking", label: "MoonshotAI: Kimi K2 Thinking" },
28244
+ { id: "openrouter/qwen/qwen3-coder-flash", label: "Qwen: Qwen3 Coder Flash" },
28245
+ { id: "openrouter/mistralai/mistral-large-2512", label: "Mistral: Mistral Large 3 2512" },
28246
+ { id: "openrouter/mistralai/mistral-large-2407", label: "Mistral Large 2407" },
28247
+ { id: "openrouter/nvidia/nemotron-3-super-120b-a12b", label: "NVIDIA: Nemotron 3 Super" },
28248
+ { id: "openrouter/nvidia/llama-3.3-nemotron-super-49b-v1.5", label: "NVIDIA: Llama 3.3 Nemotron Super 49B V1.5" },
28249
+ { id: "openrouter/ai21/jamba-large-1.7", label: "AI21: Jamba Large 1.7" },
28250
+ { id: "openrouter/arcee-ai/virtuoso-large", label: "Arcee AI: Virtuoso Large" },
28251
+ { id: "openrouter/mistralai/mistral-large", label: "Mistral Large" },
28252
+ { id: "openrouter/nvidia/nemotron-3-ultra-550b-a55b:free", label: "NVIDIA: Nemotron 3 Ultra (free)" },
28253
+ { id: "openrouter/openai/gpt-5.1-codex-mini", label: "OpenAI: GPT-5.1-Codex-Mini" },
28254
+ { id: "openrouter/qwen/qwen3.5-plus-20260420", label: "Qwen: Qwen3.5 Plus 2026-04-20" },
28255
+ { id: "openrouter/mistralai/mistral-small-2603", label: "Mistral: Mistral Small 4" },
28256
+ { id: "openrouter/mistralai/devstral-2512", label: "Mistral: Devstral 2 2512" },
28257
+ { id: "openrouter/mistralai/ministral-14b-2512", label: "Mistral: Ministral 3 14B 2512" },
28258
+ { id: "openrouter/mistralai/ministral-3b-2512", label: "Mistral: Ministral 3 3B 2512" },
28259
+ { id: "openrouter/mistralai/ministral-8b-2512", label: "Mistral: Ministral 3 8B 2512" },
28260
+ { id: "openrouter/mistralai/codestral-2508", label: "Mistral: Codestral 2508" },
28261
+ { id: "openrouter/mistralai/voxtral-small-24b-2507", label: "Mistral: Voxtral Small 24B 2507" },
28262
+ { id: "openrouter/qwen/qwen3-235b-a22b-2507", label: "Qwen: Qwen3 235B A22B Instruct 2507" },
28263
+ { id: "openrouter/qwen/qwen3-30b-a3b-instruct-2507", label: "Qwen: Qwen3 30B A3B Instruct 2507" },
28264
+ { id: "openrouter/qwen/qwen3.5-plus-02-15", label: "Qwen: Qwen3.5 Plus 2026-02-15" },
28265
+ { id: "openrouter/qwen/qwen-plus-2025-07-28", label: "Qwen: Qwen Plus 0728" },
28266
+ { id: "openrouter/openai/gpt-4o-2024-11-20", label: "OpenAI: GPT-4o (2024-11-20)" },
28267
+ { id: "openrouter/openai/gpt-4o-2024-08-06", label: "OpenAI: GPT-4o (2024-08-06)" },
28268
+ { id: "openrouter/openai/gpt-4o-2024-05-13", label: "OpenAI: GPT-4o (2024-05-13)" },
28269
+ { id: "openrouter/moonshotai/kimi-k2-0905", label: "MoonshotAI: Kimi K2 0905" },
28270
+ { id: "openrouter/moonshotai/kimi-k2", label: "MoonshotAI: Kimi K2 0711" },
28271
+ { id: "openrouter/deepseek/deepseek-r1-0528", label: "DeepSeek: R1 0528" },
28272
+ { id: "openrouter/qwen/qwen3-coder:free", label: "Qwen: Qwen3 Coder 480B A35B (free)" },
28273
+ { id: "openrouter/qwen/qwen3.5-397b-a17b", label: "Qwen: Qwen3.5 397B A17B" },
28274
+ { id: "openrouter/deepseek/deepseek-chat-v3-0324", label: "DeepSeek: DeepSeek V3 0324" },
28275
+ { id: "openrouter/qwen/qwen3-235b-a22b", label: "Qwen: Qwen3 235B A22B" },
28276
+ { id: "openrouter/qwen/qwen3-vl-235b-a22b-instruct", label: "Qwen: Qwen3 VL 235B A22B Instruct" },
28277
+ { id: "openrouter/openai/gpt-oss-120b", label: "OpenAI: gpt-oss-120b" },
28278
+ { id: "openrouter/qwen/qwen3-next-80b-a3b-instruct", label: "Qwen: Qwen3 Next 80B A3B Instruct" },
28279
+ { id: "openrouter/qwen/qwen-2.5-72b-instruct", label: "Qwen2.5 72B Instruct" },
28280
+ { id: "openrouter/meta-llama/llama-3.1-70b-instruct", label: "Meta: Llama 3.1 70B Instruct" },
28281
+ { id: "openrouter/meta-llama/llama-3.3-70b-instruct", label: "Meta: Llama 3.3 70B Instruct" },
28282
+ { id: "openrouter/sao10k/l3.1-euryale-70b", label: "Sao10K: Llama 3.1 Euryale 70B v2.2" },
28283
+ { id: "openrouter/qwen/qwen3.6-35b-a3b", label: "Qwen: Qwen3.6 35B A3B" },
28284
+ { id: "openrouter/qwen/qwen3-32b", label: "Qwen: Qwen3 32B" },
28285
+ { id: "openrouter/qwen/qwen3-vl-32b-instruct", label: "Qwen: Qwen3 VL 32B Instruct" },
28286
+ { id: "openrouter/google/gemma-4-31b-it", label: "Google: Gemma 4 31B" },
28287
+ { id: "openrouter/qwen/qwen3-30b-a3b", label: "Qwen: Qwen3 30B A3B" },
28288
+ { id: "openrouter/qwen/qwen3-vl-30b-a3b-instruct", label: "Qwen: Qwen3 VL 30B A3B Instruct" },
28289
+ { id: "openrouter/cohere/command-r-08-2024", label: "Cohere: Command R (08-2024)" },
28290
+ { id: "openrouter/cohere/command-r-plus-08-2024", label: "Cohere: Command R+ (08-2024)" },
28241
28291
  { id: "openrouter/google/gemma-3-27b-it", label: "Google: Gemma 3 27B" },
28292
+ { id: "openrouter/qwen/qwen3.6-27b", label: "Qwen: Qwen3.6 27B" },
28242
28293
  { id: "openrouter/google/gemma-4-26b-a4b-it", label: "Google: Gemma 4 26B A4B " },
28243
- { id: "openrouter/google/gemma-4-26b-a4b-it:free", label: "Google: Gemma 4 26B A4B (free)" },
28244
- { id: "openrouter/google/gemma-4-31b-it", label: "Google: Gemma 4 31B" },
28245
- { id: "openrouter/google/gemma-4-31b-it:free", label: "Google: Gemma 4 31B (free)" },
28294
+ { id: "openrouter/mistralai/mistral-small-3.2-24b-instruct", label: "Mistral: Mistral Small 3.2 24B" },
28295
+ { id: "openrouter/mistralai/mixtral-8x22b-instruct", label: "Mistral: Mixtral 8x22B Instruct" },
28296
+ { id: "openrouter/openai/gpt-oss-20b", label: "OpenAI: gpt-oss-20b" },
28297
+ { id: "openrouter/openai/gpt-oss-safeguard-20b", label: "OpenAI: gpt-oss-safeguard-20b" },
28298
+ { id: "openrouter/qwen/qwen3-14b", label: "Qwen: Qwen3 14B" },
28299
+ { id: "openrouter/google/gemma-3-12b-it", label: "Google: Gemma 3 12B" },
28300
+ { id: "openrouter/thedrummer/unslopnemo-12b", label: "TheDrummer: UnslopNemo 12B" },
28301
+ { id: "openrouter/qwen/qwen3.5-122b-a10b", label: "Qwen: Qwen3.5-122B-A10B" },
28246
28302
  { id: "openrouter/ibm-granite/granite-4.1-8b", label: "IBM: Granite 4.1 8B" },
28247
- { id: "openrouter/inception/mercury-2", label: "Inception: Mercury 2" },
28248
- { id: "openrouter/inclusionai/ling-2.6-1t", label: "inclusionAI: Ling-2.6-1T" },
28249
- { id: "openrouter/inclusionai/ling-2.6-flash", label: "inclusionAI: Ling-2.6-flash" },
28250
- { id: "openrouter/inclusionai/ring-2.6-1t", label: "inclusionAI: Ring-2.6-1T" },
28251
- { id: "openrouter/kwaipilot/kat-coder-pro-v2", label: "Kwaipilot: KAT-Coder-Pro V2" },
28252
- { id: "openrouter/liquid/lfm-2.5-1.2b-thinking:free", label: "LiquidAI: LFM2.5-1.2B-Thinking (free)" },
28253
- { id: "openrouter/meta-llama/llama-3.1-70b-instruct", label: "Meta: Llama 3.1 70B Instruct" },
28254
28303
  { id: "openrouter/meta-llama/llama-3.1-8b-instruct", label: "Meta: Llama 3.1 8B Instruct" },
28255
- { id: "openrouter/meta-llama/llama-3.3-70b-instruct", label: "Meta: Llama 3.3 70B Instruct" },
28256
- { id: "openrouter/meta-llama/llama-3.3-70b-instruct:free", label: "Meta: Llama 3.3 70B Instruct (free)" },
28304
+ { id: "openrouter/qwen/qwen3-8b", label: "Qwen: Qwen3 8B" },
28305
+ { id: "openrouter/qwen/qwen3-vl-8b-instruct", label: "Qwen: Qwen3 VL 8B Instruct" },
28306
+ { id: "openrouter/qwen/qwen-2.5-7b-instruct", label: "Qwen: Qwen2.5 7B Instruct" },
28307
+ { id: "openrouter/openai/gpt-5.5", label: "OpenAI: GPT-5.5" },
28308
+ { id: "openrouter/openai/gpt-5.4", label: "OpenAI: GPT-5.4" },
28309
+ { id: "openrouter/openai/gpt-5.3-chat", label: "OpenAI: GPT-5.3 Chat" },
28310
+ { id: "openrouter/openai/gpt-5.2", label: "OpenAI: GPT-5.2" },
28311
+ { id: "openrouter/openai/gpt-5.2-chat", label: "OpenAI: GPT-5.2 Chat" },
28312
+ { id: "openrouter/z-ai/glm-5.2", label: "Z.ai: GLM 5.2" },
28313
+ { id: "openrouter/openai/gpt-5.1", label: "OpenAI: GPT-5.1" },
28314
+ { id: "openrouter/openai/gpt-5.1-chat", label: "OpenAI: GPT-5.1 Chat" },
28315
+ { id: "openrouter/z-ai/glm-5.1", label: "Z.ai: GLM 5.1" },
28316
+ { id: "openrouter/openai/gpt-5", label: "OpenAI: GPT-5" },
28317
+ { id: "openrouter/z-ai/glm-5", label: "Z.ai: GLM 5" },
28318
+ { id: "openrouter/x-ai/grok-4.20", label: "xAI: Grok 4.20" },
28319
+ { id: "openrouter/z-ai/glm-4.7", label: "Z.ai: GLM 4.7" },
28320
+ { id: "openrouter/z-ai/glm-4.6", label: "Z.ai: GLM 4.6" },
28321
+ { id: "openrouter/z-ai/glm-4.6v", label: "Z.ai: GLM 4.6V" },
28322
+ { id: "openrouter/z-ai/glm-4.5", label: "Z.ai: GLM 4.5" },
28323
+ { id: "openrouter/z-ai/glm-4.5-air", label: "Z.ai: GLM 4.5 Air" },
28324
+ { id: "openrouter/z-ai/glm-4.5v", label: "Z.ai: GLM 4.5V" },
28325
+ { id: "openrouter/x-ai/grok-4.3", label: "xAI: Grok 4.3" },
28326
+ { id: "openrouter/openai/gpt-4.1", label: "OpenAI: GPT-4.1" },
28257
28327
  { id: "openrouter/meta-llama/llama-4-maverick", label: "Meta: Llama 4 Maverick" },
28258
28328
  { id: "openrouter/meta-llama/llama-4-scout", label: "Meta: Llama 4 Scout" },
28259
- { id: "openrouter/minimax/minimax-m1", label: "MiniMax: MiniMax M1" },
28260
- { id: "openrouter/minimax/minimax-m2", label: "MiniMax: MiniMax M2" },
28261
- { id: "openrouter/minimax/minimax-m2.1", label: "MiniMax: MiniMax M2.1" },
28262
- { id: "openrouter/minimax/minimax-m2.5", label: "MiniMax: MiniMax M2.5" },
28263
- { id: "openrouter/minimax/minimax-m2.7", label: "MiniMax: MiniMax M2.7" },
28264
- { id: "openrouter/minimax/minimax-m3", label: "MiniMax: MiniMax M3" },
28265
- { id: "openrouter/mistralai/codestral-2508", label: "Mistral: Codestral 2508" },
28266
- { id: "openrouter/mistralai/devstral-2512", label: "Mistral: Devstral 2 2512" },
28267
- { id: "openrouter/mistralai/ministral-14b-2512", label: "Mistral: Ministral 3 14B 2512" },
28268
- { id: "openrouter/mistralai/ministral-3b-2512", label: "Mistral: Ministral 3 3B 2512" },
28269
- { id: "openrouter/mistralai/ministral-8b-2512", label: "Mistral: Ministral 3 8B 2512" },
28270
- { id: "openrouter/mistralai/mistral-large", label: "Mistral Large" },
28271
- { id: "openrouter/mistralai/mistral-large-2407", label: "Mistral Large 2407" },
28272
- { id: "openrouter/mistralai/mistral-large-2512", label: "Mistral: Mistral Large 3 2512" },
28273
- { id: "openrouter/mistralai/mistral-medium-3", label: "Mistral: Mistral Medium 3" },
28329
+ { id: "openrouter/openai/gpt-4", label: "OpenAI: GPT-4" },
28330
+ { id: "openrouter/openai/gpt-4o", label: "OpenAI: GPT-4o" },
28331
+ { id: "openrouter/qwen/qwen3.7-plus", label: "Qwen: Qwen3.7 Plus" },
28332
+ { id: "openrouter/qwen/qwen3.6-plus", label: "Qwen: Qwen3.6 Plus" },
28333
+ { id: "openrouter/qwen/qwen3.5-35b-a3b", label: "Qwen: Qwen3.5-35B-A3B" },
28334
+ { id: "openrouter/qwen/qwen3.5-27b", label: "Qwen: Qwen3.5-27B" },
28335
+ { id: "openrouter/qwen/qwen3.5-9b", label: "Qwen: Qwen3.5-9B" },
28274
28336
  { id: "openrouter/mistralai/mistral-medium-3-5", label: "Mistral: Mistral Medium 3.5" },
28337
+ { id: "openrouter/deepseek/deepseek-v3.2", label: "DeepSeek: DeepSeek V3.2" },
28338
+ { id: "openrouter/deepseek/deepseek-v3.2-exp", label: "DeepSeek: DeepSeek V3.2 Exp" },
28339
+ { id: "openrouter/deepseek/deepseek-chat-v3.1", label: "DeepSeek: DeepSeek V3.1" },
28340
+ { id: "openrouter/deepseek/deepseek-v3.1-terminus", label: "DeepSeek: DeepSeek V3.1 Terminus" },
28275
28341
  { id: "openrouter/mistralai/mistral-medium-3.1", label: "Mistral: Mistral Medium 3.1" },
28342
+ { id: "openrouter/deepseek/deepseek-chat", label: "DeepSeek: DeepSeek V3" },
28343
+ { id: "openrouter/minimax/minimax-m3", label: "MiniMax: MiniMax M3" },
28344
+ { id: "openrouter/mistralai/mistral-medium-3", label: "Mistral: Mistral Medium 3" },
28345
+ { id: "openrouter/openai/o3", label: "OpenAI: o3" },
28346
+ { id: "openrouter/openai/o3-deep-research", label: "OpenAI: o3 Deep Research" },
28347
+ { id: "openrouter/tencent/hy3-preview", label: "Tencent: Hy3 preview" },
28348
+ { id: "openrouter/minimax/minimax-m2.7", label: "MiniMax: MiniMax M2.7" },
28349
+ { id: "openrouter/inclusionai/ling-2.6-1t", label: "inclusionAI: Ling-2.6-1T" },
28350
+ { id: "openrouter/inclusionai/ring-2.6-1t", label: "inclusionAI: Ring-2.6-1T" },
28351
+ { id: "openrouter/moonshotai/kimi-k2.6", label: "MoonshotAI: Kimi K2.6" },
28352
+ { id: "openrouter/minimax/minimax-m2.5", label: "MiniMax: MiniMax M2.5" },
28353
+ { id: "openrouter/moonshotai/kimi-k2.5", label: "MoonshotAI: Kimi K2.5" },
28354
+ { id: "openrouter/xiaomi/mimo-v2.5", label: "Xiaomi: MiMo-V2.5" },
28355
+ { id: "openrouter/minimax/minimax-m2.1", label: "MiniMax: MiniMax M2.1" },
28356
+ { id: "openrouter/inception/mercury-2", label: "Inception: Mercury 2" },
28357
+ { id: "openrouter/minimax/minimax-m2", label: "MiniMax: MiniMax M2" },
28358
+ { id: "openrouter/poolside/laguna-xs.2", label: "Poolside: Laguna XS.2" },
28359
+ { id: "openrouter/bytedance-seed/seed-1.6", label: "ByteDance Seed: Seed 1.6" },
28360
+ { id: "openrouter/deepseek/deepseek-r1", label: "DeepSeek: R1" },
28361
+ { id: "openrouter/minimax/minimax-m1", label: "MiniMax: MiniMax M1" },
28362
+ { id: "openrouter/openai/o1", label: "OpenAI: o1" },
28363
+ { id: "openrouter/poolside/laguna-m.1", label: "Poolside: Laguna M.1" },
28364
+ { id: "openrouter/x-ai/grok-build-0.1", label: "xAI: Grok Build 0.1" },
28365
+ { id: "openrouter/auto", label: "Auto" },
28366
+ { id: "openrouter/openrouter/auto", label: "Auto Router" },
28276
28367
  { id: "openrouter/mistralai/mistral-nemo", label: "Mistral: Mistral Nemo" },
28277
28368
  { id: "openrouter/mistralai/mistral-saba", label: "Mistral: Saba" },
28278
- { id: "openrouter/mistralai/mistral-small-2603", label: "Mistral: Mistral Small 4" },
28279
- { id: "openrouter/mistralai/mistral-small-3.2-24b-instruct", label: "Mistral: Mistral Small 3.2 24B" },
28280
- { id: "openrouter/mistralai/mixtral-8x22b-instruct", label: "Mistral: Mixtral 8x22B Instruct" },
28281
- { id: "openrouter/mistralai/voxtral-small-24b-2507", label: "Mistral: Voxtral Small 24B 2507" },
28282
- { id: "openrouter/moonshotai/kimi-k2", label: "MoonshotAI: Kimi K2 0711" },
28283
- { id: "openrouter/moonshotai/kimi-k2-0905", label: "MoonshotAI: Kimi K2 0905" },
28284
- { id: "openrouter/moonshotai/kimi-k2-thinking", label: "MoonshotAI: Kimi K2 Thinking" },
28285
- { id: "openrouter/moonshotai/kimi-k2.5", label: "MoonshotAI: Kimi K2.5" },
28286
- { id: "openrouter/moonshotai/kimi-k2.7-code", label: "MoonshotAI: Kimi K2.7 Code" },
28287
- { id: "openrouter/nex-agi/nex-n2-pro:free", label: "Nex AGI: Nex-N2-Pro (free)" },
28288
- { id: "openrouter/nvidia/llama-3.3-nemotron-super-49b-v1.5", label: "NVIDIA: Llama 3.3 Nemotron Super 49B V1.5" },
28289
- { id: "openrouter/nvidia/nemotron-3-nano-30b-a3b", label: "NVIDIA: Nemotron 3 Nano 30B A3B" },
28290
- { id: "openrouter/nvidia/nemotron-3-nano-30b-a3b:free", label: "NVIDIA: Nemotron 3 Nano 30B A3B (free)" },
28291
- { id: "openrouter/nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free", label: "NVIDIA: Nemotron 3 Nano Omni (free)" },
28292
- { id: "openrouter/nvidia/nemotron-3-super-120b-a12b", label: "NVIDIA: Nemotron 3 Super" },
28293
- { id: "openrouter/nvidia/nemotron-3-super-120b-a12b:free", label: "NVIDIA: Nemotron 3 Super (free)" },
28294
- { id: "openrouter/nvidia/nemotron-3-ultra-550b-a55b", label: "NVIDIA: Nemotron 3 Ultra" },
28295
- { id: "openrouter/nvidia/nemotron-3-ultra-550b-a55b:free", label: "NVIDIA: Nemotron 3 Ultra (free)" },
28296
- { id: "openrouter/nvidia/nemotron-nano-12b-v2-vl:free", label: "NVIDIA: Nemotron Nano 12B 2 VL (free)" },
28297
- { id: "openrouter/nvidia/nemotron-nano-9b-v2:free", label: "NVIDIA: Nemotron Nano 9B V2 (free)" },
28298
- { id: "openrouter/openai/gpt-3.5-turbo", label: "OpenAI: GPT-3.5 Turbo" },
28369
+ { id: "openrouter/~moonshotai/kimi-latest", label: "MoonshotAI Kimi Latest" },
28370
+ { id: "openrouter/~openai/gpt-latest", label: "OpenAI GPT Latest" },
28371
+ { id: "openrouter/openai/gpt-audio", label: "OpenAI: GPT Audio" },
28372
+ { id: "openrouter/openai/gpt-chat-latest", label: "OpenAI: GPT Chat Latest" },
28373
+ { id: "openrouter/openrouter/fusion", label: "OpenRouter: Fusion" },
28374
+ { id: "openrouter/qwen/qwen-plus", label: "Qwen: Qwen-Plus" },
28375
+ { id: "openrouter/rekaai/reka-edge", label: "Reka Edge" },
28376
+ { id: "openrouter/relace/relace-search", label: "Relace: Relace Search" },
28377
+ { id: "openrouter/liquid/lfm-2.5-1.2b-thinking:free", label: "LiquidAI: LFM2.5-1.2B-Thinking (free)" },
28299
28378
  { id: "openrouter/openai/gpt-3.5-turbo-0613", label: "OpenAI: GPT-3.5 Turbo (older v0613)" },
28300
28379
  { id: "openrouter/openai/gpt-3.5-turbo-16k", label: "OpenAI: GPT-3.5 Turbo 16k" },
28301
- { id: "openrouter/openai/gpt-4", label: "OpenAI: GPT-4" },
28380
+ { id: "openrouter/z-ai/glm-5-turbo", label: "Z.ai: GLM 5 Turbo" },
28381
+ { id: "openrouter/z-ai/glm-5v-turbo", label: "Z.ai: GLM 5V Turbo" },
28382
+ { id: "openrouter/z-ai/glm-4.7-flash", label: "Z.ai: GLM 4.7 Flash" },
28383
+ { id: "openrouter/deepseek/deepseek-v4-flash", label: "DeepSeek: DeepSeek V4 Flash" },
28302
28384
  { id: "openrouter/openai/gpt-4-turbo", label: "OpenAI: GPT-4 Turbo" },
28303
28385
  { id: "openrouter/openai/gpt-4-turbo-preview", label: "OpenAI: GPT-4 Turbo Preview" },
28304
- { id: "openrouter/openai/gpt-4.1", label: "OpenAI: GPT-4.1" },
28305
- { id: "openrouter/openai/gpt-4.1-mini", label: "OpenAI: GPT-4.1 Mini" },
28306
- { id: "openrouter/openai/gpt-4.1-nano", label: "OpenAI: GPT-4.1 Nano" },
28307
- { id: "openrouter/openai/gpt-4o", label: "OpenAI: GPT-4o" },
28308
- { id: "openrouter/openai/gpt-4o-2024-05-13", label: "OpenAI: GPT-4o (2024-05-13)" },
28309
- { id: "openrouter/openai/gpt-4o-2024-08-06", label: "OpenAI: GPT-4o (2024-08-06)" },
28310
- { id: "openrouter/openai/gpt-4o-2024-11-20", label: "OpenAI: GPT-4o (2024-11-20)" },
28311
- { id: "openrouter/openai/gpt-4o-mini", label: "OpenAI: GPT-4o-mini" },
28386
+ { id: "openrouter/stepfun/step-3.7-flash", label: "StepFun: Step 3.7 Flash" },
28387
+ { id: "openrouter/qwen/qwen3.6-flash", label: "Qwen: Qwen3.6 Flash" },
28388
+ { id: "openrouter/google/gemini-3.5-flash", label: "Google: Gemini 3.5 Flash" },
28389
+ { id: "openrouter/openai/gpt-3.5-turbo", label: "OpenAI: GPT-3.5 Turbo" },
28390
+ { id: "openrouter/qwen/qwen3.5-flash-02-23", label: "Qwen: Qwen3.5-Flash" },
28391
+ { id: "openrouter/stepfun/step-3.5-flash", label: "StepFun: Step 3.5 Flash" },
28392
+ { id: "openrouter/google/gemini-3-flash-preview", label: "Google: Gemini 3 Flash Preview" },
28393
+ { id: "openrouter/inclusionai/ling-2.6-flash", label: "inclusionAI: Ling-2.6-flash" },
28394
+ { id: "openrouter/google/gemini-2.5-flash", label: "Google: Gemini 2.5 Flash" },
28395
+ { id: "openrouter/bytedance-seed/seed-1.6-flash", label: "ByteDance Seed: Seed 1.6 Flash" },
28396
+ { id: "openrouter/~google/gemini-flash-latest", label: "Google Gemini Flash Latest" },
28397
+ { id: "openrouter/nvidia/nemotron-3-super-120b-a12b:free", label: "NVIDIA: Nemotron 3 Super (free)" },
28312
28398
  { id: "openrouter/openai/gpt-4o-mini-2024-07-18", label: "OpenAI: GPT-4o-mini (2024-07-18)" },
28313
- { id: "openrouter/openai/gpt-5", label: "OpenAI: GPT-5" },
28314
- { id: "openrouter/openai/gpt-5-codex", label: "OpenAI: GPT-5 Codex" },
28315
- { id: "openrouter/openai/gpt-5-mini", label: "OpenAI: GPT-5 Mini" },
28316
- { id: "openrouter/openai/gpt-5-nano", label: "OpenAI: GPT-5 Nano" },
28317
- { id: "openrouter/openai/gpt-5-pro", label: "OpenAI: GPT-5 Pro" },
28318
- { id: "openrouter/openai/gpt-5.1", label: "OpenAI: GPT-5.1" },
28319
- { id: "openrouter/openai/gpt-5.1-chat", label: "OpenAI: GPT-5.1 Chat" },
28320
- { id: "openrouter/openai/gpt-5.1-codex", label: "OpenAI: GPT-5.1-Codex" },
28321
- { id: "openrouter/openai/gpt-5.1-codex-max", label: "OpenAI: GPT-5.1-Codex-Max" },
28322
- { id: "openrouter/openai/gpt-5.1-codex-mini", label: "OpenAI: GPT-5.1-Codex-Mini" },
28323
- { id: "openrouter/openai/gpt-5.2", label: "OpenAI: GPT-5.2" },
28324
- { id: "openrouter/openai/gpt-5.2-chat", label: "OpenAI: GPT-5.2 Chat" },
28325
- { id: "openrouter/openai/gpt-5.2-codex", label: "OpenAI: GPT-5.2-Codex" },
28326
- { id: "openrouter/openai/gpt-5.2-pro", label: "OpenAI: GPT-5.2 Pro" },
28327
- { id: "openrouter/openai/gpt-5.3-chat", label: "OpenAI: GPT-5.3 Chat" },
28328
- { id: "openrouter/openai/gpt-5.3-codex", label: "OpenAI: GPT-5.3-Codex" },
28329
- { id: "openrouter/openai/gpt-5.4", label: "OpenAI: GPT-5.4" },
28399
+ { id: "openrouter/nvidia/nemotron-3-nano-30b-a3b", label: "NVIDIA: Nemotron 3 Nano 30B A3B" },
28330
28400
  { id: "openrouter/openai/gpt-5.4-mini", label: "OpenAI: GPT-5.4 Mini" },
28331
28401
  { id: "openrouter/openai/gpt-5.4-nano", label: "OpenAI: GPT-5.4 Nano" },
28332
- { id: "openrouter/openai/gpt-5.4-pro", label: "OpenAI: GPT-5.4 Pro" },
28333
- { id: "openrouter/openai/gpt-5.5", label: "OpenAI: GPT-5.5" },
28334
- { id: "openrouter/openai/gpt-5.5-pro", label: "OpenAI: GPT-5.5 Pro" },
28335
- { id: "openrouter/openai/gpt-audio", label: "OpenAI: GPT Audio" },
28336
- { id: "openrouter/openai/gpt-audio-mini", label: "OpenAI: GPT Audio Mini" },
28337
- { id: "openrouter/openai/gpt-chat-latest", label: "OpenAI: GPT Chat Latest" },
28338
- { id: "openrouter/openai/gpt-oss-120b", label: "OpenAI: gpt-oss-120b" },
28339
- { id: "openrouter/openai/gpt-oss-120b:free", label: "OpenAI: gpt-oss-120b (free)" },
28340
- { id: "openrouter/openai/gpt-oss-20b", label: "OpenAI: gpt-oss-20b" },
28341
- { id: "openrouter/openai/gpt-oss-20b:free", label: "OpenAI: gpt-oss-20b (free)" },
28342
- { id: "openrouter/openai/gpt-oss-safeguard-20b", label: "OpenAI: gpt-oss-safeguard-20b" },
28343
- { id: "openrouter/openai/o1", label: "OpenAI: o1" },
28344
- { id: "openrouter/openai/o3", label: "OpenAI: o3" },
28345
- { id: "openrouter/openai/o3-deep-research", label: "OpenAI: o3 Deep Research" },
28346
- { id: "openrouter/openai/o3-mini", label: "OpenAI: o3 Mini" },
28347
- { id: "openrouter/openai/o3-mini-high", label: "OpenAI: o3 Mini High" },
28348
- { id: "openrouter/openai/o3-pro", label: "OpenAI: o3 Pro" },
28402
+ { id: "openrouter/openai/gpt-5-mini", label: "OpenAI: GPT-5 Mini" },
28403
+ { id: "openrouter/openai/gpt-5-nano", label: "OpenAI: GPT-5 Nano" },
28404
+ { id: "openrouter/openai/gpt-4.1-mini", label: "OpenAI: GPT-4.1 Mini" },
28405
+ { id: "openrouter/openai/gpt-4.1-nano", label: "OpenAI: GPT-4.1 Nano" },
28406
+ { id: "openrouter/openai/gpt-4o-mini", label: "OpenAI: GPT-4o-mini" },
28349
28407
  { id: "openrouter/openai/o4-mini", label: "OpenAI: o4 Mini" },
28350
28408
  { id: "openrouter/openai/o4-mini-deep-research", label: "OpenAI: o4 Mini Deep Research" },
28351
28409
  { id: "openrouter/openai/o4-mini-high", label: "OpenAI: o4 Mini High" },
28352
- { id: "openrouter/openrouter/auto", label: "Auto Router" },
28353
- { id: "openrouter/openrouter/free", label: "Free Models Router" },
28354
- { id: "openrouter/openrouter/fusion", label: "OpenRouter: Fusion" },
28355
- { id: "openrouter/openrouter/owl-alpha", label: "Owl Alpha" },
28356
- { id: "openrouter/poolside/laguna-m.1", label: "Poolside: Laguna M.1" },
28357
- { id: "openrouter/poolside/laguna-m.1:free", label: "Poolside: Laguna M.1 (free)" },
28358
- { id: "openrouter/poolside/laguna-xs.2", label: "Poolside: Laguna XS.2" },
28359
- { id: "openrouter/poolside/laguna-xs.2:free", label: "Poolside: Laguna XS.2 (free)" },
28360
- { id: "openrouter/prime-intellect/intellect-3", label: "Prime Intellect: INTELLECT-3" },
28361
- { id: "openrouter/qwen/qwen-2.5-72b-instruct", label: "Qwen2.5 72B Instruct" },
28362
- { id: "openrouter/qwen/qwen-2.5-7b-instruct", label: "Qwen: Qwen2.5 7B Instruct" },
28363
- { id: "openrouter/qwen/qwen-plus", label: "Qwen: Qwen-Plus" },
28364
- { id: "openrouter/qwen/qwen-plus-2025-07-28", label: "Qwen: Qwen Plus 0728" },
28365
- { id: "openrouter/qwen/qwen-plus-2025-07-28:thinking", label: "Qwen: Qwen Plus 0728 (thinking)" },
28366
- { id: "openrouter/qwen/qwen3-14b", label: "Qwen: Qwen3 14B" },
28367
- { id: "openrouter/qwen/qwen3-235b-a22b", label: "Qwen: Qwen3 235B A22B" },
28368
- { id: "openrouter/qwen/qwen3-235b-a22b-2507", label: "Qwen: Qwen3 235B A22B Instruct 2507" },
28369
- { id: "openrouter/qwen/qwen3-235b-a22b-thinking-2507", label: "Qwen: Qwen3 235B A22B Thinking 2507" },
28370
- { id: "openrouter/qwen/qwen3-30b-a3b", label: "Qwen: Qwen3 30B A3B" },
28371
- { id: "openrouter/qwen/qwen3-30b-a3b-instruct-2507", label: "Qwen: Qwen3 30B A3B Instruct 2507" },
28372
- { id: "openrouter/qwen/qwen3-30b-a3b-thinking-2507", label: "Qwen: Qwen3 30B A3B Thinking 2507" },
28373
- { id: "openrouter/qwen/qwen3-32b", label: "Qwen: Qwen3 32B" },
28374
- { id: "openrouter/qwen/qwen3-8b", label: "Qwen: Qwen3 8B" },
28375
- { id: "openrouter/qwen/qwen3-coder", label: "Qwen: Qwen3 Coder 480B A35B" },
28376
- { id: "openrouter/qwen/qwen3-coder-30b-a3b-instruct", label: "Qwen: Qwen3 Coder 30B A3B Instruct" },
28377
- { id: "openrouter/qwen/qwen3-coder-flash", label: "Qwen: Qwen3 Coder Flash" },
28378
- { id: "openrouter/qwen/qwen3-coder-next", label: "Qwen: Qwen3 Coder Next" },
28379
- { id: "openrouter/qwen/qwen3-coder-plus", label: "Qwen: Qwen3 Coder Plus" },
28380
- { id: "openrouter/qwen/qwen3-coder:free", label: "Qwen: Qwen3 Coder 480B A35B (free)" },
28381
- { id: "openrouter/qwen/qwen3-max", label: "Qwen: Qwen3 Max" },
28382
- { id: "openrouter/qwen/qwen3-max-thinking", label: "Qwen: Qwen3 Max Thinking" },
28383
- { id: "openrouter/qwen/qwen3-next-80b-a3b-instruct", label: "Qwen: Qwen3 Next 80B A3B Instruct" },
28410
+ { id: "openrouter/openai/o3-mini", label: "OpenAI: o3 Mini" },
28411
+ { id: "openrouter/openai/o3-mini-high", label: "OpenAI: o3 Mini High" },
28412
+ { id: "openrouter/amazon/nova-2-lite-v1", label: "Amazon: Nova 2 Lite" },
28413
+ { id: "openrouter/bytedance-seed/seed-2.0-lite", label: "ByteDance Seed: Seed-2.0-Lite" },
28414
+ { id: "openrouter/bytedance-seed/seed-2.0-mini", label: "ByteDance Seed: Seed-2.0-Mini" },
28415
+ { id: "openrouter/amazon/nova-lite-v1", label: "Amazon: Nova Lite 1.0" },
28416
+ { id: "openrouter/amazon/nova-micro-v1", label: "Amazon: Nova Micro 1.0" },
28417
+ { id: "openrouter/arcee-ai/trinity-mini", label: "Arcee AI: Trinity Mini" },
28418
+ { id: "openrouter/cohere/north-mini-code:free", label: "Cohere: North Mini Code (free)" },
28419
+ { id: "openrouter/~openai/gpt-mini-latest", label: "OpenAI GPT Mini Latest" },
28420
+ { id: "openrouter/openai/gpt-audio-mini", label: "OpenAI: GPT Audio Mini" },
28421
+ { id: "openrouter/openai/gpt-oss-120b:free", label: "OpenAI: gpt-oss-120b (free)" },
28384
28422
  { id: "openrouter/qwen/qwen3-next-80b-a3b-instruct:free", label: "Qwen: Qwen3 Next 80B A3B Instruct (free)" },
28385
- { id: "openrouter/qwen/qwen3-next-80b-a3b-thinking", label: "Qwen: Qwen3 Next 80B A3B Thinking" },
28386
- { id: "openrouter/qwen/qwen3-vl-235b-a22b-instruct", label: "Qwen: Qwen3 VL 235B A22B Instruct" },
28387
- { id: "openrouter/qwen/qwen3-vl-235b-a22b-thinking", label: "Qwen: Qwen3 VL 235B A22B Thinking" },
28388
- { id: "openrouter/qwen/qwen3-vl-30b-a3b-instruct", label: "Qwen: Qwen3 VL 30B A3B Instruct" },
28389
- { id: "openrouter/qwen/qwen3-vl-30b-a3b-thinking", label: "Qwen: Qwen3 VL 30B A3B Thinking" },
28390
- { id: "openrouter/qwen/qwen3-vl-32b-instruct", label: "Qwen: Qwen3 VL 32B Instruct" },
28391
- { id: "openrouter/qwen/qwen3-vl-8b-instruct", label: "Qwen: Qwen3 VL 8B Instruct" },
28392
- { id: "openrouter/qwen/qwen3-vl-8b-thinking", label: "Qwen: Qwen3 VL 8B Thinking" },
28393
- { id: "openrouter/qwen/qwen3.5-122b-a10b", label: "Qwen: Qwen3.5-122B-A10B" },
28394
- { id: "openrouter/qwen/qwen3.5-27b", label: "Qwen: Qwen3.5-27B" },
28395
- { id: "openrouter/qwen/qwen3.5-35b-a3b", label: "Qwen: Qwen3.5-35B-A3B" },
28396
- { id: "openrouter/qwen/qwen3.5-397b-a17b", label: "Qwen: Qwen3.5 397B A17B" },
28397
- { id: "openrouter/qwen/qwen3.5-9b", label: "Qwen: Qwen3.5-9B" },
28398
- { id: "openrouter/qwen/qwen3.5-flash-02-23", label: "Qwen: Qwen3.5-Flash" },
28399
- { id: "openrouter/qwen/qwen3.5-plus-02-15", label: "Qwen: Qwen3.5 Plus 2026-02-15" },
28400
- { id: "openrouter/qwen/qwen3.5-plus-20260420", label: "Qwen: Qwen3.5 Plus 2026-04-20" },
28401
- { id: "openrouter/qwen/qwen3.6-27b", label: "Qwen: Qwen3.6 27B" },
28402
- { id: "openrouter/qwen/qwen3.6-35b-a3b", label: "Qwen: Qwen3.6 35B A3B" },
28403
- { id: "openrouter/qwen/qwen3.6-flash", label: "Qwen: Qwen3.6 Flash" },
28404
- { id: "openrouter/qwen/qwen3.6-max-preview", label: "Qwen: Qwen3.6 Max Preview" },
28405
- { id: "openrouter/qwen/qwen3.6-plus", label: "Qwen: Qwen3.6 Plus" },
28406
- { id: "openrouter/qwen/qwen3.7-max", label: "Qwen: Qwen3.7 Max" },
28407
- { id: "openrouter/qwen/qwen3.7-plus", label: "Qwen: Qwen3.7 Plus" },
28408
- { id: "openrouter/rekaai/reka-edge", label: "Reka Edge" },
28409
- { id: "openrouter/relace/relace-search", label: "Relace: Relace Search" },
28410
- { id: "openrouter/sao10k/l3.1-euryale-70b", label: "Sao10K: Llama 3.1 Euryale 70B v2.2" },
28411
- { id: "openrouter/stepfun/step-3.5-flash", label: "StepFun: Step 3.5 Flash" },
28412
- { id: "openrouter/stepfun/step-3.7-flash", label: "StepFun: Step 3.7 Flash" },
28413
- { id: "openrouter/tencent/hy3-preview", label: "Tencent: Hy3 preview" },
28414
- { id: "openrouter/thedrummer/rocinante-12b", label: "TheDrummer: Rocinante 12B" },
28415
- { id: "openrouter/thedrummer/unslopnemo-12b", label: "TheDrummer: UnslopNemo 12B" },
28416
- { id: "openrouter/upstage/solar-pro-3", label: "Upstage: Solar Pro 3" },
28417
- { id: "openrouter/x-ai/grok-4.20", label: "xAI: Grok 4.20" },
28418
- { id: "openrouter/x-ai/grok-4.3", label: "xAI: Grok 4.3" },
28419
- { id: "openrouter/x-ai/grok-build-0.1", label: "xAI: Grok Build 0.1" },
28420
- { id: "openrouter/xiaomi/mimo-v2.5", label: "Xiaomi: MiMo-V2.5" },
28421
- { id: "openrouter/xiaomi/mimo-v2.5-pro", label: "Xiaomi: MiMo-V2.5-Pro" },
28422
- { id: "openrouter/z-ai/glm-4.5", label: "Z.ai: GLM 4.5" },
28423
- { id: "openrouter/z-ai/glm-4.5-air", label: "Z.ai: GLM 4.5 Air" },
28424
- { id: "openrouter/z-ai/glm-4.5v", label: "Z.ai: GLM 4.5V" },
28425
- { id: "openrouter/z-ai/glm-4.6", label: "Z.ai: GLM 4.6" },
28426
- { id: "openrouter/z-ai/glm-4.6v", label: "Z.ai: GLM 4.6V" },
28427
- { id: "openrouter/z-ai/glm-4.7", label: "Z.ai: GLM 4.7" },
28428
- { id: "openrouter/z-ai/glm-4.7-flash", label: "Z.ai: GLM 4.7 Flash" },
28429
- { id: "openrouter/z-ai/glm-5", label: "Z.ai: GLM 5" },
28430
- { id: "openrouter/z-ai/glm-5-turbo", label: "Z.ai: GLM 5 Turbo" },
28431
- { id: "openrouter/z-ai/glm-5.1", label: "Z.ai: GLM 5.1" },
28432
- { id: "openrouter/z-ai/glm-5.2", label: "Z.ai: GLM 5.2" },
28433
- { id: "openrouter/~anthropic/claude-fable-latest", label: "Anthropic: Claude Fable Latest" },
28434
- { id: "openrouter/~anthropic/claude-haiku-latest", label: "Anthropic Claude Haiku Latest" },
28435
- { id: "openrouter/~anthropic/claude-opus-latest", label: "Anthropic: Claude Opus Latest" },
28436
- { id: "openrouter/~anthropic/claude-sonnet-latest", label: "Anthropic Claude Sonnet Latest" },
28437
- { id: "openrouter/~google/gemini-flash-latest", label: "Google Gemini Flash Latest" },
28438
- { id: "openrouter/~google/gemini-pro-latest", label: "Google Gemini Pro Latest" },
28439
- { id: "openrouter/~moonshotai/kimi-latest", label: "MoonshotAI Kimi Latest" },
28440
- { id: "openrouter/~openai/gpt-latest", label: "OpenAI GPT Latest" },
28441
- { id: "openrouter/~openai/gpt-mini-latest", label: "OpenAI GPT Mini Latest" }
28423
+ { id: "openrouter/meta-llama/llama-3.3-70b-instruct:free", label: "Meta: Llama 3.3 70B Instruct (free)" },
28424
+ { id: "openrouter/google/gemma-4-31b-it:free", label: "Google: Gemma 4 31B (free)" },
28425
+ { id: "openrouter/nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free", label: "NVIDIA: Nemotron 3 Nano Omni (free)" },
28426
+ { id: "openrouter/google/gemma-4-26b-a4b-it:free", label: "Google: Gemma 4 26B A4B (free)" },
28427
+ { id: "openrouter/openai/gpt-oss-20b:free", label: "OpenAI: gpt-oss-20b (free)" },
28428
+ { id: "openrouter/poolside/laguna-xs.2:free", label: "Poolside: Laguna XS.2 (free)" },
28429
+ { id: "openrouter/poolside/laguna-m.1:free", label: "Poolside: Laguna M.1 (free)" },
28430
+ { id: "openrouter/openrouter/free", label: "Free Models Router" },
28431
+ { id: "openrouter/google/gemini-2.5-flash-lite-preview-09-2025", label: "Google: Gemini 2.5 Flash Lite Preview 09-2025" },
28432
+ { id: "openrouter/google/gemini-3.1-flash-lite", label: "Google: Gemini 3.1 Flash Lite" },
28433
+ { id: "openrouter/google/gemini-3.1-flash-lite-preview", label: "Google: Gemini 3.1 Flash Lite Preview" },
28434
+ { id: "openrouter/google/gemini-2.5-flash-lite", label: "Google: Gemini 2.5 Flash Lite" },
28435
+ { id: "openrouter/nvidia/nemotron-3-nano-30b-a3b:free", label: "NVIDIA: Nemotron 3 Nano 30B A3B (free)" },
28436
+ { id: "openrouter/nvidia/nemotron-nano-12b-v2-vl:free", label: "NVIDIA: Nemotron Nano 12B 2 VL (free)" },
28437
+ { id: "openrouter/nvidia/nemotron-nano-9b-v2:free", label: "NVIDIA: Nemotron Nano 9B V2 (free)" }
28442
28438
  ],
28443
28439
  "openai": [
28444
- { id: "openai/gpt-5.4", label: "GPT-5.4" },
28445
- { id: "openai/gpt-4", label: "GPT-4" },
28446
- { id: "openai/gpt-4-turbo", label: "GPT-4 Turbo" },
28447
- { id: "openai/gpt-4.1", label: "GPT-4.1" },
28448
- { id: "openai/gpt-4.1-mini", label: "GPT-4.1 mini" },
28449
- { id: "openai/gpt-4.1-nano", label: "GPT-4.1 nano" },
28450
- { id: "openai/gpt-4o", label: "GPT-4o" },
28451
- { id: "openai/gpt-4o-2024-05-13", label: "GPT-4o (2024-05-13)" },
28452
- { id: "openai/gpt-4o-2024-08-06", label: "GPT-4o (2024-08-06)" },
28453
- { id: "openai/gpt-4o-2024-11-20", label: "GPT-4o (2024-11-20)" },
28454
- { id: "openai/gpt-4o-mini", label: "GPT-4o mini" },
28455
- { id: "openai/gpt-5", label: "GPT-5" },
28456
- { id: "openai/gpt-5-chat-latest", label: "GPT-5 Chat Latest" },
28457
- { id: "openai/gpt-5-codex", label: "GPT-5-Codex" },
28458
- { id: "openai/gpt-5-mini", label: "GPT-5 Mini" },
28459
- { id: "openai/gpt-5-nano", label: "GPT-5 Nano" },
28460
- { id: "openai/gpt-5-pro", label: "GPT-5 Pro" },
28461
- { id: "openai/gpt-5.1", label: "GPT-5.1" },
28462
- { id: "openai/gpt-5.1-chat-latest", label: "GPT-5.1 Chat" },
28463
- { id: "openai/gpt-5.1-codex", label: "GPT-5.1 Codex" },
28464
28440
  { id: "openai/gpt-5.1-codex-max", label: "GPT-5.1 Codex Max" },
28465
- { id: "openai/gpt-5.1-codex-mini", label: "GPT-5.1 Codex mini" },
28466
- { id: "openai/gpt-5.2", label: "GPT-5.2" },
28467
- { id: "openai/gpt-5.2-chat-latest", label: "GPT-5.2 Chat" },
28468
- { id: "openai/gpt-5.2-codex", label: "GPT-5.2 Codex" },
28441
+ { id: "openai/gpt-5.5-pro", label: "GPT-5.5 Pro" },
28442
+ { id: "openai/gpt-5.4-pro", label: "GPT-5.4 Pro" },
28469
28443
  { id: "openai/gpt-5.2-pro", label: "GPT-5.2 Pro" },
28470
- { id: "openai/gpt-5.3-chat-latest", label: "GPT-5.3 Chat (latest)" },
28444
+ { id: "openai/gpt-5-pro", label: "GPT-5 Pro" },
28445
+ { id: "openai/o3-pro", label: "o3-pro" },
28446
+ { id: "openai/o1-pro", label: "o1-pro" },
28471
28447
  { id: "openai/gpt-5.3-codex", label: "GPT-5.3 Codex" },
28472
28448
  { id: "openai/gpt-5.3-codex-spark", label: "GPT-5.3 Codex Spark" },
28473
- { id: "openai/gpt-5.4-mini", label: "GPT-5.4 mini" },
28474
- { id: "openai/gpt-5.4-nano", label: "GPT-5.4 nano" },
28475
- { id: "openai/gpt-5.4-pro", label: "GPT-5.4 Pro" },
28449
+ { id: "openai/gpt-5.2-codex", label: "GPT-5.2 Codex" },
28450
+ { id: "openai/gpt-5.1-codex", label: "GPT-5.1 Codex" },
28451
+ { id: "openai/gpt-5-codex", label: "GPT-5-Codex" },
28452
+ { id: "openai/gpt-5.1-codex-mini", label: "GPT-5.1 Codex mini" },
28453
+ { id: "openai/gpt-4o-2024-11-20", label: "GPT-4o (2024-11-20)" },
28454
+ { id: "openai/gpt-4o-2024-08-06", label: "GPT-4o (2024-08-06)" },
28455
+ { id: "openai/gpt-4o-2024-05-13", label: "GPT-4o (2024-05-13)" },
28476
28456
  { id: "openai/gpt-5.5", label: "GPT-5.5" },
28477
- { id: "openai/gpt-5.5-pro", label: "GPT-5.5 Pro" },
28478
- { id: "openai/o1", label: "o1" },
28479
- { id: "openai/o1-pro", label: "o1-pro" },
28457
+ { id: "openai/gpt-5.4", label: "GPT-5.4" },
28458
+ { id: "openai/gpt-5.3-chat-latest", label: "GPT-5.3 Chat (latest)" },
28459
+ { id: "openai/gpt-5.2", label: "GPT-5.2" },
28460
+ { id: "openai/gpt-5.2-chat-latest", label: "GPT-5.2 Chat" },
28461
+ { id: "openai/gpt-5.1", label: "GPT-5.1" },
28462
+ { id: "openai/gpt-5.1-chat-latest", label: "GPT-5.1 Chat" },
28463
+ { id: "openai/gpt-5", label: "GPT-5" },
28464
+ { id: "openai/gpt-5-chat-latest", label: "GPT-5 Chat Latest" },
28465
+ { id: "openai/gpt-4.1", label: "GPT-4.1" },
28466
+ { id: "openai/gpt-4", label: "GPT-4" },
28467
+ { id: "openai/gpt-4o", label: "GPT-4o" },
28480
28468
  { id: "openai/o3", label: "o3" },
28481
28469
  { id: "openai/o3-deep-research", label: "o3-deep-research" },
28482
- { id: "openai/o3-mini", label: "o3-mini" },
28483
- { id: "openai/o3-pro", label: "o3-pro" },
28470
+ { id: "openai/o1", label: "o1" },
28471
+ { id: "openai/gpt-4-turbo", label: "GPT-4 Turbo" },
28472
+ { id: "openai/gpt-5.4-mini", label: "GPT-5.4 mini" },
28473
+ { id: "openai/gpt-5.4-nano", label: "GPT-5.4 nano" },
28474
+ { id: "openai/gpt-5-mini", label: "GPT-5 Mini" },
28475
+ { id: "openai/gpt-5-nano", label: "GPT-5 Nano" },
28476
+ { id: "openai/gpt-4.1-mini", label: "GPT-4.1 mini" },
28477
+ { id: "openai/gpt-4.1-nano", label: "GPT-4.1 nano" },
28478
+ { id: "openai/gpt-4o-mini", label: "GPT-4o mini" },
28484
28479
  { id: "openai/o4-mini", label: "o4-mini" },
28485
- { id: "openai/o4-mini-deep-research", label: "o4-mini-deep-research" }
28480
+ { id: "openai/o4-mini-deep-research", label: "o4-mini-deep-research" },
28481
+ { id: "openai/o3-mini", label: "o3-mini" }
28486
28482
  ],
28487
28483
  "anthropic": [
28488
- { id: "anthropic/claude-opus-4-8", label: "Claude Opus 4.8" },
28489
- { id: "anthropic/claude-3-5-haiku-20241022", label: "Claude Haiku 3.5" },
28490
- { id: "anthropic/claude-3-5-haiku-latest", label: "Claude Haiku 3.5 (latest)" },
28491
- { id: "anthropic/claude-3-5-sonnet-20240620", label: "Claude Sonnet 3.5" },
28492
- { id: "anthropic/claude-3-5-sonnet-20241022", label: "Claude Sonnet 3.5 v2" },
28493
- { id: "anthropic/claude-3-7-sonnet-20250219", label: "Claude Sonnet 3.7" },
28494
- { id: "anthropic/claude-3-haiku-20240307", label: "Claude Haiku 3" },
28495
- { id: "anthropic/claude-3-opus-20240229", label: "Claude Opus 3" },
28496
- { id: "anthropic/claude-3-sonnet-20240229", label: "Claude Sonnet 3" },
28497
28484
  { id: "anthropic/claude-fable-5", label: "Claude Fable 5" },
28498
- { id: "anthropic/claude-haiku-4-5", label: "Claude Haiku 4.5 (latest)" },
28499
- { id: "anthropic/claude-haiku-4-5-20251001", label: "Claude Haiku 4.5" },
28500
- { id: "anthropic/claude-opus-4-0", label: "Claude Opus 4 (latest)" },
28501
- { id: "anthropic/claude-opus-4-1", label: "Claude Opus 4.1 (latest)" },
28502
- { id: "anthropic/claude-opus-4-1-20250805", label: "Claude Opus 4.1" },
28485
+ { id: "anthropic/claude-3-opus-20240229", label: "Claude Opus 3" },
28503
28486
  { id: "anthropic/claude-opus-4-20250514", label: "Claude Opus 4" },
28504
- { id: "anthropic/claude-opus-4-5", label: "Claude Opus 4.5 (latest)" },
28505
28487
  { id: "anthropic/claude-opus-4-5-20251101", label: "Claude Opus 4.5" },
28506
- { id: "anthropic/claude-opus-4-6", label: "Claude Opus 4.6" },
28488
+ { id: "anthropic/claude-opus-4-1-20250805", label: "Claude Opus 4.1" },
28489
+ { id: "anthropic/claude-opus-4-8", label: "Claude Opus 4.8" },
28507
28490
  { id: "anthropic/claude-opus-4-7", label: "Claude Opus 4.7" },
28508
- { id: "anthropic/claude-sonnet-4-0", label: "Claude Sonnet 4 (latest)" },
28491
+ { id: "anthropic/claude-opus-4-6", label: "Claude Opus 4.6" },
28492
+ { id: "anthropic/claude-opus-4-5", label: "Claude Opus 4.5 (latest)" },
28493
+ { id: "anthropic/claude-opus-4-1", label: "Claude Opus 4.1 (latest)" },
28494
+ { id: "anthropic/claude-opus-4-0", label: "Claude Opus 4 (latest)" },
28495
+ { id: "anthropic/claude-3-7-sonnet-20250219", label: "Claude Sonnet 3.7" },
28496
+ { id: "anthropic/claude-3-5-sonnet-20241022", label: "Claude Sonnet 3.5 v2" },
28497
+ { id: "anthropic/claude-3-5-sonnet-20240620", label: "Claude Sonnet 3.5" },
28498
+ { id: "anthropic/claude-3-sonnet-20240229", label: "Claude Sonnet 3" },
28509
28499
  { id: "anthropic/claude-sonnet-4-20250514", label: "Claude Sonnet 4" },
28510
- { id: "anthropic/claude-sonnet-4-5", label: "Claude Sonnet 4.5 (latest)" },
28511
28500
  { id: "anthropic/claude-sonnet-4-5-20250929", label: "Claude Sonnet 4.5" },
28512
- { id: "anthropic/claude-sonnet-4-6", label: "Claude Sonnet 4.6" }
28501
+ { id: "anthropic/claude-sonnet-5", label: "Claude Sonnet 5" },
28502
+ { id: "anthropic/claude-sonnet-4-6", label: "Claude Sonnet 4.6" },
28503
+ { id: "anthropic/claude-sonnet-4-5", label: "Claude Sonnet 4.5 (latest)" },
28504
+ { id: "anthropic/claude-sonnet-4-0", label: "Claude Sonnet 4 (latest)" },
28505
+ { id: "anthropic/claude-3-haiku-20240307", label: "Claude Haiku 3" },
28506
+ { id: "anthropic/claude-haiku-4-5-20251001", label: "Claude Haiku 4.5" },
28507
+ { id: "anthropic/claude-haiku-4-5", label: "Claude Haiku 4.5 (latest)" }
28513
28508
  ],
28514
28509
  "google": [
28515
28510
  { id: "google/gemini-3.1-pro-preview", label: "Gemini 3.1 Pro Preview" },
28516
- { id: "google/gemini-2.0-flash", label: "Gemini 2.0 Flash" },
28517
- { id: "google/gemini-2.0-flash-lite", label: "Gemini 2.0 Flash-Lite" },
28518
- { id: "google/gemini-2.5-flash", label: "Gemini 2.5 Flash" },
28519
- { id: "google/gemini-2.5-flash-lite", label: "Gemini 2.5 Flash-Lite" },
28511
+ { id: "google/gemini-3.1-pro-preview-customtools", label: "Gemini 3.1 Pro Preview Custom Tools" },
28512
+ { id: "google/gemini-3-pro-preview", label: "Gemini 3 Pro Preview" },
28520
28513
  { id: "google/gemini-2.5-pro", label: "Gemini 2.5 Pro" },
28514
+ { id: "google/gemma-4-31b-it", label: "Gemma 4 31B IT" },
28515
+ { id: "google/gemma-4-26b-a4b-it", label: "Gemma 4 26B A4B IT" },
28516
+ { id: "google/gemini-3.5-flash", label: "Gemini 3.5 Flash" },
28521
28517
  { id: "google/gemini-3-flash-preview", label: "Gemini 3 Flash Preview" },
28522
- { id: "google/gemini-3-pro-preview", label: "Gemini 3 Pro Preview" },
28518
+ { id: "google/gemini-2.5-flash", label: "Gemini 2.5 Flash" },
28519
+ { id: "google/gemini-2.0-flash", label: "Gemini 2.0 Flash" },
28520
+ { id: "google/gemini-flash-latest", label: "Gemini Flash Latest" },
28523
28521
  { id: "google/gemini-3.1-flash-lite", label: "Gemini 3.1 Flash Lite" },
28524
28522
  { id: "google/gemini-3.1-flash-lite-preview", label: "Gemini 3.1 Flash Lite Preview" },
28525
- { id: "google/gemini-3.1-pro-preview-customtools", label: "Gemini 3.1 Pro Preview Custom Tools" },
28526
- { id: "google/gemini-3.5-flash", label: "Gemini 3.5 Flash" },
28527
- { id: "google/gemini-flash-latest", label: "Gemini Flash Latest" },
28528
- { id: "google/gemini-flash-lite-latest", label: "Gemini Flash-Lite Latest" },
28529
- { id: "google/gemma-4-26b-a4b-it", label: "Gemma 4 26B A4B IT" },
28530
- { id: "google/gemma-4-31b-it", label: "Gemma 4 31B IT" },
28531
- { id: "google/gemma-4-E2B-it", label: "Gemma 4 E2B IT" },
28532
- { id: "google/gemma-4-E4B-it", label: "Gemma 4 E4B IT" }
28523
+ { id: "google/gemini-2.5-flash-lite", label: "Gemini 2.5 Flash-Lite" },
28524
+ { id: "google/gemini-2.0-flash-lite", label: "Gemini 2.0 Flash-Lite" },
28525
+ { id: "google/gemini-flash-lite-latest", label: "Gemini Flash-Lite Latest" }
28533
28526
  ],
28534
28527
  "xai": [
28535
- { id: "xai/grok-4.20-0309-reasoning", label: "Grok 4.20 (Reasoning)" },
28536
- { id: "xai/grok-3", label: "Grok 3" },
28537
- { id: "xai/grok-3-fast", label: "Grok 3 Fast" },
28538
28528
  { id: "xai/grok-4.20-0309-non-reasoning", label: "Grok 4.20 (Non-Reasoning)" },
28529
+ { id: "xai/grok-4.20-0309-reasoning", label: "Grok 4.20 (Reasoning)" },
28530
+ { id: "xai/grok-code-fast-1", label: "Grok Code Fast 1" },
28539
28531
  { id: "xai/grok-4.3", label: "Grok 4.3" },
28532
+ { id: "xai/grok-3", label: "Grok 3" },
28540
28533
  { id: "xai/grok-build-0.1", label: "Grok Build 0.1" },
28541
- { id: "xai/grok-code-fast-1", label: "Grok Code Fast 1" }
28534
+ { id: "xai/grok-3-fast", label: "Grok 3 Fast" }
28542
28535
  ],
28543
28536
  "xiaomi": [
28544
28537
  { id: "xiaomi/mimo-v2.5-pro", label: "MiMo-V2.5-Pro" },
28545
- { id: "xiaomi/mimo-v2-flash", label: "MiMo-V2-Flash" },
28546
- { id: "xiaomi/mimo-v2-omni", label: "MiMo-V2-Omni" },
28538
+ { id: "xiaomi/mimo-v2.5-pro-ultraspeed", label: "MiMo-V2.5-Pro-UltraSpeed" },
28547
28539
  { id: "xiaomi/mimo-v2-pro", label: "MiMo-V2-Pro" },
28548
28540
  { id: "xiaomi/mimo-v2.5", label: "MiMo-V2.5" },
28549
- { id: "xiaomi/mimo-v2.5-pro-ultraspeed", label: "MiMo-V2.5-Pro-UltraSpeed" }
28541
+ { id: "xiaomi/mimo-v2-omni", label: "MiMo-V2-Omni" },
28542
+ { id: "xiaomi/mimo-v2-flash", label: "MiMo-V2-Flash" }
28550
28543
  ]
28551
28544
  };
28552
28545
 
@@ -42798,6 +42791,21 @@ var agentApiHistoryQuerySchema = passthroughObject({
42798
42791
  around: optionalStringSchema,
42799
42792
  limit: optionalStringSchema
42800
42793
  });
42794
+ var agentApiKnowledgeGetQuerySchema = passthroughObject({
42795
+ topic: external_exports.string().trim().min(1),
42796
+ reason: optionalStringSchema,
42797
+ turn_id: optionalStringSchema,
42798
+ trace_id: optionalStringSchema
42799
+ });
42800
+ var agentApiKnowledgeGetResponseSchema = passthroughObject({
42801
+ ok: external_exports.literal(true),
42802
+ docId: external_exports.string(),
42803
+ topicOrPath: external_exports.string(),
42804
+ docVersion: external_exports.string(),
42805
+ docState: external_exports.string(),
42806
+ contentType: external_exports.string(),
42807
+ content: external_exports.string()
42808
+ });
42801
42809
  var agentApiMessageSearchQuerySchema = passthroughObject({
42802
42810
  q: optionalStringSchema,
42803
42811
  channel: optionalStringSchema,
@@ -42835,6 +42843,58 @@ var agentApiMessageReactionBodySchema = passthroughObject({
42835
42843
  var agentApiChannelMembershipParamsSchema = passthroughObject({
42836
42844
  channelId: external_exports.string().trim().min(1).transform(asChannelId)
42837
42845
  });
42846
+ var agentApiAttachmentDownloadParamsSchema = passthroughObject({
42847
+ attachmentId: external_exports.string().trim().min(1)
42848
+ });
42849
+ var agentApiAttachmentCommentsParamsSchema = passthroughObject({
42850
+ attachmentId: external_exports.string().trim().min(1)
42851
+ });
42852
+ var agentApiAttachmentCommentsQuerySchema = passthroughObject({
42853
+ limit: optionalStringSchema
42854
+ });
42855
+ var agentApiAttachmentCommentAnchorSchema = passthroughObject({
42856
+ type: external_exports.string().trim().min(1),
42857
+ data: external_exports.record(external_exports.string(), external_exports.unknown())
42858
+ });
42859
+ var agentApiAttachmentCommentReactionSchema = passthroughObject({
42860
+ emoji: external_exports.string().trim().min(1),
42861
+ reactorType: external_exports.string().trim().min(1),
42862
+ reactorId: external_exports.string().trim().min(1),
42863
+ createdAt: external_exports.string().datetime()
42864
+ });
42865
+ var agentApiAttachmentCommentResolvedBySchema = passthroughObject({
42866
+ reactorId: external_exports.string().trim().min(1),
42867
+ reactorType: external_exports.string().trim().min(1)
42868
+ });
42869
+ var agentApiAttachmentCommentSchema = passthroughObject({
42870
+ id: external_exports.string().trim().min(1),
42871
+ channelId: external_exports.string().trim().min(1).optional(),
42872
+ senderId: external_exports.string().trim().min(1),
42873
+ senderType: external_exports.enum(["user", "agent"]),
42874
+ senderName: external_exports.string().trim().min(1),
42875
+ senderAvatarUrl: nullableStringSchema.optional(),
42876
+ senderGravatarHash: nullableStringSchema.optional(),
42877
+ content: external_exports.string(),
42878
+ createdAt: external_exports.string().datetime(),
42879
+ reactions: external_exports.array(agentApiAttachmentCommentReactionSchema),
42880
+ anchor: agentApiAttachmentCommentAnchorSchema.nullable(),
42881
+ resolved: external_exports.boolean().optional(),
42882
+ resolvedBy: agentApiAttachmentCommentResolvedBySchema.nullable().optional(),
42883
+ resolvedAt: external_exports.string().datetime().nullable().optional()
42884
+ });
42885
+ var agentApiAttachmentCommentsResponseSchema = passthroughObject({
42886
+ comments: external_exports.array(agentApiAttachmentCommentSchema),
42887
+ threadChannelId: nullableStringSchema.optional(),
42888
+ viewer: passthroughObject({
42889
+ canComment: external_exports.boolean(),
42890
+ reason: external_exports.string().optional(),
42891
+ canResolve: external_exports.boolean(),
42892
+ resolveAction: passthroughObject({
42893
+ type: external_exports.string().trim().min(1),
42894
+ emoji: external_exports.string().trim().min(1)
42895
+ }).optional()
42896
+ }).optional()
42897
+ });
42838
42898
  var agentApiChannelMembersQuerySchema = passthroughObject({
42839
42899
  channel: external_exports.string().trim().min(1)
42840
42900
  });
@@ -42989,6 +43049,9 @@ var agentApiIntegrationAppPrepareBodySchema = passthroughObject({
42989
43049
  unsafeDemoUrlOverride: optionalBooleanSchema,
42990
43050
  draftHint: optionalStringSchema
42991
43051
  });
43052
+ var agentApiIntegrationAppRotateSecretBodySchema = passthroughObject({
43053
+ clientKey: external_exports.string().trim().min(1)
43054
+ });
42992
43055
  var agentApiActionPrepareBodySchema = passthroughObject({
42993
43056
  target: external_exports.string().trim().min(1),
42994
43057
  action: actionCardActionSchema
@@ -42996,6 +43059,9 @@ var agentApiActionPrepareBodySchema = passthroughObject({
42996
43059
  var agentApiServerInfoResponseSchema = passthroughObject({
42997
43060
  runtimeContext: passthroughObject({
42998
43061
  agentId: external_exports.string(),
43062
+ runtime: external_exports.string().optional(),
43063
+ model: external_exports.string().optional(),
43064
+ reasoningEffort: reasoningEffortSchema.nullable().optional(),
42999
43065
  serverId: external_exports.string(),
43000
43066
  machineId: external_exports.string().nullable().optional(),
43001
43067
  machineName: external_exports.string().nullable().optional(),
@@ -43012,10 +43078,12 @@ var agentApiServerInfoResponseSchema = passthroughObject({
43012
43078
  joined: external_exports.boolean()
43013
43079
  })),
43014
43080
  agents: external_exports.array(passthroughObject({
43015
- name: external_exports.string()
43081
+ name: external_exports.string(),
43082
+ role: external_exports.enum(["owner", "admin", "member"]).nullable().optional()
43016
43083
  })),
43017
43084
  humans: external_exports.array(passthroughObject({
43018
- name: external_exports.string()
43085
+ name: external_exports.string(),
43086
+ role: external_exports.enum(["owner", "admin", "member"]).nullable().optional()
43019
43087
  }))
43020
43088
  });
43021
43089
  var agentApiMentionActionsPendingQuerySchema = passthroughObject({
@@ -43090,6 +43158,12 @@ var agentApiIntegrationAppPrepareResponseSchema = passthroughObject({
43090
43158
  integrationUpdateAppRegistrationOperationSchema
43091
43159
  ])
43092
43160
  });
43161
+ var agentApiIntegrationAppRotateSecretResponseSchema = passthroughObject({
43162
+ clientId: external_exports.string(),
43163
+ clientKey: external_exports.string(),
43164
+ clientName: external_exports.string(),
43165
+ clientSecret: external_exports.string()
43166
+ });
43093
43167
  var agentApiAttachmentEnvelopeSchema = passthroughObject({
43094
43168
  id: external_exports.string(),
43095
43169
  filename: external_exports.string()
@@ -43225,6 +43299,21 @@ var agentApiChannelMembersResponseSchema = passthroughObject({
43225
43299
  role: optionalStringSchema
43226
43300
  }))
43227
43301
  });
43302
+ var agentApiChannelMuteResponseSchema = passthroughObject({
43303
+ activityMuted: optionalBooleanSchema,
43304
+ muteFromSeq: nullableNumberSchema.optional(),
43305
+ attention: passthroughObject({
43306
+ state: optionalStringSchema,
43307
+ ordinaryActivity: optionalStringSchema,
43308
+ unmuteCommand: optionalStringSchema,
43309
+ unmuteApi: optionalStringSchema,
43310
+ muteCommand: optionalStringSchema,
43311
+ muteApi: optionalStringSchema,
43312
+ stillArrives: optionalStringArraySchema,
43313
+ threadBoundary: optionalStringSchema,
43314
+ catchUp: optionalStringSchema
43315
+ }).optional()
43316
+ });
43228
43317
  var agentApiTaskClaimResultSchema = passthroughObject({
43229
43318
  taskNumber: external_exports.number().int().positive().optional(),
43230
43319
  messageId: optionalStringSchema,
@@ -43337,6 +43426,16 @@ var agentApiContract = {
43337
43426
  request: { query: agentApiHistoryQuerySchema },
43338
43427
  response: { body: agentApiHistoryResponseSchema }
43339
43428
  }),
43429
+ knowledgeGet: route({
43430
+ key: "knowledgeGet",
43431
+ method: "GET",
43432
+ path: "/knowledge",
43433
+ client: { resource: "knowledge", method: "get" },
43434
+ capability: "knowledge",
43435
+ description: "Fetch a Slock Manual for Agents topic from the current server.",
43436
+ request: { query: agentApiKnowledgeGetQuerySchema },
43437
+ response: { body: agentApiKnowledgeGetResponseSchema }
43438
+ }),
43340
43439
  messageSend: route({
43341
43440
  key: "messageSend",
43342
43441
  method: "POST",
@@ -43407,6 +43506,26 @@ var agentApiContract = {
43407
43506
  request: { params: agentApiChannelMembershipParamsSchema },
43408
43507
  response: { body: agentApiOkResponseSchema }
43409
43508
  }),
43509
+ channelMute: route({
43510
+ key: "channelMute",
43511
+ method: "POST",
43512
+ path: "/channels/:channelId/mute",
43513
+ client: { resource: "channels", method: "mute" },
43514
+ capability: "channels",
43515
+ description: "Mute ordinary activity delivery for a visible regular channel as the bound agent credential.",
43516
+ request: { params: agentApiChannelMembershipParamsSchema },
43517
+ response: { body: agentApiChannelMuteResponseSchema }
43518
+ }),
43519
+ channelUnmute: route({
43520
+ key: "channelUnmute",
43521
+ method: "POST",
43522
+ path: "/channels/:channelId/unmute",
43523
+ client: { resource: "channels", method: "unmute" },
43524
+ capability: "channels",
43525
+ description: "Unmute ordinary activity delivery for a visible regular channel as the bound agent credential.",
43526
+ request: { params: agentApiChannelMembershipParamsSchema },
43527
+ response: { body: agentApiChannelMuteResponseSchema }
43528
+ }),
43410
43529
  channelMembers: route({
43411
43530
  key: "channelMembers",
43412
43531
  method: "GET",
@@ -43597,6 +43716,16 @@ var agentApiContract = {
43597
43716
  request: { body: agentApiProfileUpdateBodySchema },
43598
43717
  response: { body: agentApiProfileViewSchema }
43599
43718
  }),
43719
+ profileAvatarUpdate: route({
43720
+ key: "profileAvatarUpdate",
43721
+ method: "POST",
43722
+ path: "/profile/avatar",
43723
+ client: { resource: "profile", method: "updateAvatar" },
43724
+ capability: "server",
43725
+ description: "Update the bound agent profile avatar using multipart form data.",
43726
+ request: {},
43727
+ response: { body: agentApiProfileViewSchema }
43728
+ }),
43600
43729
  integrationList: route({
43601
43730
  key: "integrationList",
43602
43731
  method: "GET",
@@ -43627,6 +43756,22 @@ var agentApiContract = {
43627
43756
  request: { body: agentApiIntegrationAppPrepareBodySchema },
43628
43757
  response: { body: agentApiIntegrationAppPrepareResponseSchema }
43629
43758
  }),
43759
+ integrationAppRotateSecret: route({
43760
+ key: "integrationAppRotateSecret",
43761
+ method: "POST",
43762
+ path: "/integrations/app/rotate-secret",
43763
+ client: { resource: "integrations", method: "rotateAppSecret" },
43764
+ // Mirrors integrationAppPrepare's "read" capability: the AgentApiCapability
43765
+ // enum has no generic "mutation"/"integrations" scope, and the sibling
43766
+ // integration app routes (prepare/login) all gate on "read". Owner-scope is
43767
+ // enforced server-side in rotateClientSecretForAgent's WHERE clause (and the
43768
+ // bound agent credential), so the capability tier is not the security
43769
+ // boundary here. Keep parity with integrationAppPrepare.
43770
+ capability: "read",
43771
+ description: "Regenerate the one-time client secret for a server-local integration app the calling agent owns; invalidates the previous secret.",
43772
+ request: { body: agentApiIntegrationAppRotateSecretBodySchema },
43773
+ response: { body: agentApiIntegrationAppRotateSecretResponseSchema }
43774
+ }),
43630
43775
  actionPrepare: route({
43631
43776
  key: "actionPrepare",
43632
43777
  method: "POST",
@@ -43646,13 +43791,43 @@ var agentApiContract = {
43646
43791
  description: "Upload a multipart attachment as the bound agent credential.",
43647
43792
  request: {},
43648
43793
  response: { body: agentApiAttachmentUploadResponseSchema }
43794
+ }),
43795
+ attachmentDownload: route({
43796
+ key: "attachmentDownload",
43797
+ method: "GET",
43798
+ path: "/attachments/:attachmentId",
43799
+ client: { resource: "attachments", method: "download" },
43800
+ capability: "read",
43801
+ description: "Download attachment bytes visible to the bound agent credential.",
43802
+ request: { params: agentApiAttachmentDownloadParamsSchema },
43803
+ response: { kind: "binary" }
43804
+ }),
43805
+ attachmentCommentsList: route({
43806
+ key: "attachmentCommentsList",
43807
+ method: "GET",
43808
+ path: "/attachments/:attachmentId/comments",
43809
+ client: { resource: "attachments", method: "comments" },
43810
+ capability: "read",
43811
+ description: "List comments scoped to an attachment visible to the bound agent credential.",
43812
+ request: { params: agentApiAttachmentCommentsParamsSchema, query: agentApiAttachmentCommentsQuerySchema },
43813
+ response: { body: agentApiAttachmentCommentsResponseSchema }
43649
43814
  })
43650
43815
  };
43651
- function buildLegacyAgentApiPath(agentId, routePath) {
43652
- return `/internal/agent/${encodeURIComponent(agentId)}${routePath}`;
43816
+ function getAgentApiResponseKind(response) {
43817
+ return "kind" in response ? response.kind ?? "json" : "json";
43653
43818
  }
43654
43819
  function parseAgentApiResponse(key, value) {
43655
- return agentApiContract[key].response.body.parse(value);
43820
+ const response = agentApiContract[key].response;
43821
+ if (getAgentApiResponseKind(response) === "binary") {
43822
+ if (!(value instanceof Uint8Array)) {
43823
+ throw new TypeError(`Agent API ${key} response did not contain binary bytes`);
43824
+ }
43825
+ return value;
43826
+ }
43827
+ if (!("body" in response)) {
43828
+ throw new TypeError(`Agent API ${key} response contract is missing a JSON body schema`);
43829
+ }
43830
+ return response.body.parse(value);
43656
43831
  }
43657
43832
 
43658
43833
  // ../shared/src/agentApiRawClient.ts
@@ -43667,17 +43842,17 @@ function failure(routeKey, reason, message, details = {}) {
43667
43842
  };
43668
43843
  }
43669
43844
  function encodePathParams(routeKey, params) {
43670
- const route2 = agentApiContract[routeKey];
43845
+ const route3 = agentApiContract[routeKey];
43671
43846
  let parsed;
43672
43847
  try {
43673
- parsed = "params" in route2.request ? route2.request.params.parse(params ?? {}) : {};
43848
+ parsed = "params" in route3.request ? route3.request.params.parse(params ?? {}) : {};
43674
43849
  } catch (cause) {
43675
- return failure(routeKey, "request_contract_mismatch", `Agent API ${route2.key} path params did not match the shared contract`, { cause });
43850
+ return failure(routeKey, "request_contract_mismatch", `Agent API ${route3.key} path params did not match the shared contract`, { cause });
43676
43851
  }
43677
- return route2.path.replace(/:([A-Za-z][A-Za-z0-9_]*)/g, (_match, key) => {
43852
+ return route3.path.replace(/:([A-Za-z][A-Za-z0-9_]*)/g, (_match, key) => {
43678
43853
  const value = parsed[key];
43679
43854
  if (value === void 0 || value === null) {
43680
- throw new MissingPathParamError(route2.key, key);
43855
+ throw new MissingPathParamError(route3.key, key);
43681
43856
  }
43682
43857
  return encodeURIComponent(String(value));
43683
43858
  });
@@ -43691,12 +43866,12 @@ var MissingPathParamError = class extends Error {
43691
43866
  };
43692
43867
  function encodeQuery(routeKey, query) {
43693
43868
  if (query === void 0) return void 0;
43694
- const route2 = agentApiContract[routeKey];
43869
+ const route3 = agentApiContract[routeKey];
43695
43870
  let parsed;
43696
43871
  try {
43697
- parsed = "query" in route2.request ? route2.request.query.parse(query) : {};
43872
+ parsed = "query" in route3.request ? route3.request.query.parse(query) : {};
43698
43873
  } catch (cause) {
43699
- return failure(routeKey, "request_contract_mismatch", `Agent API ${route2.key} query did not match the shared contract`, { cause });
43874
+ return failure(routeKey, "request_contract_mismatch", `Agent API ${route3.key} query did not match the shared contract`, { cause });
43700
43875
  }
43701
43876
  const params = new URLSearchParams();
43702
43877
  for (const [key, value] of Object.entries(parsed)) {
@@ -43711,11 +43886,11 @@ function encodeQuery(routeKey, query) {
43711
43886
  }
43712
43887
  function parseBody(routeKey, body) {
43713
43888
  if (body === void 0) return void 0;
43714
- const route2 = agentApiContract[routeKey];
43889
+ const route3 = agentApiContract[routeKey];
43715
43890
  try {
43716
- return "body" in route2.request ? route2.request.body.parse(body) : void 0;
43891
+ return "body" in route3.request ? route3.request.body.parse(body) : void 0;
43717
43892
  } catch (cause) {
43718
- return failure(routeKey, "request_contract_mismatch", `Agent API ${route2.key} body did not match the shared contract`, { cause });
43893
+ return failure(routeKey, "request_contract_mismatch", `Agent API ${route3.key} body did not match the shared contract`, { cause });
43719
43894
  }
43720
43895
  }
43721
43896
  function isAgentApiRawFailure(value) {
@@ -43741,7 +43916,7 @@ function buildAgentApiRawRoutePath(routeKey, options = {}) {
43741
43916
  return `${options.pathPrefix ?? AGENT_API_BASE_PATH}${path9}${suffix}`;
43742
43917
  }
43743
43918
  async function requestAgentApiRawRoute(transport, routeKey, options = {}) {
43744
- const route2 = agentApiContract[routeKey];
43919
+ const route3 = agentApiContract[routeKey];
43745
43920
  const path9 = buildAgentApiRawRoutePath(routeKey, options);
43746
43921
  if (typeof path9 !== "string") return path9;
43747
43922
  const body = parseBody(routeKey, options.body);
@@ -43750,12 +43925,12 @@ async function requestAgentApiRawRoute(transport, routeKey, options = {}) {
43750
43925
  try {
43751
43926
  response = await transport.request({
43752
43927
  routeKey,
43753
- method: route2.method,
43928
+ method: route3.method,
43754
43929
  path: path9,
43755
43930
  body
43756
43931
  });
43757
43932
  } catch (cause) {
43758
- return failure(routeKey, "transport_error", `Agent API ${route2.key} transport request failed`, { cause });
43933
+ return failure(routeKey, "transport_error", `Agent API ${route3.key} transport request failed`, { cause });
43759
43934
  }
43760
43935
  if (!response.ok) {
43761
43936
  return failure(routeKey, "http_error", response.error ?? `HTTP ${response.status}`, {
@@ -43765,8 +43940,22 @@ async function requestAgentApiRawRoute(transport, routeKey, options = {}) {
43765
43940
  response: response.data
43766
43941
  });
43767
43942
  }
43943
+ if (getAgentApiResponseKind(route3.response) === "binary") {
43944
+ if (!(response.data instanceof Uint8Array)) {
43945
+ return failure(routeKey, "response_contract_mismatch", `Agent API ${route3.key} response did not contain binary bytes`, {
43946
+ status: response.status,
43947
+ response: response.data
43948
+ });
43949
+ }
43950
+ return {
43951
+ ok: true,
43952
+ routeKey,
43953
+ status: response.status,
43954
+ data: response.data
43955
+ };
43956
+ }
43768
43957
  if (response.data === null) {
43769
- return failure(routeKey, "empty_response", `Agent API ${route2.key} returned an empty response body`, {
43958
+ return failure(routeKey, "empty_response", `Agent API ${route3.key} returned an empty response body`, {
43770
43959
  status: response.status
43771
43960
  });
43772
43961
  }
@@ -43778,7 +43967,7 @@ async function requestAgentApiRawRoute(transport, routeKey, options = {}) {
43778
43967
  data: parseAgentApiResponse(routeKey, response.data)
43779
43968
  };
43780
43969
  } catch (cause) {
43781
- return failure(routeKey, "response_contract_mismatch", `Agent API ${route2.key} response did not match the shared contract`, {
43970
+ return failure(routeKey, "response_contract_mismatch", `Agent API ${route3.key} response did not match the shared contract`, {
43782
43971
  status: response.status,
43783
43972
  cause,
43784
43973
  response: response.data
@@ -43786,16 +43975,16 @@ async function requestAgentApiRawRoute(transport, routeKey, options = {}) {
43786
43975
  }
43787
43976
  }
43788
43977
  function requestOptionsFromMethodArgs(routeKey, pathPrefix, args) {
43789
- const route2 = agentApiContract[routeKey];
43978
+ const route3 = agentApiContract[routeKey];
43790
43979
  let index = 0;
43791
43980
  const requestOptions = { pathPrefix };
43792
- if ("params" in route2.request) {
43981
+ if ("params" in route3.request) {
43793
43982
  requestOptions.params = args[index++];
43794
43983
  }
43795
- if ("query" in route2.request) {
43984
+ if ("query" in route3.request) {
43796
43985
  requestOptions.query = args[index++];
43797
43986
  }
43798
- if ("body" in route2.request) {
43987
+ if ("body" in route3.request) {
43799
43988
  requestOptions.body = args[index++];
43800
43989
  }
43801
43990
  return requestOptions;
@@ -43803,9 +43992,9 @@ function requestOptionsFromMethodArgs(routeKey, pathPrefix, args) {
43803
43992
  function createAgentApiRawClient(transport, options = {}) {
43804
43993
  const pathPrefix = options.pathPrefix ?? AGENT_API_BASE_PATH;
43805
43994
  const client = {};
43806
- for (const route2 of Object.values(agentApiContract)) {
43807
- const routeKey = route2.key;
43808
- const { resource, method } = route2.client;
43995
+ for (const route3 of Object.values(agentApiContract)) {
43996
+ const routeKey = route3.key;
43997
+ const { resource, method } = route3.client;
43809
43998
  const resourceClient = client[resource] ??= {};
43810
43999
  resourceClient[method] = (...args) => requestAgentApiRawRoute(
43811
44000
  transport,
@@ -43828,7 +44017,10 @@ async function authHeadersForRequest(auth, request) {
43828
44017
  if (!auth) return void 0;
43829
44018
  return typeof auth === "function" ? auth(request) : auth;
43830
44019
  }
43831
- async function parseFetchResponse(response) {
44020
+ async function parseFetchResponse(response, responseKind) {
44021
+ if (response.ok && responseKind === "binary") {
44022
+ return new Uint8Array(await response.arrayBuffer());
44023
+ }
43832
44024
  const text = await response.text();
43833
44025
  if (!text.trim()) return null;
43834
44026
  try {
@@ -43864,8 +44056,9 @@ function createAgentApiFetchTransport(options) {
43864
44056
  request: async (input) => {
43865
44057
  await options.throttle?.beforeRequest?.(input);
43866
44058
  const authHeaders = await authHeadersForRequest(options.auth, input);
44059
+ const responseKind = getAgentApiResponseKind(agentApiContract[input.routeKey].response);
43867
44060
  const headers = mergeHeaders(
43868
- { accept: "application/json" },
44061
+ { accept: responseKind === "binary" ? "*/*" : "application/json" },
43869
44062
  input.body === void 0 ? void 0 : { "content-type": "application/json" },
43870
44063
  options.headers,
43871
44064
  authHeaders
@@ -43879,7 +44072,7 @@ function createAgentApiFetchTransport(options) {
43879
44072
  for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
43880
44073
  try {
43881
44074
  const response = await fetchImpl(`${baseUrl}${input.path}`, init);
43882
- return transportResponseFromFetch(response, await parseFetchResponse(response));
44075
+ return transportResponseFromFetch(response, await parseFetchResponse(response, responseKind));
43883
44076
  } catch (cause) {
43884
44077
  lastError = cause;
43885
44078
  if (attempt === maxAttempts) throw cause;
@@ -43889,33 +44082,33 @@ function createAgentApiFetchTransport(options) {
43889
44082
  }
43890
44083
  };
43891
44084
  }
43892
- function errorFromRawFailure(failure2) {
43893
- if (failure2.reason === "transport_error") {
44085
+ function errorFromRawFailure(failure3) {
44086
+ if (failure3.reason === "transport_error") {
43894
44087
  return {
43895
44088
  kind: "transport",
43896
- reason: failure2.reason,
43897
- message: failure2.message,
43898
- cause: failure2.cause
44089
+ reason: failure3.reason,
44090
+ message: failure3.message,
44091
+ cause: failure3.cause
43899
44092
  };
43900
44093
  }
43901
- if (failure2.reason === "http_error") {
44094
+ if (failure3.reason === "http_error") {
43902
44095
  return {
43903
44096
  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
44097
+ reason: failure3.reason,
44098
+ message: failure3.message,
44099
+ status: failure3.status ?? 0,
44100
+ errorCode: failure3.errorCode,
44101
+ suggestedNextAction: failure3.suggestedNextAction,
44102
+ response: failure3.response
43910
44103
  };
43911
44104
  }
43912
44105
  return {
43913
44106
  kind: "validation",
43914
- reason: failure2.reason,
43915
- message: failure2.message,
43916
- status: failure2.status,
43917
- cause: failure2.cause,
43918
- response: failure2.response
44107
+ reason: failure3.reason,
44108
+ message: failure3.message,
44109
+ status: failure3.status,
44110
+ cause: failure3.cause,
44111
+ response: failure3.response
43919
44112
  };
43920
44113
  }
43921
44114
  function agentApiClientResultFromRaw(result2) {
@@ -43963,6 +44156,375 @@ function createAgentApiClient(transportOrOptions, maybeOptions = {}) {
43963
44156
  };
43964
44157
  }
43965
44158
 
44159
+ // ../shared/src/daemonApiContract.ts
44160
+ init_esm_shims();
44161
+ var DAEMON_API_BASE_PATH = "/internal/agent-api";
44162
+ var optionalStringSchema2 = external_exports.string().trim().optional();
44163
+ var optionalNonNegativeIntSchema = external_exports.number().int().nonnegative().optional();
44164
+ var optionalQueryIntSchema = external_exports.union([external_exports.number().int().nonnegative(), external_exports.string().trim().min(1)]).optional();
44165
+ var nullableNumberSchema2 = external_exports.number().finite().nullable();
44166
+ var passthroughObject2 = (shape) => external_exports.object(shape).passthrough();
44167
+ var daemonApiInboxFlagSchema = external_exports.enum(["mention", "thread", "dm", "task"]);
44168
+ var daemonApiInboxTargetRowSchema = passthroughObject2({
44169
+ target: external_exports.string().trim().min(1),
44170
+ channelId: optionalStringSchema2,
44171
+ channelType: optionalStringSchema2,
44172
+ pendingCount: external_exports.number().int().nonnegative(),
44173
+ firstPendingMsgId: optionalStringSchema2,
44174
+ firstPendingSeq: optionalNonNegativeIntSchema,
44175
+ latestMsgId: optionalStringSchema2,
44176
+ latestSeq: optionalNonNegativeIntSchema,
44177
+ latestSenderName: optionalStringSchema2,
44178
+ latestSenderType: external_exports.enum(["human", "agent", "system"]).optional(),
44179
+ flags: external_exports.array(daemonApiInboxFlagSchema)
44180
+ });
44181
+ var daemonApiInboxCheckResponseSchema = passthroughObject2({
44182
+ rows: external_exports.array(daemonApiInboxTargetRowSchema).optional()
44183
+ });
44184
+ var daemonApiWakeHintsQuerySchema = passthroughObject2({
44185
+ since: external_exports.union([external_exports.literal("latest"), external_exports.number().int().nonnegative(), external_exports.string().trim().min(1)]).optional(),
44186
+ limit: optionalQueryIntSchema
44187
+ });
44188
+ var daemonApiWakeHintSchema = passthroughObject2({
44189
+ hintId: optionalStringSchema2,
44190
+ hint_id: optionalStringSchema2,
44191
+ eventId: optionalStringSchema2,
44192
+ event_id: optionalStringSchema2,
44193
+ messageId: external_exports.string().nullable().optional(),
44194
+ message_id: external_exports.string().nullable().optional(),
44195
+ seq: optionalNonNegativeIntSchema,
44196
+ id: optionalStringSchema2,
44197
+ target: optionalStringSchema2,
44198
+ targetType: optionalStringSchema2,
44199
+ target_type: optionalStringSchema2,
44200
+ reason: optionalStringSchema2,
44201
+ wake_reason: optionalStringSchema2,
44202
+ createdAt: optionalStringSchema2,
44203
+ created_at: optionalStringSchema2
44204
+ });
44205
+ var daemonApiWakeHintsFetchResponseSchema = passthroughObject2({
44206
+ hints: external_exports.array(daemonApiWakeHintSchema).optional(),
44207
+ wake_hints: external_exports.array(daemonApiWakeHintSchema).optional(),
44208
+ last_seen_hint_seq: nullableNumberSchema2.optional(),
44209
+ last_hint_seq: nullableNumberSchema2.optional(),
44210
+ has_more: external_exports.boolean().optional()
44211
+ });
44212
+ var daemonApiActivityEventSchema = passthroughObject2({
44213
+ schema: optionalStringSchema2
44214
+ });
44215
+ var daemonApiActivityForwardBodySchema = passthroughObject2({
44216
+ schema: external_exports.literal("raft-agent-activity-ingest.v1"),
44217
+ coreSessionId: optionalStringSchema2,
44218
+ adapterInstance: optionalStringSchema2,
44219
+ events: external_exports.array(daemonApiActivityEventSchema),
44220
+ dropped: optionalNonNegativeIntSchema
44221
+ });
44222
+ var daemonApiActivityForwardResponseSchema = passthroughObject2({
44223
+ ok: external_exports.literal(true).optional(),
44224
+ acceptedCount: external_exports.number().int().nonnegative().optional(),
44225
+ rejectedCount: external_exports.number().int().nonnegative().optional(),
44226
+ droppedCount: external_exports.number().int().nonnegative().optional()
44227
+ });
44228
+ function route2(input) {
44229
+ return {
44230
+ ...input,
44231
+ fullPath: `${DAEMON_API_BASE_PATH}${input.path}`
44232
+ };
44233
+ }
44234
+ var daemonApiContract = {
44235
+ inboxCheck: route2({
44236
+ key: "inboxCheck",
44237
+ method: "GET",
44238
+ path: "/inbox",
44239
+ client: { resource: "inbox", method: "check" },
44240
+ description: "Read the managed-runner daemon inbox snapshot without draining message content.",
44241
+ request: {},
44242
+ response: { body: daemonApiInboxCheckResponseSchema }
44243
+ }),
44244
+ wakeHintsFetch: route2({
44245
+ key: "wakeHintsFetch",
44246
+ method: "GET",
44247
+ path: "/wake-hints",
44248
+ client: { resource: "wakeHints", method: "fetch" },
44249
+ description: "Peek content-free wake hints without advancing delivery cursors.",
44250
+ request: { query: daemonApiWakeHintsQuerySchema },
44251
+ response: { body: daemonApiWakeHintsFetchResponseSchema }
44252
+ }),
44253
+ activityForward: route2({
44254
+ key: "activityForward",
44255
+ method: "POST",
44256
+ path: "/activity",
44257
+ client: { resource: "activity", method: "forward" },
44258
+ description: "Forward plugin-observed activity from a local bridge to the daemon/server activity ingest path.",
44259
+ request: { body: daemonApiActivityForwardBodySchema },
44260
+ response: { body: daemonApiActivityForwardResponseSchema }
44261
+ })
44262
+ };
44263
+ function parseDaemonApiResponse(routeKey, data) {
44264
+ return daemonApiContract[routeKey].response.body.parse(data);
44265
+ }
44266
+
44267
+ // ../shared/src/daemonApiRawClient.ts
44268
+ init_esm_shims();
44269
+ function failure2(routeKey, reason, message, details = {}) {
44270
+ return {
44271
+ ok: false,
44272
+ ...routeKey ? { routeKey } : {},
44273
+ reason,
44274
+ message,
44275
+ ...details
44276
+ };
44277
+ }
44278
+ function encodeQuery2(routeKey, query) {
44279
+ if (query === void 0) return void 0;
44280
+ const route3 = daemonApiContract[routeKey];
44281
+ let parsed;
44282
+ try {
44283
+ parsed = "query" in route3.request ? route3.request.query.parse(query) : {};
44284
+ } catch (cause) {
44285
+ return failure2(routeKey, "request_contract_mismatch", `Daemon API ${route3.key} query did not match the shared contract`, { cause });
44286
+ }
44287
+ const params = new URLSearchParams();
44288
+ for (const [key, value] of Object.entries(parsed)) {
44289
+ if (value === void 0 || value === null) continue;
44290
+ if (Array.isArray(value)) {
44291
+ for (const item of value) params.append(key, String(item));
44292
+ continue;
44293
+ }
44294
+ params.set(key, String(value));
44295
+ }
44296
+ return params;
44297
+ }
44298
+ function parseBody2(routeKey, body) {
44299
+ if (body === void 0) return void 0;
44300
+ const route3 = daemonApiContract[routeKey];
44301
+ try {
44302
+ return "body" in route3.request ? route3.request.body.parse(body) : void 0;
44303
+ } catch (cause) {
44304
+ return failure2(routeKey, "request_contract_mismatch", `Daemon API ${route3.key} body did not match the shared contract`, { cause });
44305
+ }
44306
+ }
44307
+ function isDaemonApiRawFailure(value) {
44308
+ return Boolean(
44309
+ value && typeof value === "object" && value.ok === false && typeof value.reason === "string" && typeof value.message === "string"
44310
+ );
44311
+ }
44312
+ function buildDaemonApiRawRoutePath(routeKey, options = {}) {
44313
+ const route3 = daemonApiContract[routeKey];
44314
+ const query = encodeQuery2(routeKey, options.query);
44315
+ if (query && !(query instanceof URLSearchParams)) return query;
44316
+ const suffix = query && query.size > 0 ? `?${query.toString()}` : "";
44317
+ return `${options.pathPrefix ?? DAEMON_API_BASE_PATH}${route3.path}${suffix}`;
44318
+ }
44319
+ async function requestDaemonApiRawRoute(transport, routeKey, options = {}) {
44320
+ const route3 = daemonApiContract[routeKey];
44321
+ const path9 = buildDaemonApiRawRoutePath(routeKey, options);
44322
+ if (typeof path9 !== "string") return path9;
44323
+ const body = parseBody2(routeKey, options.body);
44324
+ if (isDaemonApiRawFailure(body)) return body;
44325
+ let response;
44326
+ try {
44327
+ response = await transport.request({
44328
+ routeKey,
44329
+ method: route3.method,
44330
+ path: path9,
44331
+ body
44332
+ });
44333
+ } catch (cause) {
44334
+ return failure2(routeKey, "transport_error", `Daemon API ${route3.key} transport request failed`, { cause });
44335
+ }
44336
+ if (!response.ok) {
44337
+ return failure2(routeKey, "http_error", response.error ?? `HTTP ${response.status}`, {
44338
+ status: response.status,
44339
+ errorCode: response.errorCode,
44340
+ suggestedNextAction: response.suggestedNextAction,
44341
+ response: response.data
44342
+ });
44343
+ }
44344
+ if (response.data === null) {
44345
+ return failure2(routeKey, "empty_response", `Daemon API ${route3.key} returned an empty response body`, {
44346
+ status: response.status
44347
+ });
44348
+ }
44349
+ try {
44350
+ return {
44351
+ ok: true,
44352
+ routeKey,
44353
+ status: response.status,
44354
+ data: parseDaemonApiResponse(routeKey, response.data)
44355
+ };
44356
+ } catch (cause) {
44357
+ return failure2(routeKey, "response_contract_mismatch", `Daemon API ${route3.key} response did not match the shared contract`, {
44358
+ status: response.status,
44359
+ cause,
44360
+ response: response.data
44361
+ });
44362
+ }
44363
+ }
44364
+ function requestOptionsFromMethodArgs2(routeKey, pathPrefix, args) {
44365
+ const route3 = daemonApiContract[routeKey];
44366
+ let index = 0;
44367
+ const requestOptions = { pathPrefix };
44368
+ if ("query" in route3.request) {
44369
+ requestOptions.query = args[index++];
44370
+ }
44371
+ if ("body" in route3.request) {
44372
+ requestOptions.body = args[index++];
44373
+ }
44374
+ return requestOptions;
44375
+ }
44376
+ function createDaemonApiRawClient(transport, options = {}) {
44377
+ const pathPrefix = options.pathPrefix ?? DAEMON_API_BASE_PATH;
44378
+ const client = {};
44379
+ for (const route3 of Object.values(daemonApiContract)) {
44380
+ const routeKey = route3.key;
44381
+ const { resource, method } = route3.client;
44382
+ const resourceClient = client[resource] ??= {};
44383
+ resourceClient[method] = (...args) => requestDaemonApiRawRoute(
44384
+ transport,
44385
+ routeKey,
44386
+ requestOptionsFromMethodArgs2(routeKey, pathPrefix, args)
44387
+ );
44388
+ }
44389
+ return client;
44390
+ }
44391
+
44392
+ // ../shared/src/daemonApiClient.ts
44393
+ init_esm_shims();
44394
+ function normalizeBaseUrl2(baseUrl) {
44395
+ return baseUrl.replace(/\/+$/, "");
44396
+ }
44397
+ function mergeHeaders2(...headers) {
44398
+ return Object.assign({}, ...headers.filter(Boolean));
44399
+ }
44400
+ async function authHeadersForRequest2(auth, request) {
44401
+ if (!auth) return void 0;
44402
+ return typeof auth === "function" ? auth(request) : auth;
44403
+ }
44404
+ async function parseFetchResponse2(response) {
44405
+ const text = await response.text();
44406
+ if (!text.trim()) return null;
44407
+ try {
44408
+ return JSON.parse(text);
44409
+ } catch {
44410
+ return text;
44411
+ }
44412
+ }
44413
+ function transportResponseFromFetch2(response, data) {
44414
+ if (response.ok) {
44415
+ return {
44416
+ ok: true,
44417
+ status: response.status,
44418
+ data,
44419
+ error: null
44420
+ };
44421
+ }
44422
+ const objectData = data && typeof data === "object" ? data : {};
44423
+ return {
44424
+ ok: false,
44425
+ status: response.status,
44426
+ data,
44427
+ error: typeof objectData.error === "string" ? objectData.error : response.statusText || `HTTP ${response.status}`,
44428
+ errorCode: typeof objectData.errorCode === "string" ? objectData.errorCode : null,
44429
+ suggestedNextAction: typeof objectData.suggestedNextAction === "string" ? objectData.suggestedNextAction : null
44430
+ };
44431
+ }
44432
+ function createDaemonApiFetchTransport(options) {
44433
+ const fetchImpl = options.fetch ?? fetch;
44434
+ const baseUrl = normalizeBaseUrl2(options.baseUrl);
44435
+ return {
44436
+ request: async (input) => {
44437
+ const authHeaders = await authHeadersForRequest2(options.auth, input);
44438
+ const headers = mergeHeaders2(
44439
+ { accept: "application/json" },
44440
+ input.body === void 0 ? void 0 : { "content-type": "application/json" },
44441
+ options.headers,
44442
+ authHeaders
44443
+ );
44444
+ const init = {
44445
+ method: input.method,
44446
+ headers,
44447
+ body: input.body === void 0 ? void 0 : JSON.stringify(input.body)
44448
+ };
44449
+ const response = await fetchImpl(`${baseUrl}${input.path}`, init);
44450
+ return transportResponseFromFetch2(response, await parseFetchResponse2(response));
44451
+ }
44452
+ };
44453
+ }
44454
+ function errorFromRawFailure2(failure3) {
44455
+ if (failure3.reason === "transport_error") {
44456
+ return {
44457
+ kind: "transport",
44458
+ reason: failure3.reason,
44459
+ message: failure3.message,
44460
+ cause: failure3.cause
44461
+ };
44462
+ }
44463
+ if (failure3.reason === "http_error") {
44464
+ return {
44465
+ kind: "http",
44466
+ reason: failure3.reason,
44467
+ message: failure3.message,
44468
+ status: failure3.status ?? 0,
44469
+ errorCode: failure3.errorCode,
44470
+ suggestedNextAction: failure3.suggestedNextAction,
44471
+ response: failure3.response
44472
+ };
44473
+ }
44474
+ return {
44475
+ kind: "validation",
44476
+ reason: failure3.reason,
44477
+ message: failure3.message,
44478
+ status: failure3.status,
44479
+ cause: failure3.cause,
44480
+ response: failure3.response
44481
+ };
44482
+ }
44483
+ function daemonApiClientResultFromRaw(result2) {
44484
+ if (result2.ok) {
44485
+ const success2 = result2;
44486
+ return {
44487
+ ok: true,
44488
+ routeKey: success2.routeKey,
44489
+ status: success2.status,
44490
+ data: success2.data
44491
+ };
44492
+ }
44493
+ return {
44494
+ ok: false,
44495
+ routeKey: result2.routeKey,
44496
+ status: result2.status,
44497
+ error: errorFromRawFailure2(result2)
44498
+ };
44499
+ }
44500
+ function wrapRawClient2(rawClient) {
44501
+ const client = {};
44502
+ for (const [resource, methods] of Object.entries(rawClient)) {
44503
+ client[resource] = {};
44504
+ for (const [method, rawMethod] of Object.entries(methods)) {
44505
+ client[resource][method] = async (...args) => daemonApiClientResultFromRaw(await rawMethod(...args));
44506
+ }
44507
+ }
44508
+ return client;
44509
+ }
44510
+ function createDaemonApiClient(transportOrOptions, maybeOptions = {}) {
44511
+ const options = "request" in transportOrOptions ? { ...maybeOptions, transport: transportOrOptions } : transportOrOptions;
44512
+ const transport = options.transport ?? (options.fetch ? createDaemonApiFetchTransport(options.fetch) : void 0);
44513
+ if (!transport) {
44514
+ throw new Error("createDaemonApiClient requires either a transport or fetch options");
44515
+ }
44516
+ const pathPrefix = options.pathPrefix ?? DAEMON_API_BASE_PATH;
44517
+ const rawClient = createDaemonApiRawClient(transport, { pathPrefix });
44518
+ const generated = wrapRawClient2(rawClient);
44519
+ return {
44520
+ ...generated,
44521
+ request: async (routeKey, requestOptions = {}) => daemonApiClientResultFromRaw(await requestDaemonApiRawRoute(transport, routeKey, {
44522
+ pathPrefix,
44523
+ ...requestOptions
44524
+ }))
44525
+ };
44526
+ }
44527
+
43966
44528
  // ../shared/src/agentInbox.ts
43967
44529
  init_esm_shims();
43968
44530
  function formatAgentInboxSnapshot(rows) {
@@ -44181,6 +44743,9 @@ init_esm_shims();
44181
44743
  // ../shared/src/agentScopes.ts
44182
44744
  init_esm_shims();
44183
44745
 
44746
+ // ../shared/src/docs/crossPageInvariants.ts
44747
+ init_esm_shims();
44748
+
44184
44749
  // ../shared/src/testing/failpoints.ts
44185
44750
  init_esm_shims();
44186
44751
  var NoopFailpointRegistry = class {
@@ -44314,13 +44879,15 @@ var RUNTIME_MODELS = {
44314
44879
  builtin: Object.values(PI_BUILTIN_PROVIDER_MODELS).flat().map((model) => ({ id: model.id, label: model.label || formatRuntimeProviderModelLabel(model.id), verified: "launchable" })),
44315
44880
  claude: [
44316
44881
  { id: "opus", label: "Claude Opus" },
44882
+ { id: "fable", label: "Claude Fable" },
44883
+ { id: "sonnet", label: "Claude Sonnet" },
44884
+ { id: "haiku", label: "Claude Haiku" },
44317
44885
  { id: "claude-opus-4-8", label: "Claude Opus 4.8" },
44318
44886
  { id: "claude-opus-4-7", label: "Claude Opus 4.7" },
44319
44887
  { id: "claude-opus-4-6", label: "Claude Opus 4.6" },
44320
- { id: "fable", label: "Claude Fable" },
44321
- { id: "sonnet", label: "Claude Sonnet" },
44888
+ { id: "claude-fable-5", label: "Claude Fable 5" },
44889
+ { id: "claude-sonnet-5", label: "Claude Sonnet 5" },
44322
44890
  { id: "claude-sonnet-4-6", label: "Claude Sonnet 4.6" },
44323
- { id: "haiku", label: "Claude Haiku" },
44324
44891
  { id: "claude-haiku-4-5", label: "Claude Haiku 4.5" }
44325
44892
  ],
44326
44893
  codex: [
@@ -44494,66 +45061,84 @@ function buildAgentApiEventsPath(query) {
44494
45061
  }
44495
45062
  function rawTransportForClient(client) {
44496
45063
  return {
44497
- request: async (input) => client.request(input.method, input.path, input.body)
45064
+ request: async (input) => {
45065
+ const route3 = agentApiContract[input.routeKey];
45066
+ if (getAgentApiResponseKind(route3.response) === "binary") {
45067
+ if (typeof client.requestBinary !== "function") {
45068
+ throw new CliError({
45069
+ code: "VIEW_FAILED",
45070
+ message: "Agent API binary download transport is unavailable in this CLI context"
45071
+ });
45072
+ }
45073
+ const response = await client.requestBinary(input.method, input.path);
45074
+ return {
45075
+ ok: response.ok,
45076
+ status: response.status,
45077
+ data: response.ok ? response.body : null,
45078
+ error: response.error
45079
+ };
45080
+ }
45081
+ return client.request(input.method, input.path, input.body);
45082
+ }
44498
45083
  };
44499
45084
  }
44500
- function cliErrorFromRawFailure(failure2) {
44501
- switch (failure2.reason) {
45085
+ function cliErrorFromRawFailure(failure3) {
45086
+ switch (failure3.reason) {
44502
45087
  case "missing_path_param":
44503
45088
  case "request_contract_mismatch":
44504
45089
  return new CliError({
44505
45090
  code: "INVALID_ARG",
44506
- message: failure2.message,
44507
- cause: failure2.cause
45091
+ message: failure3.message,
45092
+ cause: failure3.cause
44508
45093
  });
44509
45094
  case "empty_response":
44510
45095
  case "response_contract_mismatch":
44511
45096
  case "missing_route":
44512
45097
  return new CliError({
44513
45098
  code: "INVALID_JSON_RESPONSE",
44514
- message: failure2.message,
44515
- cause: failure2.cause
45099
+ message: failure3.message,
45100
+ cause: failure3.cause
44516
45101
  });
44517
45102
  case "transport_error":
44518
45103
  case "http_error":
44519
45104
  return new CliError({
44520
45105
  code: "CHECK_FAILED",
44521
- message: failure2.message,
44522
- cause: failure2.cause
45106
+ message: failure3.message,
45107
+ cause: failure3.cause
44523
45108
  });
44524
45109
  }
44525
45110
  }
44526
- function cliErrorFromClientFailure(failure2) {
44527
- switch (failure2.error.kind) {
45111
+ function cliErrorFromClientFailure(failure3) {
45112
+ switch (failure3.error.kind) {
44528
45113
  case "validation":
44529
- switch (failure2.error.reason) {
45114
+ switch (failure3.error.reason) {
44530
45115
  case "missing_path_param":
44531
45116
  case "request_contract_mismatch":
44532
45117
  return new CliError({
44533
45118
  code: "INVALID_ARG",
44534
- message: failure2.error.message,
44535
- cause: failure2.error.cause
45119
+ message: failure3.error.message,
45120
+ cause: failure3.error.cause
44536
45121
  });
44537
45122
  case "empty_response":
44538
45123
  case "response_contract_mismatch":
44539
45124
  case "missing_route":
44540
45125
  return new CliError({
44541
45126
  code: "INVALID_JSON_RESPONSE",
44542
- message: failure2.error.message,
44543
- cause: failure2.error.cause
45127
+ message: failure3.error.message,
45128
+ cause: failure3.error.cause
44544
45129
  });
44545
45130
  }
44546
45131
  break;
44547
45132
  case "transport":
44548
45133
  return new CliError({
44549
45134
  code: "CHECK_FAILED",
44550
- message: failure2.error.message,
44551
- cause: failure2.error.cause
45135
+ message: failure3.error.message,
45136
+ cause: failure3.error.cause
44552
45137
  });
44553
45138
  case "http":
44554
45139
  return new CliError({
44555
45140
  code: "CHECK_FAILED",
44556
- message: failure2.error.message
45141
+ message: failure3.error.message
44557
45142
  });
44558
45143
  }
44559
45144
  }
@@ -44615,38 +45200,20 @@ async function requestMultipartContractAgentApiRoute(client, routeKey, form) {
44615
45200
  });
44616
45201
  }
44617
45202
  }
44618
- function createAgentApiClient2(client, agentId) {
44619
- const agentApi = createAgentApiClient(rawTransportForClient(client), {
44620
- pathPrefix: buildLegacyAgentApiPath(agentId, "")
44621
- });
45203
+ function createAgentApiSurfaceClient(client) {
45204
+ const agentApi = createAgentApiClient(rawTransportForClient(client));
44622
45205
  return {
44623
45206
  server: {
44624
45207
  info: () => requestClientAsApiResponse(agentApi.server.info())
44625
45208
  },
45209
+ events: {
45210
+ get: (query) => requestClientAsApiResponse(agentApi.events.get(query))
45211
+ },
44626
45212
  history: {
44627
45213
  read: (query) => requestClientAsApiResponse(agentApi.history.read(query))
44628
45214
  },
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))
45215
+ knowledge: {
45216
+ get: (query) => requestClientAsApiResponse(agentApi.knowledge.get(query))
44650
45217
  },
44651
45218
  tasks: {
44652
45219
  list: (query) => requestClientAsApiResponse(agentApi.tasks.list(query)),
@@ -44664,9 +45231,17 @@ function createAgentApiSurfaceClient(client) {
44664
45231
  log: (params) => requestClientAsApiResponse(agentApi.reminders.log(params))
44665
45232
  },
44666
45233
  messages: {
44667
- search: (query) => requestClientAsApiResponse(agentApi.messages.search(query))
45234
+ send: (body) => requestClientAsApiResponse(agentApi.messages.send(body)),
45235
+ resolve: (params) => requestClientAsApiResponse(agentApi.messages.resolve(params)),
45236
+ search: (query) => requestClientAsApiResponse(agentApi.messages.search(query)),
45237
+ addReaction: (params, body) => requestClientAsApiResponse(agentApi.messages.addReaction(params, body)),
45238
+ removeReaction: (params, body) => requestClientAsApiResponse(agentApi.messages.removeReaction(params, body))
44668
45239
  },
44669
45240
  channels: {
45241
+ join: (params) => requestClientAsApiResponse(agentApi.channels.join(params)),
45242
+ leave: (params) => requestClientAsApiResponse(agentApi.channels.leave(params)),
45243
+ mute: (params) => requestClientAsApiResponse(agentApi.channels.mute(params)),
45244
+ unmute: (params) => requestClientAsApiResponse(agentApi.channels.unmute(params)),
44670
45245
  members: (query) => requestClientAsApiResponse(agentApi.channels.members(query)),
44671
45246
  resolve: (body) => requestClientAsApiResponse(agentApi.channels.resolve(body))
44672
45247
  },
@@ -44675,18 +45250,27 @@ function createAgentApiSurfaceClient(client) {
44675
45250
  },
44676
45251
  profile: {
44677
45252
  show: (query) => requestClientAsApiResponse(agentApi.profile.show(query)),
44678
- update: (body) => requestClientAsApiResponse(agentApi.profile.update(body))
45253
+ update: (body) => requestClientAsApiResponse(agentApi.profile.update(body)),
45254
+ updateAvatar: (form) => requestMultipartContractAgentApiRoute(client, "profileAvatarUpdate", form)
44679
45255
  },
44680
45256
  integrations: {
44681
45257
  list: () => requestClientAsApiResponse(agentApi.integrations.list()),
44682
45258
  login: (body) => requestClientAsApiResponse(agentApi.integrations.login(body)),
44683
- prepareApp: (body) => requestClientAsApiResponse(agentApi.integrations.prepareApp(body))
45259
+ prepareApp: (body) => requestClientAsApiResponse(agentApi.integrations.prepareApp(body)),
45260
+ rotateAppSecret: (body) => requestClientAsApiResponse(agentApi.integrations.rotateAppSecret(body))
44684
45261
  },
44685
45262
  actions: {
44686
45263
  prepare: (body) => requestClientAsApiResponse(agentApi.actions.prepare(body))
44687
45264
  },
45265
+ mentions: {
45266
+ pendingActions: (query) => requestClientAsApiResponse(agentApi.mentions.pendingActions(query ?? {})),
45267
+ executeAction: (body) => requestClientAsApiResponse(agentApi.mentions.executeAction(body))
45268
+ },
44688
45269
  attachments: {
44689
- upload: (form) => requestMultipartContractAgentApiRoute(client, "attachmentUpload", form)
45270
+ upload: (form) => requestMultipartContractAgentApiRoute(client, "attachmentUpload", form),
45271
+ download: (params) => requestClientAsApiResponse(agentApi.attachments.download(params)),
45272
+ view: (params) => requestClientAsApiResponse(agentApi.attachments.download(params)),
45273
+ comments: (params, query = {}) => requestClientAsApiResponse(agentApi.attachments.comments(params, query))
44690
45274
  }
44691
45275
  };
44692
45276
  }
@@ -44782,7 +45366,6 @@ function routeFamilyForPath(pathname) {
44782
45366
  if (normalized === "/internal/agent-api/activity") return "agent-api/activity";
44783
45367
  if (normalized === "/internal/agent-api/events") return "agent-api/events";
44784
45368
  if (normalized === "/internal/agent-api/inbox") return "agent-api/inbox";
44785
- if (normalized === "/internal/agent-api/receive-ack") return "agent-api/events";
44786
45369
  if (normalized === "/internal/agent-api/tasks/claim") return "tasks/claim";
44787
45370
  if (normalized === "/internal/agent-api/tasks/update-status") return "tasks/update";
44788
45371
  if (normalized === "/internal/agent-api/tasks" || normalized.startsWith("/internal/agent-api/tasks/")) {
@@ -44812,7 +45395,7 @@ function routeFamilyForPath(pathname) {
44812
45395
  const firstAfterAgentId = parts[3] ?? "unknown";
44813
45396
  if (firstAfterAgentId === "server") return "server";
44814
45397
  if (firstAfterAgentId === "send") return "agent-api/send";
44815
- if (firstAfterAgentId === "history" || firstAfterAgentId === "search" || firstAfterAgentId === "receive" || firstAfterAgentId === "receive-ack") {
45398
+ if (firstAfterAgentId === "history" || firstAfterAgentId === "search" || firstAfterAgentId === "receive") {
44816
45399
  return "agent-api/events";
44817
45400
  }
44818
45401
  if (firstAfterAgentId === "channel-members") return "channel-members";
@@ -44917,6 +45500,7 @@ var ApiClient = class {
44917
45500
  if (!pathname.startsWith(agentPrefix)) return pathname;
44918
45501
  const suffix = pathname.slice(agentPrefix.length);
44919
45502
  if (suffix === "/server") return "/internal/agent-api/server";
45503
+ if (suffix === "/server/avatar") return "/internal/agent-api/server/avatar";
44920
45504
  if (suffix === "/send") return "/internal/agent-api/send";
44921
45505
  if (suffix.startsWith("/history")) return `/internal/agent-api/history${suffix.slice("/history".length)}`;
44922
45506
  if (suffix.startsWith("/search")) return `/internal/agent-api/search${suffix.slice("/search".length)}`;
@@ -44934,6 +45518,7 @@ var ApiClient = class {
44934
45518
  if (suffix === "/resolve-channel") return "/internal/agent-api/resolve-channel";
44935
45519
  if (suffix === "/threads/unfollow") return "/internal/agent-api/threads/unfollow";
44936
45520
  if (suffix === "/prepare-action") return "/internal/agent-api/prepare-action";
45521
+ if (suffix === "/channels") return "/internal/agent-api/channels";
44937
45522
  if (suffix === "/tasks" || suffix.startsWith("/tasks?") || suffix.startsWith("/tasks/")) {
44938
45523
  return `/internal/agent-api${suffix}`;
44939
45524
  }
@@ -44954,6 +45539,14 @@ var ApiClient = class {
44954
45539
  if (channelMembership) {
44955
45540
  return `/internal/agent-api/channels/${channelMembership[1]}/${channelMembership[2]}`;
44956
45541
  }
45542
+ const channelUpdate = /^\/channels\/([^/]+)$/.exec(suffix);
45543
+ if (channelUpdate) {
45544
+ return `/internal/agent-api/channels/${channelUpdate[1]}`;
45545
+ }
45546
+ const channelAddMember = /^\/channels\/([^/]+)\/members$/.exec(suffix);
45547
+ if (channelAddMember) {
45548
+ return `/internal/agent-api/channels/${channelAddMember[1]}/members`;
45549
+ }
44957
45550
  return pathname;
44958
45551
  }
44959
45552
  normalizeAgentCredentialResponse(pathname, data) {
@@ -45093,10 +45686,7 @@ var ApiClient = class {
45093
45686
  const res = await this.fetchWithTransportTrace(url2, pathname, init);
45094
45687
  return this.parseJsonResponse(res);
45095
45688
  }
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) {
45689
+ async requestBody(method, pathname) {
45100
45690
  pathname = this.rewriteAgentCredentialPath(pathname);
45101
45691
  const url2 = new URL(pathname, this.ctx.serverUrl);
45102
45692
  const dispatcher = buildFetchDispatcher(url2.toString());
@@ -45123,6 +45713,21 @@ var ApiClient = class {
45123
45713
  }
45124
45714
  return { ok: res.ok, status: res.status, response: res, error: error48 };
45125
45715
  }
45716
+ async requestBinary(method, pathname) {
45717
+ const res = await this.requestBody(method, pathname);
45718
+ if (!res.ok) {
45719
+ return { ok: false, status: res.status, body: new Uint8Array(), error: res.error };
45720
+ }
45721
+ return {
45722
+ ok: true,
45723
+ status: res.status,
45724
+ body: new Uint8Array(await res.response.arrayBuffer()),
45725
+ error: null
45726
+ };
45727
+ }
45728
+ async streamWakeHints(query) {
45729
+ return this.requestBody("GET", `/internal/agent-api/wake-hints/stream?${query.toString()}`);
45730
+ }
45126
45731
  };
45127
45732
 
45128
45733
  // src/auth/env.ts
@@ -45196,21 +45801,21 @@ function readProfileCredential(slug, env) {
45196
45801
  }
45197
45802
  return { filePath, data: parsed };
45198
45803
  }
45199
- function readTokenFromFile(filePath) {
45804
+ function readTokenFromFile(filePath, envName) {
45200
45805
  let raw;
45201
45806
  try {
45202
45807
  raw = fs.readFileSync(filePath, "utf-8");
45203
45808
  } catch (err) {
45204
45809
  throw new AgentBootstrapError(
45205
45810
  "TOKEN_FILE_UNREADABLE",
45206
- `SLOCK_AGENT_TOKEN_FILE=${filePath} could not be read: ${err.message}`
45811
+ `${envName}=${filePath} could not be read: ${err.message}`
45207
45812
  );
45208
45813
  }
45209
45814
  const token = raw.trim();
45210
45815
  if (!token) {
45211
45816
  throw new AgentBootstrapError(
45212
45817
  "TOKEN_FILE_EMPTY",
45213
- `SLOCK_AGENT_TOKEN_FILE=${filePath} is empty`
45818
+ `${envName}=${filePath} is empty`
45214
45819
  );
45215
45820
  }
45216
45821
  return token;
@@ -45263,7 +45868,7 @@ function loadAgentContext(env = process.env) {
45263
45868
  "Set only one of SLOCK_AGENT_PROXY_TOKEN or SLOCK_AGENT_PROXY_TOKEN_FILE"
45264
45869
  );
45265
45870
  }
45266
- const token = agentProxyToken ?? (agentProxyTokenFile ? readTokenFromFile(agentProxyTokenFile) : null);
45871
+ const token = agentProxyToken ?? (agentProxyTokenFile ? readTokenFromFile(agentProxyTokenFile, "SLOCK_AGENT_PROXY_TOKEN_FILE") : null);
45267
45872
  if (!token) {
45268
45873
  throw new AgentBootstrapError(
45269
45874
  "MISSING_AGENT_PROXY_TOKEN",
@@ -45281,32 +45886,16 @@ function loadAgentContext(env = process.env) {
45281
45886
  };
45282
45887
  }
45283
45888
  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
45889
  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
- };
45890
+ if (tokenFile || tokenLiteral) {
45891
+ throw new AgentBootstrapError(
45892
+ "LEGACY_MACHINE_UNSUPPORTED",
45893
+ "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`."
45894
+ );
45306
45895
  }
45307
45896
  throw new AgentBootstrapError(
45308
45897
  "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."
45898
+ "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
45899
  );
45311
45900
  }
45312
45901
 
@@ -46184,6 +46773,84 @@ function describeMintError(code, serverUrl) {
46184
46773
  // src/commands/agent/bridge.ts
46185
46774
  init_esm_shims();
46186
46775
 
46776
+ // src/daemonApiPath.ts
46777
+ init_esm_shims();
46778
+ function rawTransportForClient2(client) {
46779
+ return {
46780
+ request: (input) => client.request(input.method, input.path, input.body)
46781
+ };
46782
+ }
46783
+ function cliErrorFromClientFailure2(failure3) {
46784
+ switch (failure3.error.kind) {
46785
+ case "validation":
46786
+ switch (failure3.error.reason) {
46787
+ case "request_contract_mismatch":
46788
+ return new CliError({
46789
+ code: "INVALID_ARG",
46790
+ message: failure3.error.message,
46791
+ cause: failure3.error.cause
46792
+ });
46793
+ case "empty_response":
46794
+ case "response_contract_mismatch":
46795
+ return new CliError({
46796
+ code: "INVALID_JSON_RESPONSE",
46797
+ message: failure3.error.message,
46798
+ cause: failure3.error.cause
46799
+ });
46800
+ }
46801
+ break;
46802
+ case "transport":
46803
+ return new CliError({
46804
+ code: "CHECK_FAILED",
46805
+ message: failure3.error.message,
46806
+ cause: failure3.error.cause
46807
+ });
46808
+ case "http":
46809
+ return new CliError({
46810
+ code: "CHECK_FAILED",
46811
+ message: failure3.error.message
46812
+ });
46813
+ }
46814
+ }
46815
+ function apiResponseFromClientResult2(result2) {
46816
+ if (result2.ok) {
46817
+ return {
46818
+ ok: true,
46819
+ status: result2.status,
46820
+ data: result2.data,
46821
+ error: null
46822
+ };
46823
+ }
46824
+ if (result2.error.kind === "http") {
46825
+ return {
46826
+ ok: false,
46827
+ status: result2.error.status,
46828
+ data: null,
46829
+ error: result2.error.message,
46830
+ errorCode: result2.error.errorCode,
46831
+ suggestedNextAction: result2.error.suggestedNextAction
46832
+ };
46833
+ }
46834
+ throw cliErrorFromClientFailure2(result2);
46835
+ }
46836
+ async function requestClientAsApiResponse2(result2) {
46837
+ return apiResponseFromClientResult2(await result2);
46838
+ }
46839
+ function createDaemonApiSurfaceClient(client) {
46840
+ const daemonApi = createDaemonApiClient(rawTransportForClient2(client));
46841
+ return {
46842
+ inbox: {
46843
+ check: () => requestClientAsApiResponse2(daemonApi.inbox.check())
46844
+ },
46845
+ wakeHints: {
46846
+ fetch: (query) => requestClientAsApiResponse2(daemonApi.wakeHints.fetch(query))
46847
+ },
46848
+ activity: {
46849
+ forward: (body) => requestClientAsApiResponse2(daemonApi.activity.forward(body))
46850
+ }
46851
+ };
46852
+ }
46853
+
46187
46854
  // src/agentCommsCore/bridge.ts
46188
46855
  init_esm_shims();
46189
46856
  import fs2 from "fs";
@@ -46994,17 +47661,17 @@ function statusFailureClass(status) {
46994
47661
  if (status === 404 || status === 410) return "no_session";
46995
47662
  return "injection_failed";
46996
47663
  }
46997
- function buildRaftChannelWakeFailedEvent(input, failure2) {
47664
+ function buildRaftChannelWakeFailedEvent(input, failure3) {
46998
47665
  return validateExternalAgentWakeEventEnvelope({
46999
47666
  ...input,
47000
47667
  schema: "slock-external-agent-wake-event.v1",
47001
47668
  kind: "wake_attempt",
47002
47669
  outcome: "failed",
47003
47670
  failureMeta: {
47004
- failureClass: failure2.failureClass,
47005
- ...failure2.retryAfterMs ? { retryAfterMs: failure2.retryAfterMs } : {}
47671
+ failureClass: failure3.failureClass,
47672
+ ...failure3.retryAfterMs ? { retryAfterMs: failure3.retryAfterMs } : {}
47006
47673
  },
47007
- reason: failure2.reason,
47674
+ reason: failure3.reason,
47008
47675
  lifecycleState: "degraded_backoff",
47009
47676
  authority: {
47010
47677
  source: "wake_adapter",
@@ -47049,11 +47716,12 @@ var agentBridgeCommand = defineCommand(
47049
47716
  const limit = parsePositiveInt(options.limit, 50, "limit");
47050
47717
  const activityDrainLimit = parsePositiveInt(options.activityDrainLimit, 50, "activity-drain-limit");
47051
47718
  const client = ctx.createApiClient(agentContext);
47052
- const pollSource = createAgentApiWakeHintSource(client);
47053
- const streamSource = options.once ? null : createAgentApiWakeHintStreamSource(client, ctx.env);
47719
+ const daemonApi = createDaemonApiSurfaceClient(client);
47720
+ const pollSource = createDaemonApiWakeHintSource(daemonApi);
47721
+ const streamSource = options.once ? null : createDaemonApiWakeHintStreamSource(client, ctx.env);
47054
47722
  const wakeAdapter = createWakeAdapter(options, ctx.env);
47055
47723
  const activitySource = createActivityDrainSource(options, ctx.env);
47056
- const activitySink = activitySource ? createAgentApiActivitySink(client) : void 0;
47724
+ const activitySink = activitySource ? createDaemonApiActivitySink(daemonApi) : void 0;
47057
47725
  let bridgeLock;
47058
47726
  try {
47059
47727
  bridgeLock = acquireAgentCommsBridgeLock({
@@ -47212,14 +47880,13 @@ var agentBridgeCommand = defineCommand(
47212
47880
  function registerAgentBridgeCommand(parent, runtimeOptions) {
47213
47881
  registerCliCommand(parent, agentBridgeCommand, runtimeOptions);
47214
47882
  }
47215
- function createAgentApiWakeHintSource(client) {
47883
+ function createDaemonApiWakeHintSource(client) {
47216
47884
  return {
47217
47885
  async fetchWakeHints(input) {
47218
- const query = new URLSearchParams({
47219
- since: String(input.since),
47220
- limit: String(input.limit)
47886
+ const response = await client.wakeHints.fetch({
47887
+ since: input.since,
47888
+ limit: input.limit
47221
47889
  });
47222
- const response = await client.request("GET", `/internal/agent-api/wake-hints?${query.toString()}`);
47223
47890
  if (!response.ok) {
47224
47891
  throw new CliError({
47225
47892
  code: response.status >= 500 ? "SERVER_5XX" : "BRIDGE_WAKE_HINTS_FAILED",
@@ -47234,8 +47901,8 @@ function createAgentApiWakeHintSource(client) {
47234
47901
  }
47235
47902
  };
47236
47903
  }
47237
- function createAgentApiWakeHintStreamSource(client, env = process.env) {
47238
- if (!client.requestRaw) return null;
47904
+ function createDaemonApiWakeHintStreamSource(client, env = process.env) {
47905
+ if (!client.streamWakeHints) return null;
47239
47906
  let reader = null;
47240
47907
  let bufferedText = "";
47241
47908
  let pendingEvent = {};
@@ -47250,7 +47917,7 @@ function createAgentApiWakeHintStreamSource(client, env = process.env) {
47250
47917
  async function ensureReader(since) {
47251
47918
  if (reader) return reader;
47252
47919
  const query = new URLSearchParams({ since: String(since) });
47253
- const response = await client.requestRaw("GET", `/internal/agent-api/wake-hints/stream?${query.toString()}`);
47920
+ const response = await client.streamWakeHints(query);
47254
47921
  if (!response.ok) {
47255
47922
  throw new CliError({
47256
47923
  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 +48102,10 @@ function createActivityDrainSource(options, env = process.env) {
47435
48102
  }
47436
48103
  };
47437
48104
  }
47438
- function createAgentApiActivitySink(client) {
48105
+ function createDaemonApiActivitySink(client) {
47439
48106
  return {
47440
48107
  async forwardActivity(input) {
47441
- const response = await client.request("POST", "/internal/agent-api/activity", input);
48108
+ const response = await client.activity.forward(input);
47442
48109
  if (!response.ok) {
47443
48110
  throw new CliError({
47444
48111
  code: response.status >= 500 ? "SERVER_5XX" : "BRIDGE_ACTIVITY_FORWARD_FAILED",
@@ -47576,6 +48243,9 @@ function formatRuntimeContext(ctx) {
47576
48243
  "Authoritative context for this agent process. Do not infer computer identity from hostname or cwd when this section is present."
47577
48244
  ];
47578
48245
  if (ctx.agentId) lines.push(`- Agent ID: ${ctx.agentId}`);
48246
+ if (ctx.runtime) lines.push(`- Runtime: ${ctx.runtime}`);
48247
+ if (ctx.model) lines.push(`- Model: ${ctx.model}`);
48248
+ if (ctx.reasoningEffort) lines.push(`- Reasoning: ${ctx.reasoningEffort}`);
47579
48249
  if (ctx.serverId) lines.push(`- Server ID: ${ctx.serverId}`);
47580
48250
  if (ctx.machineName || ctx.machineId) {
47581
48251
  const label = ctx.machineName && ctx.machineId ? `${ctx.machineName} (${ctx.machineId})` : ctx.machineName || ctx.machineId;
@@ -47589,14 +48259,26 @@ function formatRuntimeContext(ctx) {
47589
48259
 
47590
48260
  ` : "";
47591
48261
  }
48262
+ function roleLabel(role) {
48263
+ return role && role !== "member" ? ` (${role})` : "";
48264
+ }
48265
+ function formatCurrentAgent(data) {
48266
+ if (!data.serverRole) return "";
48267
+ const lines = ["### Current Agent"];
48268
+ lines.push(`- Role: ${data.serverRole}`);
48269
+ return `${lines.join("\n")}
48270
+
48271
+ `;
48272
+ }
47592
48273
  function formatServerInfo(data) {
47593
48274
  let text = "## Server\n\n";
47594
48275
  const channels = data.channels ?? [];
47595
48276
  const agents = data.agents ?? [];
47596
48277
  const humans = data.humans ?? [];
47597
48278
  text += formatRuntimeContext(data.runtimeContext);
48279
+ text += formatCurrentAgent(data);
47598
48280
  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';
48281
+ 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
48282
  if (channels.length > 0) {
47601
48283
  for (const t of channels) {
47602
48284
  const visibility = t.type === "private" ? "private" : "public";
@@ -47610,10 +48292,12 @@ function formatServerInfo(data) {
47610
48292
  }
47611
48293
  text += "\n### Agents\n";
47612
48294
  text += "Other AI agents in this server.\n";
48295
+ text += "Role labels show server-level owner/admin authority; no role label means ordinary member.\n";
47613
48296
  if (agents.length > 0) {
47614
48297
  for (const a of agents) {
47615
- text += a.description ? ` - @${a.name} (${a.status}) \u2014 ${a.description}
47616
- ` : ` - @${a.name} (${a.status})
48298
+ const role = roleLabel(a.role);
48299
+ text += a.description ? ` - @${a.name} (${a.status})${role} \u2014 ${a.description}
48300
+ ` : ` - @${a.name} (${a.status})${role}
47617
48301
  `;
47618
48302
  }
47619
48303
  } else {
@@ -47622,10 +48306,12 @@ function formatServerInfo(data) {
47622
48306
  text += "\n### Humans\n";
47623
48307
  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
48308
  `;
48309
+ text += "Role labels show server-level owner/admin authority; no role label means ordinary member.\n";
47625
48310
  if (humans.length > 0) {
47626
48311
  for (const u of humans) {
47627
- text += u.description ? ` - @${u.name} \u2014 ${u.description}
47628
- ` : ` - @${u.name}
48312
+ const role = roleLabel(u.role);
48313
+ text += u.description ? ` - @${u.name}${role} \u2014 ${u.description}
48314
+ ` : ` - @${u.name}${role}
47629
48315
  `;
47630
48316
  }
47631
48317
  } else {
@@ -47643,10 +48329,12 @@ function formatChannelMembers(data) {
47643
48329
  `;
47644
48330
  text += "Members means join/post authority for this surface.\n\n";
47645
48331
  text += "### Agents\n";
48332
+ text += "Role labels show server-level owner/admin authority; no role label means ordinary member.\n";
47646
48333
  if (agents.length > 0) {
47647
48334
  for (const a of agents) {
47648
- text += a.description ? ` - @${a.name} (${a.status}) \u2014 ${a.description}
47649
- ` : ` - @${a.name} (${a.status})
48335
+ const role = roleLabel(a.role);
48336
+ text += a.description ? ` - @${a.name} (${a.status})${role} \u2014 ${a.description}
48337
+ ` : ` - @${a.name} (${a.status})${role}
47650
48338
  `;
47651
48339
  }
47652
48340
  } else {
@@ -47656,7 +48344,7 @@ function formatChannelMembers(data) {
47656
48344
  text += "Role labels show server-level owner/admin authority; no role label means ordinary member.\n";
47657
48345
  if (humans.length > 0) {
47658
48346
  for (const u of humans) {
47659
- const role = u.role && u.role !== "member" ? ` (${u.role})` : "";
48347
+ const role = roleLabel(u.role);
47660
48348
  text += u.description ? ` - @${u.name}${role} \u2014 ${u.description}
47661
48349
  ` : ` - @${u.name}${role}
47662
48350
  `;
@@ -47699,7 +48387,68 @@ function registerChannelMembersCommand(parent, runtimeOptions) {
47699
48387
  registerCliCommand(parent, channelMembersCommand, runtimeOptions);
47700
48388
  }
47701
48389
 
47702
- // src/commands/channel/join.ts
48390
+ // src/commands/channel/create.ts
48391
+ init_esm_shims();
48392
+ function normalizeChannelName(raw) {
48393
+ return (raw ?? "").trim().replace(/^#/, "");
48394
+ }
48395
+ function formatCreateChannelResult(channel) {
48396
+ const target = `#${channel.name}`;
48397
+ const visibility = channel.type === "private" ? "private" : "public";
48398
+ return `Created ${target} (${visibility}). You are joined and can send messages there.`;
48399
+ }
48400
+ var channelCreateCommand = defineCommand(
48401
+ {
48402
+ name: "create",
48403
+ description: "Create a public or private channel when this agent has server admin authority",
48404
+ options: [
48405
+ {
48406
+ flags: "--name <name>",
48407
+ description: "Channel name, with or without a leading '#'"
48408
+ },
48409
+ {
48410
+ flags: "--description <description>",
48411
+ description: "Optional channel description"
48412
+ },
48413
+ {
48414
+ flags: "--private",
48415
+ description: "Create a private channel instead of a public channel"
48416
+ }
48417
+ ]
48418
+ },
48419
+ async (ctx, opts) => {
48420
+ const name = normalizeChannelName(opts.name);
48421
+ if (!name) {
48422
+ throw new CliError({
48423
+ code: "INVALID_ARG",
48424
+ message: "--name is required"
48425
+ });
48426
+ }
48427
+ const agentContext = ctx.loadAgentContext();
48428
+ const client = ctx.createApiClient(agentContext);
48429
+ const res = await client.request(
48430
+ "POST",
48431
+ `/internal/agent/${encodeURIComponent(agentContext.agentId)}/channels`,
48432
+ {
48433
+ name,
48434
+ description: opts.description,
48435
+ visibility: opts.private ? "private" : "public"
48436
+ }
48437
+ );
48438
+ if (!res.ok || !res.data) {
48439
+ throw new CliError({
48440
+ code: res.status >= 500 ? "SERVER_5XX" : "CREATE_FAILED",
48441
+ message: res.error ?? `HTTP ${res.status}`
48442
+ });
48443
+ }
48444
+ writeText(ctx.io, formatCreateChannelResult(res.data) + "\n");
48445
+ }
48446
+ );
48447
+ function registerChannelCreateCommand(parent, runtimeOptions) {
48448
+ registerCliCommand(parent, channelCreateCommand, runtimeOptions);
48449
+ }
48450
+
48451
+ // src/commands/channel/update.ts
47703
48452
  init_esm_shims();
47704
48453
 
47705
48454
  // src/commands/channel/leave.ts
@@ -47738,7 +48487,8 @@ var channelLeaveCommand = defineCommand(
47738
48487
  }
47739
48488
  const agentContext = ctx.loadAgentContext();
47740
48489
  const client = ctx.createApiClient(agentContext);
47741
- const infoRes = await createAgentApiClient2(client, agentContext.agentId).server.info();
48490
+ const agentApi = createAgentApiSurfaceClient(client);
48491
+ const infoRes = await agentApi.server.info();
47742
48492
  if (!infoRes.ok) {
47743
48493
  throw new CliError({
47744
48494
  code: infoRes.status >= 500 ? "SERVER_5XX" : "INFO_FAILED",
@@ -47756,7 +48506,7 @@ var channelLeaveCommand = defineCommand(
47756
48506
  writeText(ctx.io, formatAlreadyNotJoined(target) + "\n");
47757
48507
  return;
47758
48508
  }
47759
- const leaveRes = await createAgentApiClient2(client, agentContext.agentId).channels.leave({
48509
+ const leaveRes = await agentApi.channels.leave({
47760
48510
  channelId: channel.id
47761
48511
  });
47762
48512
  if (!leaveRes.ok) {
@@ -47772,7 +48522,278 @@ function registerChannelLeaveCommand(parent, runtimeOptions) {
47772
48522
  registerCliCommand(parent, channelLeaveCommand, runtimeOptions);
47773
48523
  }
47774
48524
 
48525
+ // src/commands/channel/update.ts
48526
+ function normalizeChannelName2(raw) {
48527
+ return (raw ?? "").trim().replace(/^#/, "");
48528
+ }
48529
+ function formatUpdateChannelResult(channel) {
48530
+ const visibility = channel.type === "private" ? "private" : "public";
48531
+ return `Updated #${channel.name} (${visibility}).`;
48532
+ }
48533
+ var channelUpdateCommand = defineCommand(
48534
+ {
48535
+ name: "update",
48536
+ description: "Edit a regular channel when this agent has server admin authority",
48537
+ options: [
48538
+ {
48539
+ flags: "--target <target>",
48540
+ description: "Regular channel to edit, e.g. '#engineering'"
48541
+ },
48542
+ {
48543
+ flags: "--name <name>",
48544
+ description: "New channel name, with or without a leading '#'"
48545
+ },
48546
+ {
48547
+ flags: "--description <description>",
48548
+ description: "New channel description"
48549
+ },
48550
+ {
48551
+ flags: "--public",
48552
+ description: "Make the channel public"
48553
+ },
48554
+ {
48555
+ flags: "--private",
48556
+ description: "Make the channel private"
48557
+ }
48558
+ ]
48559
+ },
48560
+ async (ctx, opts) => {
48561
+ const target = opts.target ?? "";
48562
+ const channelName = parseRegularChannelTarget(target);
48563
+ if (!channelName) {
48564
+ throw new CliError({
48565
+ code: "INVALID_TARGET",
48566
+ message: "Target must be a regular channel in the form '#channel-name'. DMs and thread targets are not supported."
48567
+ });
48568
+ }
48569
+ if (opts.public && opts.private) {
48570
+ throw new CliError({
48571
+ code: "INVALID_ARG",
48572
+ message: "Use either --public or --private, not both."
48573
+ });
48574
+ }
48575
+ const body = {};
48576
+ if (opts.name !== void 0) body.name = normalizeChannelName2(opts.name);
48577
+ if (opts.description !== void 0) body.description = opts.description;
48578
+ if (opts.public) body.visibility = "public";
48579
+ if (opts.private) body.visibility = "private";
48580
+ if (body.name === void 0 && body.description === void 0 && body.visibility === void 0) {
48581
+ throw new CliError({
48582
+ code: "INVALID_ARG",
48583
+ message: "Provide at least one of --name, --description, --public, or --private."
48584
+ });
48585
+ }
48586
+ const agentContext = ctx.loadAgentContext();
48587
+ const client = ctx.createApiClient(agentContext);
48588
+ const infoRes = await client.request(
48589
+ "GET",
48590
+ `/internal/agent/${encodeURIComponent(agentContext.agentId)}/server`
48591
+ );
48592
+ if (!infoRes.ok) {
48593
+ throw new CliError({
48594
+ code: infoRes.status >= 500 ? "SERVER_5XX" : "INFO_FAILED",
48595
+ message: infoRes.error ?? `HTTP ${infoRes.status}`
48596
+ });
48597
+ }
48598
+ const channel = (infoRes.data?.channels ?? []).find((candidate) => candidate.name === channelName);
48599
+ if (!channel) {
48600
+ throw new CliError({
48601
+ code: "NOT_FOUND",
48602
+ message: `Channel not found: ${target}`
48603
+ });
48604
+ }
48605
+ const updateRes = await client.request(
48606
+ "PATCH",
48607
+ `/internal/agent/${encodeURIComponent(agentContext.agentId)}/channels/${encodeURIComponent(channel.id)}`,
48608
+ body
48609
+ );
48610
+ if (!updateRes.ok || !updateRes.data) {
48611
+ throw new CliError({
48612
+ code: updateRes.status >= 500 ? "SERVER_5XX" : "UPDATE_FAILED",
48613
+ message: updateRes.error ?? `HTTP ${updateRes.status}`
48614
+ });
48615
+ }
48616
+ writeText(ctx.io, formatUpdateChannelResult(updateRes.data) + "\n");
48617
+ }
48618
+ );
48619
+ function registerChannelUpdateCommand(parent, runtimeOptions) {
48620
+ registerCliCommand(parent, channelUpdateCommand, runtimeOptions);
48621
+ }
48622
+
48623
+ // src/commands/channel/add-member.ts
48624
+ init_esm_shims();
48625
+ function normalizeHandle(raw) {
48626
+ return (raw ?? "").trim().replace(/^@/, "");
48627
+ }
48628
+ function formatAddMemberResult(target, memberType, memberName, alreadyMember) {
48629
+ const member = `@${memberName}`;
48630
+ if (alreadyMember) {
48631
+ return `${member} is already in ${target}.`;
48632
+ }
48633
+ return `Added ${member} to ${target} as ${memberType === "agent" ? "an agent" : "a user"}.`;
48634
+ }
48635
+ var channelAddMemberCommand = defineCommand(
48636
+ {
48637
+ name: "add-member",
48638
+ description: "Add a human or agent to a regular channel when this agent has server admin authority",
48639
+ options: [
48640
+ {
48641
+ flags: "--target <target>",
48642
+ description: "Regular channel to add a member to, e.g. '#engineering'"
48643
+ },
48644
+ {
48645
+ flags: "--user <handle>",
48646
+ description: "Human handle to add, e.g. '@alice'"
48647
+ },
48648
+ {
48649
+ flags: "--agent <handle>",
48650
+ description: "Agent handle to add, e.g. '@assistant'"
48651
+ }
48652
+ ]
48653
+ },
48654
+ async (ctx, opts) => {
48655
+ const target = opts.target ?? "";
48656
+ const channelName = parseRegularChannelTarget(target);
48657
+ if (!channelName) {
48658
+ throw new CliError({
48659
+ code: "INVALID_TARGET",
48660
+ message: "Target must be a regular channel in the form '#channel-name'. DMs and thread targets are not supported."
48661
+ });
48662
+ }
48663
+ const user = normalizeHandle(opts.user);
48664
+ const agent = normalizeHandle(opts.agent);
48665
+ if ((user ? 1 : 0) + (agent ? 1 : 0) !== 1) {
48666
+ throw new CliError({
48667
+ code: "INVALID_ARG",
48668
+ message: "Provide exactly one of --user or --agent."
48669
+ });
48670
+ }
48671
+ const agentContext = ctx.loadAgentContext();
48672
+ const client = ctx.createApiClient(agentContext);
48673
+ const infoRes = await client.request(
48674
+ "GET",
48675
+ `/internal/agent/${encodeURIComponent(agentContext.agentId)}/server`
48676
+ );
48677
+ if (!infoRes.ok) {
48678
+ throw new CliError({
48679
+ code: infoRes.status >= 500 ? "SERVER_5XX" : "INFO_FAILED",
48680
+ message: infoRes.error ?? `HTTP ${infoRes.status}`
48681
+ });
48682
+ }
48683
+ const channel = (infoRes.data?.channels ?? []).find((candidate) => candidate.name === channelName);
48684
+ if (!channel) {
48685
+ throw new CliError({
48686
+ code: "NOT_FOUND",
48687
+ message: `Channel not found: ${target}`
48688
+ });
48689
+ }
48690
+ const body = user ? { user } : { agent };
48691
+ const addRes = await client.request(
48692
+ "POST",
48693
+ `/internal/agent/${encodeURIComponent(agentContext.agentId)}/channels/${encodeURIComponent(channel.id)}/members`,
48694
+ body
48695
+ );
48696
+ if (!addRes.ok) {
48697
+ throw new CliError({
48698
+ code: addRes.status >= 500 ? "SERVER_5XX" : "MEMBERS_FAILED",
48699
+ message: addRes.error ?? `HTTP ${addRes.status}`
48700
+ });
48701
+ }
48702
+ const memberName = addRes.data?.member?.name ?? (user || agent);
48703
+ const memberType = addRes.data?.member?.type === "agent" ? "agent" : "user";
48704
+ writeText(ctx.io, formatAddMemberResult(target, memberType, memberName, addRes.data?.alreadyMember === true) + "\n");
48705
+ }
48706
+ );
48707
+ function registerChannelAddMemberCommand(parent, runtimeOptions) {
48708
+ registerCliCommand(parent, channelAddMemberCommand, runtimeOptions);
48709
+ }
48710
+
48711
+ // src/commands/channel/remove-member.ts
48712
+ init_esm_shims();
48713
+ function normalizeHandle2(raw) {
48714
+ return (raw ?? "").trim().replace(/^@/, "");
48715
+ }
48716
+ function formatRemoveMemberResult(target, memberName, wasMember) {
48717
+ const member = `@${memberName}`;
48718
+ return wasMember ? `Removed ${member} from ${target}.` : `${member} was not in ${target}.`;
48719
+ }
48720
+ var channelRemoveMemberCommand = defineCommand(
48721
+ {
48722
+ name: "remove-member",
48723
+ description: "Remove a human or agent from a regular channel when this agent has server admin authority",
48724
+ options: [
48725
+ {
48726
+ flags: "--target <target>",
48727
+ description: "Regular channel to remove a member from, e.g. '#engineering'"
48728
+ },
48729
+ {
48730
+ flags: "--user <handle>",
48731
+ description: "Human handle to remove, e.g. '@alice'"
48732
+ },
48733
+ {
48734
+ flags: "--agent <handle>",
48735
+ description: "Agent handle to remove, e.g. '@assistant'"
48736
+ }
48737
+ ]
48738
+ },
48739
+ async (ctx, opts) => {
48740
+ const target = opts.target ?? "";
48741
+ const channelName = parseRegularChannelTarget(target);
48742
+ if (!channelName) {
48743
+ throw new CliError({
48744
+ code: "INVALID_TARGET",
48745
+ message: "Target must be a regular channel in the form '#channel-name'. DMs and thread targets are not supported."
48746
+ });
48747
+ }
48748
+ const user = normalizeHandle2(opts.user);
48749
+ const agent = normalizeHandle2(opts.agent);
48750
+ if ((user ? 1 : 0) + (agent ? 1 : 0) !== 1) {
48751
+ throw new CliError({
48752
+ code: "INVALID_ARG",
48753
+ message: "Provide exactly one of --user or --agent."
48754
+ });
48755
+ }
48756
+ const agentContext = ctx.loadAgentContext();
48757
+ const client = ctx.createApiClient(agentContext);
48758
+ const infoRes = await client.request(
48759
+ "GET",
48760
+ `/internal/agent/${encodeURIComponent(agentContext.agentId)}/server`
48761
+ );
48762
+ if (!infoRes.ok) {
48763
+ throw new CliError({
48764
+ code: infoRes.status >= 500 ? "SERVER_5XX" : "INFO_FAILED",
48765
+ message: infoRes.error ?? `HTTP ${infoRes.status}`
48766
+ });
48767
+ }
48768
+ const channel = (infoRes.data?.channels ?? []).find((candidate) => candidate.name === channelName);
48769
+ if (!channel) {
48770
+ throw new CliError({
48771
+ code: "NOT_FOUND",
48772
+ message: `Channel not found: ${target}`
48773
+ });
48774
+ }
48775
+ const body = user ? { user } : { agent };
48776
+ const removeRes = await client.request(
48777
+ "DELETE",
48778
+ `/internal/agent/${encodeURIComponent(agentContext.agentId)}/channels/${encodeURIComponent(channel.id)}/members`,
48779
+ body
48780
+ );
48781
+ if (!removeRes.ok) {
48782
+ throw new CliError({
48783
+ code: removeRes.status >= 500 ? "SERVER_5XX" : "MEMBERS_FAILED",
48784
+ message: removeRes.error ?? `HTTP ${removeRes.status}`
48785
+ });
48786
+ }
48787
+ const memberName = removeRes.data?.member?.name ?? (user || agent);
48788
+ writeText(ctx.io, formatRemoveMemberResult(target, memberName, removeRes.data?.wasMember === true) + "\n");
48789
+ }
48790
+ );
48791
+ function registerChannelRemoveMemberCommand(parent, runtimeOptions) {
48792
+ registerCliCommand(parent, channelRemoveMemberCommand, runtimeOptions);
48793
+ }
48794
+
47775
48795
  // src/commands/channel/join.ts
48796
+ init_esm_shims();
47776
48797
  function formatJoinChannelResult(target) {
47777
48798
  return `Joined ${target}. You can now send messages there and receive ordinary channel delivery.`;
47778
48799
  }
@@ -47801,7 +48822,8 @@ var channelJoinCommand = defineCommand(
47801
48822
  }
47802
48823
  const agentContext = ctx.loadAgentContext();
47803
48824
  const client = ctx.createApiClient(agentContext);
47804
- const infoRes = await createAgentApiClient2(client, agentContext.agentId).server.info();
48825
+ const agentApi = createAgentApiSurfaceClient(client);
48826
+ const infoRes = await agentApi.server.info();
47805
48827
  if (!infoRes.ok) {
47806
48828
  throw new CliError({
47807
48829
  code: infoRes.status >= 500 ? "SERVER_5XX" : "INFO_FAILED",
@@ -47819,7 +48841,7 @@ var channelJoinCommand = defineCommand(
47819
48841
  writeText(ctx.io, formatAlreadyJoined(target) + "\n");
47820
48842
  return;
47821
48843
  }
47822
- const joinRes = await createAgentApiClient2(client, agentContext.agentId).channels.join({
48844
+ const joinRes = await agentApi.channels.join({
47823
48845
  channelId: channel.id
47824
48846
  });
47825
48847
  if (!joinRes.ok) {
@@ -47877,7 +48899,8 @@ function makeChannelMuteCommand(action) {
47877
48899
  }
47878
48900
  const agentContext = ctx.loadAgentContext();
47879
48901
  const client = ctx.createApiClient(agentContext);
47880
- const infoRes = await createAgentApiClient2(client, agentContext.agentId).server.info();
48902
+ const agentApi = createAgentApiSurfaceClient(client);
48903
+ const infoRes = await agentApi.server.info();
47881
48904
  if (!infoRes.ok) {
47882
48905
  throw new CliError({
47883
48906
  code: infoRes.status >= 500 ? "SERVER_5XX" : "INFO_FAILED",
@@ -47891,10 +48914,7 @@ function makeChannelMuteCommand(action) {
47891
48914
  message: `Channel not found: ${target}`
47892
48915
  });
47893
48916
  }
47894
- const res = await client.request(
47895
- "POST",
47896
- `/internal/agent/${encodeURIComponent(agentContext.agentId)}/channels/${encodeURIComponent(channel.id)}/${action}`
47897
- );
48917
+ const res = action === "mute" ? await agentApi.channels.mute({ channelId: channel.id }) : await agentApi.channels.unmute({ channelId: channel.id });
47898
48918
  if (!res.ok) {
47899
48919
  throw new CliError({
47900
48920
  code: res.status >= 500 ? "SERVER_5XX" : action === "mute" ? "MUTE_FAILED" : "UNMUTE_FAILED",
@@ -47925,7 +48945,7 @@ var serverInfoCommand = defineCommand(
47925
48945
  async (ctx) => {
47926
48946
  const agentContext = ctx.loadAgentContext();
47927
48947
  const client = ctx.createApiClient(agentContext);
47928
- const res = await createAgentApiClient2(client, agentContext.agentId).server.info();
48948
+ const res = await createAgentApiSurfaceClient(client).server.info();
47929
48949
  if (!res.ok) {
47930
48950
  const code = res.status >= 500 ? "SERVER_5XX" : "INFO_FAILED";
47931
48951
  throw new CliError({
@@ -47947,16 +48967,341 @@ function registerServerInfoCommand(parent, runtimeOptions) {
47947
48967
  registerCliCommand(parent, serverInfoCommand, runtimeOptions);
47948
48968
  }
47949
48969
 
47950
- // src/commands/knowledge/get.ts
48970
+ // src/commands/server/update.ts
47951
48971
  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()}`;
48972
+
48973
+ // src/commands/profile/update.ts
48974
+ init_esm_shims();
48975
+ import { basename } from "path";
48976
+ import { existsSync, readFileSync as readFileSync2, statSync } from "fs";
48977
+
48978
+ // src/commands/profile/_format.ts
48979
+ init_esm_shims();
48980
+ function formatCreatedAgents(createdAgents) {
48981
+ if (createdAgents.length === 0) {
48982
+ return ["- Created Agents: none"];
48983
+ }
48984
+ return [
48985
+ `- Created Agents (${createdAgents.length}):`,
48986
+ ...createdAgents.map((createdAgent) => ` - @${createdAgent.name} (${getRuntimeDisplayName(createdAgent.runtime)}, ${createdAgent.status})`)
48987
+ ];
48988
+ }
48989
+ function formatHumanProfile(profile) {
48990
+ const lines = [
48991
+ "## Profile",
48992
+ "",
48993
+ "- Type: human",
48994
+ `- Handle: @${profile.name}`,
48995
+ `- Display Name: ${profile.displayName ?? "(none)"}`,
48996
+ `- Description: ${profile.description ?? "(none)"}`,
48997
+ `- Membership: ${profile.membershipStatus}`
48998
+ ];
48999
+ if (profile.role) lines.push(`- Role: ${profile.role}`);
49000
+ if (profile.joinedAt) lines.push(`- Joined: ${profile.joinedAt}`);
49001
+ if (profile.email) lines.push(`- Email: ${profile.email}`);
49002
+ return [...lines, ...formatCreatedAgents(profile.createdAgents)].join("\n");
49003
+ }
49004
+ function formatCreator(profile) {
49005
+ if (!profile.creator) return null;
49006
+ return profile.creator.displayName ? `${profile.creator.displayName} (@${profile.creator.name})` : `@${profile.creator.name}`;
49007
+ }
49008
+ function formatAgentProfile(profile) {
49009
+ const lines = [
49010
+ "## Profile",
49011
+ "",
49012
+ "- Type: agent",
49013
+ `- Handle: @${profile.name}`,
49014
+ `- Display Name: ${profile.displayName ?? "(none)"}`,
49015
+ `- Description: ${profile.description ?? "(none)"}`,
49016
+ `- Status: ${profile.status}`,
49017
+ `- Role: ${profile.serverRole}`,
49018
+ `- Runtime: ${getRuntimeDisplayName(profile.runtime)}`,
49019
+ `- Model: ${profile.model}`,
49020
+ `- Reasoning: ${profile.reasoningEffort ?? "medium"}`
49021
+ ];
49022
+ if (profile.executionMode) lines.push(`- Execution: ${profile.executionMode}`);
49023
+ if (profile.computerName || profile.computerId) {
49024
+ const label = profile.computerName && profile.computerId ? `${profile.computerName} (${profile.computerId})` : profile.computerName ?? profile.computerId;
49025
+ lines.push(`- Computer: ${label}`);
49026
+ }
49027
+ if (profile.computerHostname) lines.push(`- Hostname: ${profile.computerHostname}`);
49028
+ if (profile.daemonVersion) lines.push(`- Daemon: v${profile.daemonVersion}`);
49029
+ lines.push(`- Created: ${profile.createdAt}`);
49030
+ if (profile.deletedAt) lines.push(`- Deleted At: ${profile.deletedAt}`);
49031
+ const creator = formatCreator(profile);
49032
+ if (creator) lines.push(`- Creator: ${creator}`);
49033
+ return [...lines, ...formatCreatedAgents(profile.createdAgents)].join("\n");
47959
49034
  }
49035
+ function formatProfile(profile) {
49036
+ return profile.kind === "human" ? formatHumanProfile(profile) : formatAgentProfile(profile);
49037
+ }
49038
+
49039
+ // src/commands/profile/update.ts
49040
+ var MAX_PROFILE_AVATAR_BYTES = 2 * 1024 * 1024;
49041
+ var PROFILE_AVATAR_MIME_TYPES = /* @__PURE__ */ new Set([
49042
+ "image/jpeg",
49043
+ "image/png",
49044
+ "image/gif",
49045
+ "image/webp"
49046
+ ]);
49047
+ var FILENAME_MIME_MAP = {
49048
+ ".jpg": "image/jpeg",
49049
+ ".jpeg": "image/jpeg",
49050
+ ".png": "image/png",
49051
+ ".gif": "image/gif",
49052
+ ".webp": "image/webp"
49053
+ };
49054
+ var MAX_PROFILE_DESCRIPTION_LENGTH = 3e3;
49055
+ var MAX_PROFILE_DISPLAY_NAME_LENGTH = 80;
49056
+ function inferImageMimeType(filename, buffer) {
49057
+ const lowerFilename = filename.toLowerCase();
49058
+ if (buffer.length >= 8 && buffer.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]))) {
49059
+ return "image/png";
49060
+ }
49061
+ if (buffer.length >= 3 && buffer.subarray(0, 3).equals(Buffer.from([255, 216, 255]))) {
49062
+ return "image/jpeg";
49063
+ }
49064
+ if (buffer.length >= 6) {
49065
+ const header = buffer.subarray(0, 6).toString("ascii");
49066
+ if (header === "GIF87a" || header === "GIF89a") return "image/gif";
49067
+ }
49068
+ if (buffer.length >= 12 && buffer.subarray(0, 4).toString("ascii") === "RIFF" && buffer.subarray(8, 12).toString("ascii") === "WEBP") {
49069
+ return "image/webp";
49070
+ }
49071
+ const dot = lowerFilename.lastIndexOf(".");
49072
+ return dot >= 0 ? FILENAME_MIME_MAP[lowerFilename.slice(dot)] ?? null : null;
49073
+ }
49074
+ function readAvatarFile(avatarFile) {
49075
+ if (!existsSync(avatarFile)) {
49076
+ throw cliError("PROFILE_FILE_NOT_FOUND", `Avatar file does not exist: ${avatarFile}`);
49077
+ }
49078
+ const stat2 = statSync(avatarFile);
49079
+ if (!stat2.isFile()) {
49080
+ throw cliError("PROFILE_FILE_NOT_FOUND", `Avatar file is not a regular file: ${avatarFile}`);
49081
+ }
49082
+ if (stat2.size > MAX_PROFILE_AVATAR_BYTES) {
49083
+ throw cliError(
49084
+ "PROFILE_AVATAR_TOO_LARGE",
49085
+ `Avatar file is ${stat2.size} bytes; max size is ${MAX_PROFILE_AVATAR_BYTES} bytes`
49086
+ );
49087
+ }
49088
+ const buffer = readFileSync2(avatarFile);
49089
+ const filename = basename(avatarFile);
49090
+ const mimeType = inferImageMimeType(filename, buffer);
49091
+ if (!mimeType || !PROFILE_AVATAR_MIME_TYPES.has(mimeType)) {
49092
+ throw cliError(
49093
+ "PROFILE_AVATAR_BAD_FORMAT",
49094
+ "Avatar must be a JPEG, PNG, GIF, or WebP image"
49095
+ );
49096
+ }
49097
+ return { filename, buffer, mimeType };
49098
+ }
49099
+ function normalizeAvatarUrl(avatarUrl) {
49100
+ const trimmed = avatarUrl.trim();
49101
+ if (trimmed.length === 0) {
49102
+ throw cliError("INVALID_ARG", "--avatar-url must not be empty");
49103
+ }
49104
+ if (!trimmed.startsWith("pixel:")) {
49105
+ throw cliError("INVALID_ARG", "--avatar-url currently supports only pixel avatar URLs; use --avatar-file for image uploads");
49106
+ }
49107
+ return trimmed;
49108
+ }
49109
+ var profileUpdateCommand = defineCommand(
49110
+ {
49111
+ name: "update",
49112
+ description: "Update your own profile",
49113
+ options: [
49114
+ { flags: "--avatar-file <path>", description: "Path to a local image file to use as your avatar" },
49115
+ { flags: "--avatar-url <value>", description: "Set a pixel avatar URL such as pixel:random:<seed>" },
49116
+ { flags: "--display-name <name>", description: "Set your display name (non-empty)" },
49117
+ { flags: "--description <text>", description: "Set your profile description (non-empty)" },
49118
+ { flags: "--json", description: "Emit machine-readable JSON" }
49119
+ ]
49120
+ },
49121
+ async (ctx, opts) => {
49122
+ const hasAvatar = opts.avatarFile !== void 0;
49123
+ const hasAvatarUrl = opts.avatarUrl !== void 0;
49124
+ const hasDisplayName = opts.displayName !== void 0;
49125
+ const hasDescription = opts.description !== void 0;
49126
+ if (!hasAvatar && !hasAvatarUrl && !hasDisplayName && !hasDescription) {
49127
+ throw cliError("INVALID_ARG", "Provide at least one of --avatar-file, --avatar-url, --display-name, or --description");
49128
+ }
49129
+ if (hasAvatar && hasAvatarUrl) {
49130
+ throw cliError("INVALID_ARG", "Use either --avatar-file or --avatar-url, not both");
49131
+ }
49132
+ let normalizedAvatarUrl;
49133
+ if (hasAvatarUrl) {
49134
+ normalizedAvatarUrl = normalizeAvatarUrl(opts.avatarUrl);
49135
+ }
49136
+ let trimmedDisplayName;
49137
+ if (hasDisplayName) {
49138
+ trimmedDisplayName = opts.displayName.trim();
49139
+ if (trimmedDisplayName.length === 0) {
49140
+ throw cliError("INVALID_ARG", "--display-name must not be empty");
49141
+ }
49142
+ if (trimmedDisplayName.length > MAX_PROFILE_DISPLAY_NAME_LENGTH) {
49143
+ throw cliError("INVALID_ARG", `--display-name must be at most ${MAX_PROFILE_DISPLAY_NAME_LENGTH} characters`);
49144
+ }
49145
+ }
49146
+ if (hasDescription) {
49147
+ if (opts.description.length === 0) {
49148
+ throw cliError("INVALID_ARG", "--description must not be empty");
49149
+ }
49150
+ if (opts.description.length > MAX_PROFILE_DESCRIPTION_LENGTH) {
49151
+ throw cliError("INVALID_ARG", `--description must be at most ${MAX_PROFILE_DESCRIPTION_LENGTH} characters`);
49152
+ }
49153
+ }
49154
+ const avatar = hasAvatar ? readAvatarFile(opts.avatarFile) : null;
49155
+ const agentContext = ctx.loadAgentContext();
49156
+ const client = ctx.createApiClient(agentContext);
49157
+ const agentApi = createAgentApiSurfaceClient(client);
49158
+ let latestProfile = null;
49159
+ if (hasAvatarUrl || hasDisplayName || hasDescription) {
49160
+ const body = {};
49161
+ if (hasAvatarUrl) {
49162
+ body.avatarUrl = normalizedAvatarUrl;
49163
+ }
49164
+ if (hasDisplayName) {
49165
+ body.displayName = trimmedDisplayName;
49166
+ }
49167
+ if (hasDescription) {
49168
+ body.description = opts.description;
49169
+ }
49170
+ const res = await agentApi.profile.update(body);
49171
+ if (!res.ok || !res.data) {
49172
+ const code = res.errorCode ?? (res.status >= 500 ? "SERVER_5XX" : "PROFILE_UPDATE_FAILED");
49173
+ throw cliError(code, res.error ?? `HTTP ${res.status}`);
49174
+ }
49175
+ latestProfile = res.data;
49176
+ }
49177
+ if (hasAvatar) {
49178
+ const form = new FormData();
49179
+ const avatarBytes = Uint8Array.from(avatar.buffer);
49180
+ form.append("avatar", new Blob([avatarBytes], { type: avatar.mimeType }), avatar.filename);
49181
+ const res = await agentApi.profile.updateAvatar(form);
49182
+ if (!res.ok || !res.data) {
49183
+ const code = res.errorCode ?? (res.status >= 500 ? "SERVER_5XX" : "PROFILE_UPDATE_FAILED");
49184
+ throw cliError(code, res.error ?? `HTTP ${res.status}`);
49185
+ }
49186
+ latestProfile = res.data;
49187
+ }
49188
+ if (!latestProfile) {
49189
+ throw cliError("PROFILE_UPDATE_FAILED", "No profile returned from server");
49190
+ }
49191
+ if (opts.json) {
49192
+ writeJson(ctx.io, { ok: true, data: latestProfile });
49193
+ return;
49194
+ }
49195
+ writeText(ctx.io, `${formatProfile(latestProfile)}
49196
+ `);
49197
+ }
49198
+ );
49199
+ function registerProfileUpdateCommand(parent, runtimeOptions = {}) {
49200
+ registerCliCommand(parent, profileUpdateCommand, runtimeOptions);
49201
+ }
49202
+
49203
+ // src/commands/server/update.ts
49204
+ function formatServerUpdateResult(server) {
49205
+ return `Updated server ${server.name ?? server.id ?? "profile"}.`;
49206
+ }
49207
+ var serverUpdateCommand = defineCommand(
49208
+ {
49209
+ name: "update",
49210
+ description: "Update the current server profile when this agent has server admin authority",
49211
+ options: [
49212
+ {
49213
+ flags: "--name <name>",
49214
+ description: "Set the server name"
49215
+ },
49216
+ {
49217
+ flags: "--avatar-file <path>",
49218
+ description: "Path to a local image file to use as the server avatar"
49219
+ },
49220
+ {
49221
+ flags: "--json",
49222
+ description: "Emit machine-readable JSON"
49223
+ }
49224
+ ]
49225
+ },
49226
+ async (ctx, opts) => {
49227
+ const hasName = opts.name !== void 0;
49228
+ const hasAvatar = opts.avatarFile !== void 0;
49229
+ if (!hasName && !hasAvatar) {
49230
+ throw new CliError({
49231
+ code: "INVALID_ARG",
49232
+ message: "Provide at least one of --name or --avatar-file."
49233
+ });
49234
+ }
49235
+ let trimmedName;
49236
+ if (hasName) {
49237
+ trimmedName = opts.name.trim();
49238
+ if (!trimmedName) {
49239
+ throw new CliError({
49240
+ code: "INVALID_ARG",
49241
+ message: "--name must not be empty"
49242
+ });
49243
+ }
49244
+ if (trimmedName.length > 100) {
49245
+ throw new CliError({
49246
+ code: "INVALID_ARG",
49247
+ message: "--name must be 100 characters or fewer"
49248
+ });
49249
+ }
49250
+ }
49251
+ const avatar = hasAvatar ? readAvatarFile(opts.avatarFile) : null;
49252
+ const agentContext = ctx.loadAgentContext();
49253
+ const client = ctx.createApiClient(agentContext);
49254
+ let latestServer = null;
49255
+ if (hasName) {
49256
+ const res = await client.request(
49257
+ "PATCH",
49258
+ `/internal/agent/${encodeURIComponent(agentContext.agentId)}/server`,
49259
+ { name: trimmedName }
49260
+ );
49261
+ if (!res.ok || !res.data) {
49262
+ throw new CliError({
49263
+ code: res.status >= 500 ? "SERVER_5XX" : "UPDATE_FAILED",
49264
+ message: res.error ?? `HTTP ${res.status}`
49265
+ });
49266
+ }
49267
+ latestServer = res.data;
49268
+ }
49269
+ if (hasAvatar) {
49270
+ const form = new FormData();
49271
+ const avatarBytes = Uint8Array.from(avatar.buffer);
49272
+ form.append("avatar", new Blob([avatarBytes], { type: avatar.mimeType }), avatar.filename);
49273
+ const res = await client.requestMultipart(
49274
+ "POST",
49275
+ `/internal/agent/${encodeURIComponent(agentContext.agentId)}/server/avatar`,
49276
+ form
49277
+ );
49278
+ if (!res.ok || !res.data) {
49279
+ throw new CliError({
49280
+ code: res.status >= 500 ? "SERVER_5XX" : "UPDATE_FAILED",
49281
+ message: res.error ?? `HTTP ${res.status}`
49282
+ });
49283
+ }
49284
+ latestServer = res.data;
49285
+ }
49286
+ if (!latestServer) {
49287
+ throw new CliError({
49288
+ code: "UPDATE_FAILED",
49289
+ message: "No server profile returned from server"
49290
+ });
49291
+ }
49292
+ if (opts.json) {
49293
+ writeJson(ctx.io, { ok: true, data: latestServer });
49294
+ return;
49295
+ }
49296
+ writeText(ctx.io, formatServerUpdateResult(latestServer) + "\n");
49297
+ }
49298
+ );
49299
+ function registerServerUpdateCommand(parent, runtimeOptions) {
49300
+ registerCliCommand(parent, serverUpdateCommand, runtimeOptions);
49301
+ }
49302
+
49303
+ // src/commands/knowledge/get.ts
49304
+ init_esm_shims();
47960
49305
  function formatKnowledgeStdout(content) {
47961
49306
  return content.endsWith("\n") ? content : `${content}
47962
49307
  `;
@@ -48003,10 +49348,12 @@ var knowledgeGetCommand = defineCommand(
48003
49348
  async (ctx, topic, opts) => {
48004
49349
  const agentContext = ctx.loadAgentContext();
48005
49350
  const client = ctx.createApiClient(agentContext);
48006
- const res = await client.request(
48007
- "GET",
48008
- buildKnowledgeGetPath(agentContext.agentId, topic, opts)
48009
- );
49351
+ const res = await createAgentApiSurfaceClient(client).knowledge.get({
49352
+ topic,
49353
+ reason: opts.reason,
49354
+ turn_id: opts.turnId,
49355
+ trace_id: opts.traceId
49356
+ });
48010
49357
  if (!res.ok) {
48011
49358
  throw new CliError({
48012
49359
  code: toKnowledgeErrorCode(res.errorCode, res.status),
@@ -48050,7 +49397,7 @@ var inboxCheckCommand = defineCommand(
48050
49397
  });
48051
49398
  }
48052
49399
  const client = ctx.createApiClient(agentContext);
48053
- const response = await client.request("GET", "/internal/agent-api/inbox");
49400
+ const response = await createDaemonApiSurfaceClient(client).inbox.check();
48054
49401
  if (!response.ok) {
48055
49402
  throw new CliError({
48056
49403
  code: response.status >= 500 ? "SERVER_5XX" : "INBOX_CHECK_FAILED",
@@ -48412,6 +49759,7 @@ function renderSearchPreview(content, query) {
48412
49759
  }
48413
49760
  function formatSearchResults(query, data) {
48414
49761
  if (!data.results || data.results.length === 0) return "No search results.";
49762
+ const trimmedQuery = query.trim();
48415
49763
  const formatted = data.results.map((result2, index) => {
48416
49764
  const ref = `msg:${result2.id}`;
48417
49765
  const content = result2.content ?? result2.snippet ?? "";
@@ -48424,14 +49772,14 @@ function formatSearchResults(query, data) {
48424
49772
  `Time: ${result2.createdAt ? toLocalTime(result2.createdAt) : "-"}`,
48425
49773
  "",
48426
49774
  "<preview>",
48427
- renderSearchPreview(content, query),
49775
+ renderSearchPreview(content, trimmedQuery),
48428
49776
  "</preview>",
48429
49777
  "</result>"
48430
49778
  ].join("\n");
48431
49779
  }).join("\n\n");
48432
49780
  const resultLabel = data.results.length === 1 ? "result" : "results";
48433
49781
  return [
48434
- `Search results for: "${query}" (${data.results.length} ${resultLabel})`,
49782
+ trimmedQuery ? `Search results for: "${trimmedQuery}" (${data.results.length} ${resultLabel})` : `Filtered message results (${data.results.length} ${resultLabel})`,
48435
49783
  "",
48436
49784
  formatted,
48437
49785
  "",
@@ -48740,7 +50088,8 @@ var messageSendCommand = defineCommand(
48740
50088
  ]
48741
50089
  },
48742
50090
  async (ctx, positionalContent, opts) => {
48743
- if (!opts.target?.trim()) {
50091
+ const target = opts.target?.trim() ?? "";
50092
+ if (!target) {
48744
50093
  throw cliError("INVALID_ARG", "--target is required");
48745
50094
  }
48746
50095
  try {
@@ -48781,14 +50130,14 @@ var messageSendCommand = defineCommand(
48781
50130
  const agentContext = ctx.loadAgentContext();
48782
50131
  const client = ctx.createApiClient(agentContext);
48783
50132
  if (opts.sendDraft) {
48784
- const savedDraft = getSavedDraft(agentContext.agentId, opts.target);
50133
+ const savedDraft = getSavedDraft(agentContext.agentId, target);
48785
50134
  if (!savedDraft) {
48786
50135
  throw cliError(
48787
50136
  "SEND_DRAFT_NOT_FOUND",
48788
50137
  [
48789
50138
  "No saved draft exists for this target.",
48790
50139
  "To create or update a draft, send message content normally:",
48791
- ` raft message send --target "${opts.target}" <<'${MESSAGE_HEREDOC_DELIMITER}'`,
50140
+ ` raft message send --target "${target}" <<'${MESSAGE_HEREDOC_DELIMITER}'`,
48792
50141
  " message body",
48793
50142
  ` ${MESSAGE_HEREDOC_DELIMITER}`
48794
50143
  ].join("\n")
@@ -48800,15 +50149,15 @@ var messageSendCommand = defineCommand(
48800
50149
  previousDraftReholdCount = savedDraft.reholdCount;
48801
50150
  seenUpToSeq = savedDraft.seenUpToSeq;
48802
50151
  } else {
48803
- const previousDraft = getSavedDraft(agentContext.agentId, opts.target);
50152
+ const previousDraft = getSavedDraft(agentContext.agentId, target);
48804
50153
  previousDraftReholdCount = previousDraft?.reholdCount ?? 0;
48805
50154
  seenUpToSeq = previousDraft?.seenUpToSeq;
48806
50155
  }
48807
50156
  if (seenUpToSeq === void 0) {
48808
- seenUpToSeq = getConsumedSeq(agentContext.agentId, opts.target);
50157
+ seenUpToSeq = getConsumedSeq(agentContext.agentId, target);
48809
50158
  }
48810
50159
  const body = {
48811
- target: opts.target,
50160
+ target,
48812
50161
  content: outgoingContent,
48813
50162
  draftReholdCount: previousDraftReholdCount
48814
50163
  };
@@ -48824,7 +50173,7 @@ var messageSendCommand = defineCommand(
48824
50173
  if (outgoingAttachmentIds.length > 0) {
48825
50174
  body.attachmentIds = outgoingAttachmentIds;
48826
50175
  }
48827
- const agentApi = createAgentApiClient2(client, agentContext.agentId);
50176
+ const agentApi = createAgentApiSurfaceClient(client);
48828
50177
  const res = await agentApi.messages.send(body);
48829
50178
  if (!res.ok) {
48830
50179
  const code = res.status >= 500 ? "SERVER_5XX" : "SEND_FAILED";
@@ -48836,21 +50185,21 @@ var messageSendCommand = defineCommand(
48836
50185
  }
48837
50186
  if (data.state === "held") {
48838
50187
  if (typeof data.seenUpToSeq === "number" && Number.isFinite(data.seenUpToSeq)) {
48839
- recordConsumedSeqs(agentContext.agentId, { [opts.target]: data.seenUpToSeq });
50188
+ recordConsumedSeqs(agentContext.agentId, { [target]: data.seenUpToSeq });
48840
50189
  }
48841
- setSavedDraft(agentContext.agentId, opts.target, {
50190
+ setSavedDraft(agentContext.agentId, target, {
48842
50191
  content: outgoingContent,
48843
50192
  attachmentIds: outgoingAttachmentIds,
48844
50193
  savedAt: Date.now(),
48845
50194
  reholdCount: previousDraftReholdCount + 1,
48846
50195
  seenUpToSeq: data.seenUpToSeq
48847
50196
  });
48848
- writeText(ctx.io, formatHeldSendOutput(opts.target, data));
50197
+ writeText(ctx.io, formatHeldSendOutput(target, data));
48849
50198
  return;
48850
50199
  }
48851
- clearSavedDraft(agentContext.agentId, opts.target);
50200
+ clearSavedDraft(agentContext.agentId, target);
48852
50201
  const shortId = data.messageId ? data.messageId.slice(0, 8) : null;
48853
- const replyHint = shortId ? ` (to reply in this message's thread, use target "${opts.target.includes(":") ? opts.target : opts.target + ":" + shortId}")` : "";
50202
+ const replyHint = shortId ? ` (to reply in this message's thread, use target "${target.includes(":") ? target : target + ":" + shortId}")` : "";
48854
50203
  let unreadSection = "";
48855
50204
  if (data.recentUnread && data.recentUnread.length > 0) {
48856
50205
  unreadSection = `
@@ -48862,7 +50211,7 @@ ${formatMessages(data.recentUnread)}`;
48862
50211
  const mentionSection = pendingMentionActions.length > 0 ? `
48863
50212
 
48864
50213
  ${formatPendingMentionActions(pendingMentionActions, { source: "send" }).trimEnd()}` : "";
48865
- writeText(ctx.io, `Message sent to ${opts.target}. Message ID: ${data.messageId}${replyHint}${mentionSection}${unreadSection}
50214
+ writeText(ctx.io, `Message sent to ${target}. Message ID: ${data.messageId}${replyHint}${mentionSection}${unreadSection}
48866
50215
  `);
48867
50216
  }
48868
50217
  );
@@ -48886,47 +50235,18 @@ function sortedMessages(messages) {
48886
50235
  function result(messages, opts = {}) {
48887
50236
  return {
48888
50237
  messages: sortedMessages(messages),
48889
- ...opts.ackFailure ? { ackFailure: opts.ackFailure } : {},
48890
50238
  ...opts.drainedMore ? { drainedMore: true } : {},
48891
50239
  ...opts.hasMore ? { hasMore: true } : {},
48892
50240
  ...opts.drainComplete ? { drainComplete: true } : {}
48893
50241
  };
48894
50242
  }
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
50243
  async function drainInbox(ctx, opts, client = new ApiClient(ctx)) {
48900
- const agentPath = `/internal/agent/${encodeURIComponent(ctx.agentId)}`;
48901
50244
  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`;
50245
+ const agentApi = createAgentApiSurfaceClient(client);
48907
50246
  const allMessages = [];
48908
50247
  let sawHasMore = false;
48909
50248
  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);
50249
+ const res = await agentApi.events.get({ since: "latest" });
48930
50250
  if (!res.ok) {
48931
50251
  if (allMessages.length > 0) {
48932
50252
  return result(allMessages, { drainedMore: sawHasMore, hasMore: true });
@@ -48936,25 +50256,13 @@ async function drainInbox(ctx, opts, client = new ApiClient(ctx)) {
48936
50256
  message: res.error ?? `HTTP ${res.status}`
48937
50257
  });
48938
50258
  }
48939
- const messages = res.data?.messages ?? [];
50259
+ const messages = res.data?.events ?? [];
48940
50260
  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;
50261
+ const hasMore = res.data?.has_more === true;
50262
+ const drainComplete = !hasMore && allMessages.length > 0;
48944
50263
  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 });
50264
+ if (hasMore && messages.length > 0) continue;
50265
+ return result(allMessages, { drainedMore: sawHasMore, hasMore, drainComplete });
48958
50266
  }
48959
50267
  return result(allMessages, { drainedMore: sawHasMore, hasMore: true });
48960
50268
  }
@@ -49062,7 +50370,7 @@ var messageReadCommand = defineCommand(
49062
50370
  const readOpts = validateReadOpts(opts);
49063
50371
  const agentContext = ctx.loadAgentContext();
49064
50372
  const client = ctx.createApiClient(agentContext);
49065
- const agentApi = createAgentApiClient2(client, agentContext.agentId);
50373
+ const agentApi = createAgentApiSurfaceClient(client);
49066
50374
  const res = await agentApi.history.read({
49067
50375
  channel: readOpts.channel,
49068
50376
  ...readOpts.before !== void 0 ? { before: readOpts.before } : {},
@@ -49137,29 +50445,53 @@ function parsePositiveInt3(name, raw) {
49137
50445
  }
49138
50446
  return n;
49139
50447
  }
49140
- function normalizeSearchOpts(opts) {
49141
- const query = opts.query?.trim();
49142
- if (!query) {
50448
+ function parseNonNegativeInt(name, raw) {
50449
+ if (raw === void 0) return void 0;
50450
+ const n = Number(raw);
50451
+ if (!Number.isFinite(n) || !Number.isInteger(n) || n < 0) {
49143
50452
  throw new CliError({
49144
50453
  code: "INVALID_ARG",
49145
- message: "--query is required"
50454
+ message: `--${name} must be a non-negative integer; got ${raw}`
49146
50455
  });
49147
50456
  }
50457
+ return n;
50458
+ }
50459
+ function normalizeSearchOpts(opts) {
50460
+ const query = opts.query?.trim();
49148
50461
  if (opts.sort !== void 0 && opts.sort !== "relevance" && opts.sort !== "recent") {
49149
50462
  throw new CliError({
49150
50463
  code: "INVALID_ARG",
49151
50464
  message: `--sort must be "relevance" or "recent"; got ${opts.sort}`
49152
50465
  });
49153
50466
  }
50467
+ const channel = opts.channel?.trim();
50468
+ const sender = opts.sender ? normalizeMemberHandleRef(opts.sender) : void 0;
50469
+ const hasFilter = Boolean(channel || sender || opts.before || opts.after);
50470
+ if (!query && !hasFilter) {
50471
+ throw new CliError({
50472
+ code: "INVALID_ARG",
50473
+ message: "--query is required unless --sender, --channel, --before, or --after is provided"
50474
+ });
50475
+ }
50476
+ if (!query && opts.sort === "relevance") {
50477
+ throw new CliError({
50478
+ code: "INVALID_ARG",
50479
+ message: "--sort relevance requires --query; filter-only search is sorted by recent"
50480
+ });
50481
+ }
49154
50482
  const limit = parsePositiveInt3("limit", opts.limit);
50483
+ const offset = parseNonNegativeInt("offset", opts.offset);
50484
+ const sort = opts.sort ?? (query ? void 0 : "recent");
49155
50485
  return {
49156
- query,
49157
- ...opts.channel ? { channel: opts.channel } : {},
49158
- ...opts.sender ? { sender: normalizeMemberHandleRef(opts.sender) } : {},
49159
- ...opts.sort ? { sort: opts.sort } : {},
50486
+ ...query ? { query } : {},
50487
+ displayQuery: query ?? "",
50488
+ ...channel ? { channel } : {},
50489
+ ...sender ? { sender } : {},
50490
+ ...sort ? { sort } : {},
49160
50491
  ...opts.before ? { before: opts.before } : {},
49161
50492
  ...opts.after ? { after: opts.after } : {},
49162
- ...limit !== void 0 ? { limit } : {}
50493
+ ...limit !== void 0 ? { limit } : {},
50494
+ ...offset !== void 0 ? { offset } : {}
49163
50495
  };
49164
50496
  }
49165
50497
  function toSearchErrorCode(errorCode2, status) {
@@ -49176,13 +50508,14 @@ var messageSearchCommand = defineCommand(
49176
50508
  name: "search",
49177
50509
  description: "Search messages across channels the agent can see",
49178
50510
  options: [
49179
- { flags: "--query <q>", description: "Search query string" },
50511
+ { flags: "--query <q>", description: "Search query string (optional when filters are provided)" },
49180
50512
  { flags: "--channel <target>", description: "Restrict to a single channel/DM/thread" },
49181
50513
  { 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)" },
50514
+ { flags: "--sort <mode>", description: "Sort results by relevance or recent (default: relevance; filter-only searches use recent)" },
49183
50515
  { flags: "--before <iso>", description: "Only messages before this ISO datetime" },
49184
50516
  { flags: "--after <iso>", description: "Only messages after this ISO datetime" },
49185
- { flags: "--limit <n>", description: "Max results (server default applies if omitted)" }
50517
+ { flags: "--limit <n>", description: "Max results (server default applies if omitted)" },
50518
+ { flags: "--offset <n>", description: "Skip this many results (server default applies if omitted)" }
49186
50519
  ]
49187
50520
  },
49188
50521
  async (ctx, opts) => {
@@ -49191,13 +50524,14 @@ var messageSearchCommand = defineCommand(
49191
50524
  const client = ctx.createApiClient(agentContext);
49192
50525
  const agentApi = createAgentApiSurfaceClient(client);
49193
50526
  const res = await agentApi.messages.search({
49194
- q: searchOpts.query,
50527
+ ...searchOpts.query ? { q: searchOpts.query } : {},
49195
50528
  ...searchOpts.channel ? { channel: searchOpts.channel } : {},
49196
50529
  ...searchOpts.sender ? { sender: searchOpts.sender } : {},
49197
50530
  ...searchOpts.sort ? { sort: searchOpts.sort } : {},
49198
50531
  ...searchOpts.before ? { before: searchOpts.before } : {},
49199
50532
  ...searchOpts.after ? { after: searchOpts.after } : {},
49200
- ...searchOpts.limit !== void 0 ? { limit: String(searchOpts.limit) } : {}
50533
+ ...searchOpts.limit !== void 0 ? { limit: String(searchOpts.limit) } : {},
50534
+ ...searchOpts.offset !== void 0 ? { offset: String(searchOpts.offset) } : {}
49201
50535
  });
49202
50536
  if (!res.ok) {
49203
50537
  throw new CliError({
@@ -49205,7 +50539,7 @@ var messageSearchCommand = defineCommand(
49205
50539
  message: res.error ?? `HTTP ${res.status}`
49206
50540
  });
49207
50541
  }
49208
- writeText(ctx.io, `${formatSearchResults(searchOpts.query, res.data)}
50542
+ writeText(ctx.io, `${formatSearchResults(searchOpts.displayQuery, res.data)}
49209
50543
  `);
49210
50544
  }
49211
50545
  );
@@ -49255,7 +50589,7 @@ var messageResolveCommand = defineCommand(
49255
50589
  }
49256
50590
  const agentContext = ctx.loadAgentContext();
49257
50591
  const client = ctx.createApiClient(agentContext);
49258
- const res = await createAgentApiClient2(client, agentContext.agentId).messages.resolve({ msgId: asMessageId(id) });
50592
+ const res = await createAgentApiSurfaceClient(client).messages.resolve({ msgId: asMessageId(id) });
49259
50593
  if (!res.ok) {
49260
50594
  const mapped = mapResolveError(res);
49261
50595
  throw new CliError(mapped);
@@ -49314,7 +50648,7 @@ var messageReactCommand = defineCommand(
49314
50648
  }
49315
50649
  const agentContext = ctx.loadAgentContext();
49316
50650
  const client = ctx.createApiClient(agentContext);
49317
- const agentApi = createAgentApiClient2(client, agentContext.agentId);
50651
+ const agentApi = createAgentApiSurfaceClient(client);
49318
50652
  const messageId = asMessageId(opts.messageId.trim());
49319
50653
  const res = opts.remove ? await agentApi.messages.removeReaction({ msgId: messageId }, { emoji: emoji3 }) : await agentApi.messages.addReaction({ msgId: messageId }, { emoji: emoji3 });
49320
50654
  if (!res.ok) {
@@ -49332,11 +50666,11 @@ function registerReactCommand(parent, runtimeOptions = {}) {
49332
50666
 
49333
50667
  // src/commands/attachment/upload.ts
49334
50668
  init_esm_shims();
49335
- import { existsSync, statSync, readFileSync as readFileSync2 } from "fs";
49336
- import { basename } from "path";
50669
+ import { existsSync as existsSync2, statSync as statSync2, readFileSync as readFileSync3 } from "fs";
50670
+ import { basename as basename2 } from "path";
49337
50671
  var MAX_ATTACHMENT_UPLOAD_BYTES = 50 * 1024 * 1024;
49338
50672
  var MAX_ATTACHMENT_UPLOAD_LABEL = "50MB";
49339
- var FILENAME_MIME_MAP = {
50673
+ var FILENAME_MIME_MAP2 = {
49340
50674
  ".jpg": "image/jpeg",
49341
50675
  ".jpeg": "image/jpeg",
49342
50676
  ".png": "image/png",
@@ -49359,7 +50693,7 @@ var AttachmentUploadArgError = class extends Error {
49359
50693
  function inferMimeTypeFromFilename(filename) {
49360
50694
  const index = filename.lastIndexOf(".");
49361
50695
  const ext = index >= 0 ? filename.slice(index).toLowerCase() : "";
49362
- return FILENAME_MIME_MAP[ext] || null;
50696
+ return FILENAME_MIME_MAP2[ext] || null;
49363
50697
  }
49364
50698
  function inferMimeTypeFromBuffer(buffer) {
49365
50699
  if (buffer.length >= 8 && buffer.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]))) {
@@ -49434,10 +50768,10 @@ var attachmentUploadCommand = defineCommand(
49434
50768
  if (typeof opts.path !== "string" || opts.path.length === 0) {
49435
50769
  throw cliError("INVALID_ARG", "--path is required");
49436
50770
  }
49437
- if (!existsSync(opts.path)) {
50771
+ if (!existsSync2(opts.path)) {
49438
50772
  throw cliError("INVALID_ARG", `--path does not exist: ${opts.path}`);
49439
50773
  }
49440
- const stat2 = statSync(opts.path);
50774
+ const stat2 = statSync2(opts.path);
49441
50775
  if (!stat2.isFile()) {
49442
50776
  throw cliError("INVALID_ARG", `--path is not a regular file: ${opts.path}`);
49443
50777
  }
@@ -49453,8 +50787,8 @@ var attachmentUploadCommand = defineCommand(
49453
50787
  "v0 server requires a channel to attach the upload to. Pass --channel '#name', 'dm:@peer', or a thread target."
49454
50788
  );
49455
50789
  }
49456
- const buffer = readFileSync2(opts.path);
49457
- const filename = basename(opts.path);
50790
+ const buffer = readFileSync3(opts.path);
50791
+ const filename = basename2(opts.path);
49458
50792
  let explicitMimeType;
49459
50793
  try {
49460
50794
  explicitMimeType = normalizeExplicitMimeType(opts.mimeType);
@@ -49531,17 +50865,20 @@ var attachmentViewCommand = defineCommand(
49531
50865
  const { id, output } = validateViewOpts(opts);
49532
50866
  const agentContext = ctx.loadAgentContext();
49533
50867
  const client = ctx.createApiClient(agentContext);
49534
- const res = await client.requestRaw(
49535
- "GET",
49536
- `/api/attachments/${encodeURIComponent(id)}`
49537
- );
50868
+ const res = await createAgentApiSurfaceClient(client).attachments.view({ attachmentId: id });
49538
50869
  if (!res.ok) {
49539
50870
  throw new CliError({
49540
50871
  code: res.status >= 500 ? "SERVER_5XX" : "VIEW_FAILED",
49541
50872
  message: res.error ?? `HTTP ${res.status}`
49542
50873
  });
49543
50874
  }
49544
- const buffer = Buffer.from(await res.response.arrayBuffer());
50875
+ if (res.data === null) {
50876
+ throw new CliError({
50877
+ code: "VIEW_FAILED",
50878
+ message: "Attachment download returned no bytes"
50879
+ });
50880
+ }
50881
+ const buffer = Buffer.from(res.data);
49545
50882
  writeFileSync(output, buffer);
49546
50883
  writeText(ctx.io, `Downloaded to: ${output}
49547
50884
  `);
@@ -49591,11 +50928,9 @@ var attachmentCommentsCommand = defineCommand(
49591
50928
  }
49592
50929
  const agentContext = ctx.loadAgentContext();
49593
50930
  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
- );
50931
+ const agentApi = createAgentApiSurfaceClient(client);
50932
+ const limit = opts.limit && Number.isFinite(Number(opts.limit)) ? String(Number(opts.limit)) : void 0;
50933
+ const res = await agentApi.attachments.comments({ attachmentId: id }, limit ? { limit } : {});
49599
50934
  if (!res.ok || !res.data) {
49600
50935
  const code = res.status >= 500 ? "SERVER_5XX" : "COMMENTS_FAILED";
49601
50936
  throw new CliError({ code, message: res.error ?? `HTTP ${res.status}` });
@@ -49658,7 +50993,7 @@ function formatClaimResults(channel, data) {
49658
50993
  const msgShort = r.messageId ? r.messageId.slice(0, 8) : "";
49659
50994
  return `${label} (msg:${msgShort}): claimed`;
49660
50995
  }
49661
- return `${label}: FAILED \u2014 ${r.reason || "already claimed"}. Do not reply.`;
50996
+ return `${label}: FAILED \u2014 ${r.reason || "already claimed"}. Do not work on this task unless an owner/admin explicitly redirects it to you.`;
49662
50997
  });
49663
50998
  const succeeded = data.results.filter((r) => r.success).length;
49664
50999
  const failed = data.results.length - succeeded;
@@ -50011,7 +51346,7 @@ function buildMentionExecuteCommand(action) {
50011
51346
  const ids = normalizeResolutionIds(resolutionIds);
50012
51347
  const agentContext = ctx.loadAgentContext();
50013
51348
  const client = ctx.createApiClient(agentContext);
50014
- const res = await createAgentApiClient2(client, agentContext.agentId).mentions.executeAction({
51349
+ const res = await createAgentApiSurfaceClient(client).mentions.executeAction({
50015
51350
  action,
50016
51351
  resolutionIds: ids
50017
51352
  });
@@ -50043,7 +51378,7 @@ var mentionPendingCommand = defineCommand(
50043
51378
  async (ctx, opts = {}) => {
50044
51379
  const agentContext = ctx.loadAgentContext();
50045
51380
  const client = ctx.createApiClient(agentContext);
50046
- const res = await createAgentApiClient2(client, agentContext.agentId).mentions.pendingActions();
51381
+ const res = await createAgentApiSurfaceClient(client).mentions.pendingActions();
50047
51382
  if (!res.ok || !res.data) {
50048
51383
  throw cliError(res.status >= 500 ? "SERVER_5XX" : "MENTION_PENDING_FAILED", res.error ?? `HTTP ${res.status}`);
50049
51384
  }
@@ -50067,69 +51402,6 @@ function registerMentionCommands(parent, runtimeOptions = {}) {
50067
51402
 
50068
51403
  // src/commands/profile/show.ts
50069
51404
  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
51405
  function normalizeTarget(target) {
50134
51406
  if (target === void 0) return null;
50135
51407
  const trimmed = target.trim();
@@ -50179,177 +51451,6 @@ function registerProfileShowCommand(parent, runtimeOptions) {
50179
51451
  registerCliCommand(parent, profileShowCommand, runtimeOptions);
50180
51452
  }
50181
51453
 
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
51454
  // src/commands/integration/list.ts
50354
51455
  init_esm_shims();
50355
51456
 
@@ -50378,6 +51479,7 @@ function pushServiceBlock(lines, service, active) {
50378
51479
  if (service.agentManifestUrl) {
50379
51480
  lines.push(` agent behavior manifest: ${service.agentManifestUrl}`);
50380
51481
  lines.push(` local CLI env: raft integration env --service ${JSON.stringify(service.clientId)}`);
51482
+ lines.push(` if manifest exposes HTTP API actions: raft integration invoke --service ${JSON.stringify(service.clientId)} --list-actions`);
50381
51483
  }
50382
51484
  if (service.homepageUrl) lines.push(` homepage: ${service.homepageUrl}`);
50383
51485
  if (service.description) lines.push(` description: ${service.description}`);
@@ -50417,6 +51519,7 @@ function formatIntegrationList(data) {
50417
51519
  if (login.agentManifestUrl) {
50418
51520
  lines.push(` agent behavior manifest: ${login.agentManifestUrl}`);
50419
51521
  lines.push(` local CLI env: raft integration env --service ${JSON.stringify(login.clientId)}`);
51522
+ lines.push(` if manifest exposes HTTP API actions: raft integration invoke --service ${JSON.stringify(login.clientId)} --list-actions`);
50420
51523
  }
50421
51524
  lines.push(` created: ${login.createdAt}`);
50422
51525
  }
@@ -50453,14 +51556,15 @@ function formatIntegrationLogin(data) {
50453
51556
  if (data.service.agentManifestUrl) {
50454
51557
  lines.push(`agent behavior manifest: ${data.service.agentManifestUrl}`);
50455
51558
  lines.push(`local CLI env: raft integration env --service ${JSON.stringify(data.service.clientId)}`);
51559
+ lines.push(`if manifest exposes HTTP API actions: raft integration invoke --service ${JSON.stringify(data.service.clientId)} --list-actions`);
50456
51560
  }
50457
51561
  lines.push("complete: this agent login is configured in Slock; no human OAuth is required");
50458
51562
  lines.push("identity: run `raft profile show` if the service or human asks for your Slock Agent identity card");
50459
51563
  const callbackHandoffUrl = buildAgentCallbackHandoffUrl(data.service.returnUrl, data.requestId);
50460
51564
  if (callbackHandoffUrl) {
50461
51565
  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");
51566
+ lines.push("note: stateless Login with Raft API-action services use this callback once to create their service session");
51567
+ lines.push(`next: prefer \`raft integration invoke --service ${JSON.stringify(data.service.clientId)} --list-actions\` when the service manifest exposes actions`);
50464
51568
  } else {
50465
51569
  lines.push("next: use the service, or run `raft integration list` to confirm active login");
50466
51570
  }
@@ -50563,7 +51667,10 @@ import os4 from "os";
50563
51667
  import path8 from "path";
50564
51668
  var AGENT_MANIFEST_MAX_BYTES = 64 * 1024;
50565
51669
  var AGENT_MANIFEST_SCHEMA_V0 = "slock-agent-manifest.v0";
51670
+ var RAFT_AGENT_MANIFEST_SCHEMA_V0 = "raft-agent-manifest.v0";
50566
51671
  var AGENT_MANIFEST_SCHEMA_V0_URL = "https://app.slock.ai/schemas/agent-manifest.v0.json";
51672
+ var RAFT_AGENT_MANIFEST_WELL_KNOWN_PATH = "/.well-known/raft-agent-manifest.json";
51673
+ var SLOCK_AGENT_MANIFEST_WELL_KNOWN_PATH = "/.well-known/slock-agent-manifest.json";
50567
51674
  var AgentManifestFetchError = class extends Error {
50568
51675
  constructor(message, status) {
50569
51676
  super(message);
@@ -50608,10 +51715,125 @@ function requireCommand(value) {
50608
51715
  }
50609
51716
  return command;
50610
51717
  }
51718
+ function requireName(value, field) {
51719
+ if (typeof value !== "string" || !value.trim()) {
51720
+ throw new Error(`${field} must be a non-empty string`);
51721
+ }
51722
+ const name = value.trim();
51723
+ if (!/^[A-Za-z0-9._:-]{1,80}$/.test(name)) {
51724
+ throw new Error(`${field} may only contain letters, digits, dot, underscore, colon, or dash`);
51725
+ }
51726
+ return name;
51727
+ }
51728
+ function optionalString(value) {
51729
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
51730
+ }
51731
+ function requireEndpointPath(value, field) {
51732
+ if (typeof value !== "string" || !value.trim()) {
51733
+ throw new Error(`${field} must be a non-empty path string`);
51734
+ }
51735
+ const path9 = value.trim();
51736
+ if (!path9.startsWith("/")) {
51737
+ throw new Error(`${field} must start with /`);
51738
+ }
51739
+ if (path9.startsWith("//")) {
51740
+ throw new Error(`${field} must be a relative service path`);
51741
+ }
51742
+ try {
51743
+ const parsed = new URL(path9, "https://manifest.local");
51744
+ if (parsed.origin !== "https://manifest.local" || parsed.username || parsed.password || parsed.hash) {
51745
+ throw new Error();
51746
+ }
51747
+ } catch {
51748
+ throw new Error(`${field} must be a relative service path`);
51749
+ }
51750
+ return path9;
51751
+ }
51752
+ function normalizeActionMethod(value) {
51753
+ if (typeof value !== "string") {
51754
+ throw new Error("actions[].endpoint.method must be a string");
51755
+ }
51756
+ const method = value.trim().toUpperCase();
51757
+ if (method !== "GET" && method !== "POST" && method !== "PUT" && method !== "PATCH" && method !== "DELETE") {
51758
+ throw new Error("actions[].endpoint.method must be GET, POST, PUT, PATCH, or DELETE");
51759
+ }
51760
+ return method;
51761
+ }
51762
+ function normalizeActionFields(value, field) {
51763
+ if (value === void 0) return void 0;
51764
+ if (!isRecord(value)) throw new Error(`${field} must be an object when present`);
51765
+ const fields = {};
51766
+ for (const [key, raw] of Object.entries(value)) {
51767
+ const name = requireName(key, `${field} key`);
51768
+ if (!isRecord(raw)) throw new Error(`${field}.${name} must be an object`);
51769
+ if (typeof raw.type !== "string" || !raw.type.trim()) {
51770
+ throw new Error(`${field}.${name}.type must be a non-empty string`);
51771
+ }
51772
+ fields[name] = {
51773
+ type: raw.type.trim(),
51774
+ description: optionalString(raw.description),
51775
+ required: raw.required === true
51776
+ };
51777
+ }
51778
+ return fields;
51779
+ }
51780
+ function normalizeActionReturns(value) {
51781
+ if (value === void 0) return void 0;
51782
+ if (!isRecord(value)) throw new Error("actions[].returns must be an object when present");
51783
+ const fields = {};
51784
+ for (const [key, raw] of Object.entries(value)) {
51785
+ const name = requireName(key, "actions[].returns key");
51786
+ if (!isRecord(raw)) throw new Error(`actions[].returns.${name} must be an object`);
51787
+ if (typeof raw.type !== "string" || !raw.type.trim()) {
51788
+ throw new Error(`actions[].returns.${name}.type must be a non-empty string`);
51789
+ }
51790
+ fields[name] = {
51791
+ type: raw.type.trim(),
51792
+ description: optionalString(raw.description)
51793
+ };
51794
+ }
51795
+ return fields;
51796
+ }
51797
+ function normalizeActions(value) {
51798
+ if (value === void 0) return void 0;
51799
+ if (!Array.isArray(value)) throw new Error("actions must be an array when present");
51800
+ const actions = value.map((raw, index) => {
51801
+ if (!isRecord(raw)) throw new Error(`actions[${index}] must be an object`);
51802
+ const endpoint = raw.endpoint;
51803
+ if (!isRecord(endpoint)) throw new Error(`actions[${index}].endpoint must be an object`);
51804
+ return {
51805
+ name: requireName(raw.name, `actions[${index}].name`),
51806
+ description: optionalString(raw.description),
51807
+ endpoint: {
51808
+ method: normalizeActionMethod(endpoint.method),
51809
+ path: requireEndpointPath(endpoint.path, `actions[${index}].endpoint.path`)
51810
+ },
51811
+ parameters: normalizeActionFields(raw.parameters, `actions[${index}].parameters`),
51812
+ returns: normalizeActionReturns(raw.returns)
51813
+ };
51814
+ });
51815
+ const seen = /* @__PURE__ */ new Set();
51816
+ for (const action of actions) {
51817
+ if (seen.has(action.name)) throw new Error(`duplicate action name: ${action.name}`);
51818
+ seen.add(action.name);
51819
+ }
51820
+ return actions;
51821
+ }
51822
+ function normalizeAuth(value) {
51823
+ if (value === void 0) return void 0;
51824
+ if (!isRecord(value)) throw new Error("auth must be an object when present");
51825
+ if (value.type !== "login_with_raft") {
51826
+ throw new Error("auth.type must be login_with_raft");
51827
+ }
51828
+ return {
51829
+ type: "login_with_raft",
51830
+ login_url: value.login_url === void 0 ? void 0 : requireUrl(value.login_url, "auth.login_url")
51831
+ };
51832
+ }
50611
51833
  function validateAgentManifestV0(value) {
50612
51834
  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}`);
51835
+ if (value.schema !== AGENT_MANIFEST_SCHEMA_V0 && value.schema !== RAFT_AGENT_MANIFEST_SCHEMA_V0 && value.schema !== AGENT_MANIFEST_SCHEMA_V0_URL) {
51836
+ throw new Error(`manifest schema must be ${AGENT_MANIFEST_SCHEMA_V0} or ${RAFT_AGENT_MANIFEST_SCHEMA_V0}`);
50615
51837
  }
50616
51838
  const execution = value.execution;
50617
51839
  if (!isRecord(execution)) throw new Error("execution must be an object");
@@ -50633,12 +51855,17 @@ function validateAgentManifestV0(value) {
50633
51855
  return {
50634
51856
  schema: AGENT_MANIFEST_SCHEMA_V0,
50635
51857
  service: typeof value.service === "string" && value.service.trim() ? value.service.trim() : void 0,
51858
+ name: optionalString(value.name),
51859
+ description: optionalString(value.description),
50636
51860
  docs_url: value.docs_url === void 0 ? void 0 : requireUrl(value.docs_url, "docs_url"),
51861
+ app_origin: value.app_origin === void 0 ? void 0 : requireUrl(value.app_origin, "app_origin"),
50637
51862
  execution: {
50638
51863
  mode: execution.mode,
50639
51864
  command: execution.mode === "local_cli" ? requireCommand(execution.command) : void 0,
50640
51865
  base_url: execution.base_url === void 0 ? void 0 : requireUrl(execution.base_url, "execution.base_url")
50641
51866
  },
51867
+ auth: normalizeAuth(value.auth),
51868
+ actions: normalizeActions(value.actions),
50642
51869
  credential_boundary: credentialStorage ? {
50643
51870
  storage: credentialStorage,
50644
51871
  forbid_user_home: forbidUserHome
@@ -50686,13 +51913,45 @@ async function fetchAgentManifest(url2) {
50686
51913
  }
50687
51914
  return validateAgentManifestV0(parsedJson);
50688
51915
  }
51916
+ function wellKnownAliasUrl(url2) {
51917
+ const parsed = new URL(url2);
51918
+ if (parsed.pathname === RAFT_AGENT_MANIFEST_WELL_KNOWN_PATH) {
51919
+ parsed.pathname = SLOCK_AGENT_MANIFEST_WELL_KNOWN_PATH;
51920
+ return parsed.toString();
51921
+ }
51922
+ if (parsed.pathname === SLOCK_AGENT_MANIFEST_WELL_KNOWN_PATH) {
51923
+ parsed.pathname = RAFT_AGENT_MANIFEST_WELL_KNOWN_PATH;
51924
+ return parsed.toString();
51925
+ }
51926
+ return null;
51927
+ }
51928
+ function shouldTryWellKnownAlias(err) {
51929
+ if (err instanceof AgentManifestFetchError) return err.status === 404 || err.status === 410;
51930
+ return err instanceof AgentManifestResponseFormatError;
51931
+ }
51932
+ async function fetchAgentManifestWithWellKnownAliases(url2, fetchManifestImpl = fetchAgentManifest) {
51933
+ try {
51934
+ return await fetchManifestImpl(url2);
51935
+ } catch (err) {
51936
+ if (!shouldTryWellKnownAlias(err)) throw err;
51937
+ const alias = wellKnownAliasUrl(url2);
51938
+ if (!alias) throw err;
51939
+ return await fetchManifestImpl(alias);
51940
+ }
51941
+ }
50689
51942
  function sanitizePathSegment(value) {
50690
51943
  const segment = value.trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
50691
51944
  return segment || "service";
50692
51945
  }
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");
51946
+ function resolveSlockHome(env, homeDir = os4.homedir()) {
51947
+ const configured = env.SLOCK_HOME?.trim() || env.RAFT_HOME?.trim();
51948
+ const raw = configured && configured.length > 0 ? configured : path8.join(homeDir, ".slock");
51949
+ return path8.resolve(expandHome(raw, homeDir));
51950
+ }
51951
+ function expandHome(input, homeDir) {
51952
+ if (input === "~") return homeDir;
51953
+ if (input.startsWith("~/")) return path8.join(homeDir, input.slice(2));
51954
+ return input;
50696
51955
  }
50697
51956
  function buildLocalCliProfileEnv(input) {
50698
51957
  if (input.manifest.execution.mode !== "local_cli" || !input.manifest.execution.command) {
@@ -50704,7 +51963,7 @@ function buildLocalCliProfileEnv(input) {
50704
51963
  if (input.manifest.credential_boundary.forbid_user_home !== true) {
50705
51964
  throw new Error("manifest must set credential_boundary.forbid_user_home=true for local_cli isolation");
50706
51965
  }
50707
- const root = resolveSlockHome(input.env ?? process.env);
51966
+ const root = resolveSlockHome(input.env ?? process.env, input.homeDir);
50708
51967
  const profileHome = path8.join(
50709
51968
  root,
50710
51969
  "integration-profiles",
@@ -50758,7 +52017,10 @@ function findService(data, service) {
50758
52017
  }
50759
52018
  function describeNoLocalEnv(manifest) {
50760
52019
  if (manifest.execution.mode !== "local_cli") {
50761
- return "manifest execution mode is not local_cli; no local CLI env is required";
52020
+ if (manifest.actions && manifest.actions.length > 0) {
52021
+ return "manifest exposes HTTP API actions; no local CLI env is required";
52022
+ }
52023
+ return "manifest execution mode is http_api; no local CLI env is required";
50762
52024
  }
50763
52025
  if (!manifest.credential_boundary) {
50764
52026
  return "manifest does not request a Slock-managed local environment";
@@ -50803,7 +52065,7 @@ async function resolveIntegrationEnv(input) {
50803
52065
  message: describeMissingManifest({ service: input.service })
50804
52066
  };
50805
52067
  }
50806
- const fetchManifestImpl = input.fetchManifest ?? fetchAgentManifest;
52068
+ const fetchManifestImpl = input.fetchManifest ?? (isInferredWellKnownManifest(input.service) ? fetchAgentManifestWithWellKnownAliases : fetchAgentManifest);
50807
52069
  let manifest;
50808
52070
  try {
50809
52071
  manifest = await fetchManifestImpl(input.service.agentManifestUrl);
@@ -50842,13 +52104,19 @@ async function resolveIntegrationEnv(input) {
50842
52104
  }
50843
52105
  }
50844
52106
  function formatNoLocalEnv(input) {
50845
- return [
52107
+ const lines = [
50846
52108
  `# Slock integration profile for ${input.service}`,
50847
52109
  input.manifestUrl ? `# manifest: ${input.manifestUrl}` : "# manifest: none declared",
50848
52110
  "# 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");
52111
+ `# ${input.message}`
52112
+ ];
52113
+ if (input.actions && input.actions.length > 0) {
52114
+ lines.push(`# API actions: ${input.actions.join(", ")}`);
52115
+ lines.push(`# list actions: raft integration invoke --service ${JSON.stringify(input.service)} --list-actions`);
52116
+ lines.push(`# invoke action: raft integration invoke --service ${JSON.stringify(input.service)} --action <name>`);
52117
+ }
52118
+ lines.push("# Slock did not set HOME/XDG exports and did not execute manifest commands.");
52119
+ return lines.join("\n");
50852
52120
  }
50853
52121
  var integrationEnvCommand = defineCommand(
50854
52122
  {
@@ -50892,6 +52160,7 @@ var integrationEnvCommand = defineCommand(
50892
52160
  manifestUrl: resolution.manifestUrl,
50893
52161
  requiresLocalEnv: false,
50894
52162
  command: resolution.manifest?.execution.command ?? null,
52163
+ actions: resolution.manifest?.actions?.map((action) => action.name) ?? [],
50895
52164
  env: {},
50896
52165
  message: resolution.message
50897
52166
  }
@@ -50901,7 +52170,8 @@ var integrationEnvCommand = defineCommand(
50901
52170
  writeText(cmdCtx.io, `${formatNoLocalEnv({
50902
52171
  service: resolution.service.clientId,
50903
52172
  manifestUrl: resolution.manifestUrl,
50904
- message: resolution.message
52173
+ message: resolution.message,
52174
+ actions: resolution.manifest?.actions?.map((action) => action.name) ?? []
50905
52175
  })}
50906
52176
  `);
50907
52177
  return;
@@ -50928,8 +52198,19 @@ function registerIntegrationEnvCommand(parent, runtimeOptions = {}) {
50928
52198
  registerCliCommand(parent, integrationEnvCommand, runtimeOptions);
50929
52199
  }
50930
52200
 
50931
- // src/commands/integration/app.ts
52201
+ // src/commands/integration/invoke.ts
50932
52202
  init_esm_shims();
52203
+ import fs6 from "fs";
52204
+ function normalizeService2(value) {
52205
+ return value.trim().toLowerCase();
52206
+ }
52207
+ function findService2(data, service) {
52208
+ const normalized = normalizeService2(service);
52209
+ if (!normalized) return null;
52210
+ return data.services.find(
52211
+ (candidate) => candidate.id === service || normalizeService2(candidate.clientId) === normalized || normalizeService2(candidate.name) === normalized
52212
+ ) ?? null;
52213
+ }
50933
52214
  function normalizeScopes2(raw) {
50934
52215
  if (!raw || raw.length === 0) return void 0;
50935
52216
  const scopes = Array.from(new Set(
@@ -50940,6 +52221,393 @@ function normalizeScopes2(raw) {
50940
52221
  }
50941
52222
  return scopes;
50942
52223
  }
52224
+ function parseHandlerArgs(serviceArgOrOpts, actionArgOrOpts, maybeOpts) {
52225
+ if (typeof serviceArgOrOpts === "object" && serviceArgOrOpts !== null) {
52226
+ return { opts: serviceArgOrOpts };
52227
+ }
52228
+ if (typeof actionArgOrOpts === "object" && actionArgOrOpts !== null) {
52229
+ return { serviceArg: serviceArgOrOpts, opts: actionArgOrOpts };
52230
+ }
52231
+ return { serviceArg: serviceArgOrOpts, actionArg: actionArgOrOpts, opts: maybeOpts ?? {} };
52232
+ }
52233
+ function readTextReference(value) {
52234
+ if (!value.startsWith("@")) return value;
52235
+ const path9 = value.slice(1);
52236
+ if (!path9) throw cliError("INVALID_ARG", "@ file references must include a path");
52237
+ if (path9 === "-") return fs6.readFileSync(0, "utf8");
52238
+ return fs6.readFileSync(path9, "utf8");
52239
+ }
52240
+ function parseJsonObject(raw, label) {
52241
+ let parsed;
52242
+ try {
52243
+ parsed = JSON.parse(raw);
52244
+ } catch (err) {
52245
+ throw cliError("INVALID_ARG", `${label} is not valid JSON: ${err.message}`);
52246
+ }
52247
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
52248
+ throw cliError("INVALID_ARG", `${label} must be a JSON object`);
52249
+ }
52250
+ return parsed;
52251
+ }
52252
+ function parseActionPayload(opts) {
52253
+ if (opts.dataJson && opts.dataFile) {
52254
+ throw cliError("INVALID_ARG", "use only one of --data-json or --data-file");
52255
+ }
52256
+ const payload = {};
52257
+ if (opts.dataJson) {
52258
+ Object.assign(payload, parseJsonObject(opts.dataJson, "--data-json"));
52259
+ }
52260
+ if (opts.dataFile) {
52261
+ const raw = opts.dataFile === "-" ? fs6.readFileSync(0, "utf8") : fs6.readFileSync(opts.dataFile, "utf8");
52262
+ Object.assign(payload, parseJsonObject(raw, "--data-file"));
52263
+ }
52264
+ for (const rawParam of opts.param ?? []) {
52265
+ const separator = rawParam.indexOf("=");
52266
+ if (separator <= 0) {
52267
+ throw cliError("INVALID_ARG", "--param values must use key=value");
52268
+ }
52269
+ const key = rawParam.slice(0, separator).trim();
52270
+ if (!key) throw cliError("INVALID_ARG", "--param keys must not be empty");
52271
+ payload[key] = readTextReference(rawParam.slice(separator + 1));
52272
+ }
52273
+ return payload;
52274
+ }
52275
+ function validateRequiredParams(action, payload) {
52276
+ for (const [name, spec] of Object.entries(action.parameters ?? {})) {
52277
+ if (!spec.required) continue;
52278
+ if (payload[name] === void 0 || payload[name] === null || payload[name] === "") {
52279
+ throw cliError("INVALID_ARG", `missing required parameter ${name}`);
52280
+ }
52281
+ }
52282
+ }
52283
+ function safeUrl(value, label) {
52284
+ let url2;
52285
+ try {
52286
+ url2 = new URL(value);
52287
+ } catch {
52288
+ throw cliError("INVALID_ARG", `${label} must be a valid URL`);
52289
+ }
52290
+ if (url2.protocol !== "https:" && url2.protocol !== "http:") {
52291
+ throw cliError("INVALID_ARG", `${label} must use http or https`);
52292
+ }
52293
+ if (url2.username || url2.password) {
52294
+ throw cliError("INVALID_ARG", `${label} must not include credentials`);
52295
+ }
52296
+ return url2;
52297
+ }
52298
+ function resolveActionUrl(input) {
52299
+ 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);
52300
+ if (!base) {
52301
+ throw cliError(
52302
+ "INVALID_ARG",
52303
+ "manifest must provide execution.base_url or app_origin, or the service must provide a homepage/return URL"
52304
+ );
52305
+ }
52306
+ const baseUrl = safeUrl(base, "action base URL");
52307
+ return new URL(input.action.endpoint.path, baseUrl);
52308
+ }
52309
+ function setCookieHeaderValues(headers) {
52310
+ const getSetCookie = headers.getSetCookie;
52311
+ return typeof getSetCookie === "function" ? getSetCookie.call(headers) : [headers.get("set-cookie")].filter((value) => Boolean(value));
52312
+ }
52313
+ function defaultCookiePath(pathname) {
52314
+ if (!pathname.startsWith("/") || pathname === "/") return "/";
52315
+ const lastSlash = pathname.lastIndexOf("/");
52316
+ if (lastSlash <= 0) return "/";
52317
+ return pathname.slice(0, lastSlash);
52318
+ }
52319
+ function parseSessionCookie(value, sourceUrl) {
52320
+ const parts = value.split(";").map((part) => part.trim()).filter(Boolean);
52321
+ const pair = parts.shift();
52322
+ if (!pair || !pair.includes("=") || pair.startsWith("=")) return null;
52323
+ const sourceHost = sourceUrl.hostname.toLowerCase();
52324
+ let host = sourceHost;
52325
+ let path9 = defaultCookiePath(sourceUrl.pathname);
52326
+ let secure = false;
52327
+ for (const part of parts) {
52328
+ const separator = part.indexOf("=");
52329
+ const rawName = separator >= 0 ? part.slice(0, separator) : part;
52330
+ const rawValue = separator >= 0 ? part.slice(separator + 1) : "";
52331
+ const name = rawName.trim().toLowerCase();
52332
+ if (name === "secure") {
52333
+ secure = true;
52334
+ } else if (name === "path" && rawValue.trim().startsWith("/")) {
52335
+ path9 = rawValue.trim();
52336
+ } else if (name === "domain") {
52337
+ const domain2 = rawValue.trim().replace(/^\./, "").toLowerCase();
52338
+ if (domain2 !== sourceHost) return null;
52339
+ host = domain2;
52340
+ }
52341
+ }
52342
+ return { pair, host, path: path9, secure };
52343
+ }
52344
+ function cookiePathMatches(requestPath, cookiePath) {
52345
+ if (requestPath === cookiePath) return true;
52346
+ if (cookiePath.endsWith("/")) return requestPath.startsWith(cookiePath);
52347
+ return requestPath.startsWith(`${cookiePath}/`);
52348
+ }
52349
+ function cookieHeaderForUrl(cookies, url2) {
52350
+ const host = url2.hostname.toLowerCase();
52351
+ const valid = cookies.filter((cookie) => cookie.host === host).filter((cookie) => !cookie.secure || url2.protocol === "https:").filter((cookie) => cookiePathMatches(url2.pathname || "/", cookie.path)).map((cookie) => cookie.pair);
52352
+ return valid.length > 0 ? valid.join("; ") : null;
52353
+ }
52354
+ function sessionCookiesFromSetCookie(headers, sourceUrl) {
52355
+ return setCookieHeaderValues(headers).map((value) => parseSessionCookie(value, sourceUrl)).filter((value) => Boolean(value));
52356
+ }
52357
+ async function establishServiceSession(input) {
52358
+ const callbackUrl = buildAgentCallbackHandoffUrl(input.service.returnUrl, input.login.requestId);
52359
+ if (!callbackUrl) {
52360
+ throw cliError("INTEGRATION_INVOKE_FAILED", "service return URL cannot be used for Agent Login callback handoff");
52361
+ }
52362
+ const parsedCallbackUrl = safeUrl(callbackUrl, "service callback URL");
52363
+ const response = await fetch(callbackUrl, {
52364
+ method: "GET",
52365
+ redirect: "manual",
52366
+ headers: { accept: "text/html,application/json" }
52367
+ });
52368
+ if (response.status < 200 || response.status >= 400) {
52369
+ throw cliError("INTEGRATION_INVOKE_FAILED", `service callback handoff failed with HTTP ${response.status}`);
52370
+ }
52371
+ const cookies = sessionCookiesFromSetCookie(response.headers, parsedCallbackUrl);
52372
+ if (cookies.length === 0) {
52373
+ throw cliError(
52374
+ "INTEGRATION_INVOKE_FAILED",
52375
+ "service callback handoff did not set a session cookie; the service may not support stateless Agent Login API actions yet"
52376
+ );
52377
+ }
52378
+ return cookies;
52379
+ }
52380
+ function appendPayloadAsQuery(url2, payload) {
52381
+ for (const [key, value] of Object.entries(payload)) {
52382
+ if (value === void 0 || value === null) continue;
52383
+ url2.searchParams.set(key, typeof value === "string" ? value : JSON.stringify(value));
52384
+ }
52385
+ }
52386
+ async function invokeHttpAction(input) {
52387
+ const url2 = new URL(input.url);
52388
+ const cookie = cookieHeaderForUrl(input.cookies, url2);
52389
+ if (!cookie) {
52390
+ throw cliError(
52391
+ "INTEGRATION_INVOKE_FAILED",
52392
+ "service callback handoff did not set a session cookie usable for the action URL; ensure the cookie host and Path cover the action endpoint"
52393
+ );
52394
+ }
52395
+ const headers = {
52396
+ accept: "application/json,text/plain,*/*",
52397
+ cookie
52398
+ };
52399
+ const init = {
52400
+ method: input.action.endpoint.method,
52401
+ headers,
52402
+ redirect: "follow"
52403
+ };
52404
+ if (input.action.endpoint.method === "GET") {
52405
+ appendPayloadAsQuery(url2, input.payload);
52406
+ } else {
52407
+ headers["content-type"] = "application/json";
52408
+ init.body = JSON.stringify(input.payload);
52409
+ }
52410
+ const response = await fetch(url2, init);
52411
+ const contentType = response.headers.get("content-type") ?? "";
52412
+ if (contentType.includes("application/json")) {
52413
+ const value2 = await response.json().catch(() => {
52414
+ throw cliError("INVALID_JSON_RESPONSE", `service action returned invalid JSON (HTTP ${response.status})`);
52415
+ });
52416
+ if (!response.ok) {
52417
+ const message = value2 && typeof value2 === "object" && "error" in value2 ? String(value2.error) : `service action failed with HTTP ${response.status}`;
52418
+ throw cliError("INTEGRATION_INVOKE_FAILED", message);
52419
+ }
52420
+ return { kind: "json", status: response.status, value: value2 };
52421
+ }
52422
+ const value = await response.text();
52423
+ if (!response.ok) {
52424
+ throw cliError("INTEGRATION_INVOKE_FAILED", value || `service action failed with HTTP ${response.status}`);
52425
+ }
52426
+ return { kind: "text", status: response.status, value };
52427
+ }
52428
+ function formatActions(input) {
52429
+ const actions = input.manifest.actions ?? [];
52430
+ const lines = [
52431
+ `Actions for ${input.service.name}`,
52432
+ `service: ${input.service.clientId}`,
52433
+ `manifest: ${input.manifestUrl}`
52434
+ ];
52435
+ if (actions.length === 0) {
52436
+ lines.push("- none");
52437
+ return lines.join("\n");
52438
+ }
52439
+ for (const action of actions) {
52440
+ const required2 = Object.entries(action.parameters ?? {}).filter(([, param]) => param.required).map(([name]) => name);
52441
+ lines.push(`- ${action.name}`);
52442
+ lines.push(` endpoint: ${action.endpoint.method} ${action.endpoint.path}`);
52443
+ if (action.description) lines.push(` description: ${action.description}`);
52444
+ if (required2.length > 0) lines.push(` required params: ${required2.join(", ")}`);
52445
+ }
52446
+ lines.push(`next: raft integration invoke --service ${JSON.stringify(input.service.clientId)} --action ${JSON.stringify(actions[0]?.name ?? "<name>")}`);
52447
+ return lines.join("\n");
52448
+ }
52449
+ function pickViewerUrl(value) {
52450
+ return value && typeof value === "object" && typeof value.viewerUrl === "string" ? value.viewerUrl : null;
52451
+ }
52452
+ function formatActionResult(input) {
52453
+ const lines = [
52454
+ `Action invoked: ${input.action.name}`,
52455
+ `service: ${input.service.clientId}`,
52456
+ `status: HTTP ${input.result.status}`
52457
+ ];
52458
+ if (input.result.kind === "json") {
52459
+ const viewerUrl = pickViewerUrl(input.result.value);
52460
+ if (viewerUrl) lines.push(`viewer URL: ${viewerUrl}`);
52461
+ lines.push("result:");
52462
+ lines.push(JSON.stringify(input.result.value, null, 2));
52463
+ } else if (input.result.value) {
52464
+ lines.push("result:");
52465
+ lines.push(input.result.value);
52466
+ }
52467
+ return lines.join("\n");
52468
+ }
52469
+ async function fetchManifestForInvoke(service) {
52470
+ if (!service.agentManifestUrl) {
52471
+ throw cliError("INTEGRATION_MANIFEST_MISSING", `${service.name} does not expose an agent behavior manifest`);
52472
+ }
52473
+ try {
52474
+ const fetchManifest = service.agentManifestUrlSource === "well_known" ? fetchAgentManifestWithWellKnownAliases : fetchAgentManifest;
52475
+ return await fetchManifest(service.agentManifestUrl);
52476
+ } catch (err) {
52477
+ if (err instanceof AgentManifestFetchError && (err.status === 404 || err.status === 410)) {
52478
+ throw cliError("INTEGRATION_MANIFEST_MISSING", "agent behavior manifest was not found", { cause: err });
52479
+ }
52480
+ if (err instanceof AgentManifestResponseFormatError) {
52481
+ throw cliError("INTEGRATION_MANIFEST_INVALID", err.message, { cause: err });
52482
+ }
52483
+ throw cliError("INTEGRATION_MANIFEST_INVALID", err.message, { cause: err });
52484
+ }
52485
+ }
52486
+ var integrationInvokeCommand = defineCommand(
52487
+ {
52488
+ name: "invoke",
52489
+ description: "Invoke a manifest-backed HTTP API action for a registered integration",
52490
+ arguments: ["[service]", "[action]"],
52491
+ options: [
52492
+ { flags: "--service <id>", description: "Registered service id, client id, or exact service name" },
52493
+ { flags: "--action <name>", description: "Manifest action name to invoke" },
52494
+ { flags: "--list-actions", description: "List manifest actions instead of invoking one" },
52495
+ {
52496
+ flags: "--param <key=value>",
52497
+ description: "Action parameter; repeatable. Use key=@file or key=@- to read text",
52498
+ parse: (value, previous = []) => {
52499
+ previous.push(value);
52500
+ return previous;
52501
+ }
52502
+ },
52503
+ { flags: "--data-json <json>", description: "JSON object request body for the action" },
52504
+ { flags: "--data-file <path>", description: "JSON object request body file, or - for stdin" },
52505
+ {
52506
+ flags: "--scope <scope>",
52507
+ description: "Login scope to request before invoking; can be repeated or comma-separated",
52508
+ parse: (value, previous = []) => {
52509
+ previous.push(value);
52510
+ return previous;
52511
+ }
52512
+ },
52513
+ { flags: "--target <target>", description: "Conversation target to post a human approval card when approval is required" },
52514
+ { flags: "--json", description: "Emit machine-readable JSON" }
52515
+ ]
52516
+ },
52517
+ async (cmdCtx, serviceArgOrOpts, actionArgOrOpts, maybeOpts) => {
52518
+ const { serviceArg, actionArg, opts } = parseHandlerArgs(serviceArgOrOpts, actionArgOrOpts, maybeOpts);
52519
+ const serviceQuery = (opts.service ?? serviceArg ?? "").trim();
52520
+ const actionName = (opts.action ?? actionArg ?? "").trim();
52521
+ if (!serviceQuery) throw cliError("INVALID_ARG", "--service or service argument is required");
52522
+ if (!opts.listActions && !actionName) throw cliError("INVALID_ARG", "--action or action argument is required");
52523
+ const agentContext = cmdCtx.loadAgentContext();
52524
+ const client = cmdCtx.createApiClient(agentContext);
52525
+ const api = createAgentApiSurfaceClient(client);
52526
+ const listRes = await api.integrations.list();
52527
+ if (!listRes.ok || !listRes.data) {
52528
+ const code = listRes.status >= 500 ? "SERVER_5XX" : "INTEGRATION_LIST_FAILED";
52529
+ throw cliError(code, listRes.error ?? `HTTP ${listRes.status}`);
52530
+ }
52531
+ const service = findService2(listRes.data, serviceQuery);
52532
+ if (!service) {
52533
+ throw cliError("INTEGRATION_NOT_FOUND", `No registered integration matched ${serviceQuery}`);
52534
+ }
52535
+ const manifest = await fetchManifestForInvoke(service);
52536
+ if (manifest.execution.mode !== "http_api") {
52537
+ throw cliError("INTEGRATION_MANIFEST_UNSUPPORTED", "manifest execution mode is not http_api");
52538
+ }
52539
+ if (opts.listActions) {
52540
+ if (opts.json) {
52541
+ writeJson(cmdCtx.io, {
52542
+ ok: true,
52543
+ data: {
52544
+ service: service.clientId,
52545
+ manifestUrl: service.agentManifestUrl,
52546
+ actions: manifest.actions ?? []
52547
+ }
52548
+ });
52549
+ return;
52550
+ }
52551
+ writeText(cmdCtx.io, `${formatActions({ service, manifestUrl: service.agentManifestUrl ?? "-", manifest })}
52552
+ `);
52553
+ return;
52554
+ }
52555
+ const action = (manifest.actions ?? []).find((candidate) => candidate.name === actionName);
52556
+ if (!action) throw cliError("INVALID_ARG", `manifest does not define action ${actionName}`);
52557
+ const payload = parseActionPayload(opts);
52558
+ validateRequiredParams(action, payload);
52559
+ const scopes = normalizeScopes2(opts.scope);
52560
+ const loginRes = await api.integrations.login({
52561
+ service: service.clientId,
52562
+ scopes,
52563
+ target: opts.target?.trim() || void 0
52564
+ });
52565
+ if (!loginRes.ok || !loginRes.data) {
52566
+ const code = loginRes.status >= 500 ? "SERVER_5XX" : "INTEGRATION_LOGIN_FAILED";
52567
+ throw cliError(code, loginRes.error ?? `HTTP ${loginRes.status}`);
52568
+ }
52569
+ if (loginRes.data.status === "approval_required") {
52570
+ throw cliError(
52571
+ "INTEGRATION_APPROVAL_REQUIRED",
52572
+ "human approval is required before invoking this integration action",
52573
+ { suggestedNextAction: "Ask a server owner/admin to approve the integration login request, then rerun the command." }
52574
+ );
52575
+ }
52576
+ const cookies = await establishServiceSession({ login: loginRes.data, service });
52577
+ const url2 = resolveActionUrl({ service, manifest, action });
52578
+ const result2 = await invokeHttpAction({ url: url2, action, payload, cookies });
52579
+ if (opts.json) {
52580
+ writeJson(cmdCtx.io, {
52581
+ ok: true,
52582
+ data: {
52583
+ service: service.clientId,
52584
+ action: action.name,
52585
+ status: result2.status,
52586
+ result: result2.value
52587
+ }
52588
+ });
52589
+ return;
52590
+ }
52591
+ writeText(cmdCtx.io, `${formatActionResult({ service, action, result: result2 })}
52592
+ `);
52593
+ }
52594
+ );
52595
+ function registerIntegrationInvokeCommand(parent, runtimeOptions = {}) {
52596
+ registerCliCommand(parent, integrationInvokeCommand, runtimeOptions);
52597
+ }
52598
+
52599
+ // src/commands/integration/app.ts
52600
+ init_esm_shims();
52601
+ function normalizeScopes3(raw) {
52602
+ if (!raw || raw.length === 0) return void 0;
52603
+ const scopes = Array.from(new Set(
52604
+ raw.flatMap((value) => value.split(",")).map((value) => value.trim()).filter(Boolean)
52605
+ )).sort();
52606
+ if (scopes.length === 0) {
52607
+ throw cliError("INVALID_ARG", "--scope must include at least one non-empty scope");
52608
+ }
52609
+ return scopes;
52610
+ }
50943
52611
  function requiredTrimmed(value, flag) {
50944
52612
  const trimmed = value?.trim() ?? "";
50945
52613
  if (!trimmed) throw cliError("INVALID_ARG", `${flag} is required`);
@@ -50968,7 +52636,7 @@ function formatAppPrepare(data) {
50968
52636
  async function prepareApp(mode, ctx, opts) {
50969
52637
  const target = requiredTrimmed(opts.target, "--target");
50970
52638
  const clientKey = requiredTrimmed(opts.clientKey, "--client-key");
50971
- const scopes = normalizeScopes2([...opts.scope ?? [], ...opts.scopes ?? []]);
52639
+ const scopes = normalizeScopes3([...opts.scope ?? [], ...opts.scopes ?? []]);
50972
52640
  const agentContext = ctx.loadAgentContext();
50973
52641
  const client = ctx.createApiClient(agentContext);
50974
52642
  const body = {
@@ -50999,6 +52667,40 @@ async function prepareApp(mode, ctx, opts) {
50999
52667
  writeText(ctx.io, `${formatAppPrepare(res.data)}
51000
52668
  `);
51001
52669
  }
52670
+ function formatAppRotateSecret(data) {
52671
+ return [
52672
+ `Integration app secret regenerated for ${data.clientName} (${data.clientKey})`,
52673
+ `client secret: ${data.clientSecret}`,
52674
+ "shown once \u2014 store it now; regenerating again invalidates the previous secret"
52675
+ ].join("\n");
52676
+ }
52677
+ async function rotateAppSecret(ctx, opts) {
52678
+ const clientKey = requiredTrimmed(opts.client, "--client");
52679
+ const agentContext = ctx.loadAgentContext();
52680
+ const client = ctx.createApiClient(agentContext);
52681
+ const res = await createAgentApiSurfaceClient(client).integrations.rotateAppSecret({ clientKey });
52682
+ if (!res.ok || !res.data) {
52683
+ const code = res.status >= 500 ? "SERVER_5XX" : "INTEGRATION_APP_ROTATE_SECRET_FAILED";
52684
+ throw cliError(code, res.error ?? `HTTP ${res.status}`);
52685
+ }
52686
+ if (opts.json) {
52687
+ writeJson(ctx.io, { ok: true, data: res.data });
52688
+ return;
52689
+ }
52690
+ writeText(ctx.io, `${formatAppRotateSecret(res.data)}
52691
+ `);
52692
+ }
52693
+ var integrationAppRotateSecretCommand = defineCommand(
52694
+ {
52695
+ name: "rotate-secret",
52696
+ description: "Regenerate the one-time client secret for a server-local app you registered (invalidates the previous secret)",
52697
+ options: [
52698
+ { flags: "--client <key>", description: "App client key / OAuth client_id you registered" },
52699
+ { flags: "--json", description: "Emit machine-readable JSON" }
52700
+ ]
52701
+ },
52702
+ async (ctx, opts) => rotateAppSecret(ctx, opts)
52703
+ );
51002
52704
  var sharedOptions = [
51003
52705
  { flags: "--client-key <key>", description: "Stable app client key / OAuth client_id to reserve or update" },
51004
52706
  { flags: "--name <name>", description: "App display name" },
@@ -51048,6 +52750,7 @@ function registerIntegrationAppCommands(parent, runtimeOptions = {}) {
51048
52750
  const prepareCmd = appCmd.command("prepare").description("Prepare app registration/update action cards");
51049
52751
  registerCliCommand(prepareCmd, integrationAppPrepareRegisterCommand, runtimeOptions);
51050
52752
  registerCliCommand(prepareCmd, integrationAppPrepareUpdateCommand, runtimeOptions);
52753
+ registerCliCommand(appCmd, integrationAppRotateSecretCommand, runtimeOptions);
51051
52754
  }
51052
52755
 
51053
52756
  // src/commands/reminder/schedule.ts
@@ -51466,6 +53169,10 @@ registerAgentListCommand(agentCmd);
51466
53169
  registerAgentBridgeCommand(agentCmd);
51467
53170
  var channelCmd = program2.command("channel").description("Channel membership and attention operations");
51468
53171
  registerChannelMembersCommand(channelCmd);
53172
+ registerChannelCreateCommand(channelCmd);
53173
+ registerChannelUpdateCommand(channelCmd);
53174
+ registerChannelAddMemberCommand(channelCmd);
53175
+ registerChannelRemoveMemberCommand(channelCmd);
51469
53176
  registerChannelJoinCommand(channelCmd);
51470
53177
  registerChannelLeaveCommand(channelCmd);
51471
53178
  registerChannelMuteCommand(channelCmd);
@@ -51474,6 +53181,7 @@ var threadCmd = program2.command("thread").description("Thread attention operati
51474
53181
  registerThreadUnfollowCommand(threadCmd);
51475
53182
  var serverCmd = program2.command("server").description("Server / workspace introspection");
51476
53183
  registerServerInfoCommand(serverCmd);
53184
+ registerServerUpdateCommand(serverCmd);
51477
53185
  var manualCmd = program2.command("manual").description("Slock Manual for Agents retrieval (canonical operating topics)");
51478
53186
  registerKnowledgeGetCommand(manualCmd);
51479
53187
  var knowledgeCmd = program2.command("knowledge").description("Legacy alias for `raft manual`");
@@ -51506,6 +53214,7 @@ var integrationCmd = program2.command("integration").description("Third-party se
51506
53214
  registerIntegrationListCommand(integrationCmd);
51507
53215
  registerIntegrationLoginCommand(integrationCmd);
51508
53216
  registerIntegrationEnvCommand(integrationCmd);
53217
+ registerIntegrationInvokeCommand(integrationCmd);
51509
53218
  registerIntegrationAppCommands(integrationCmd);
51510
53219
  var reminderCmd = program2.command("reminder").description("Reminder operations");
51511
53220
  registerReminderScheduleCommand(reminderCmd);