@michael-joseph-miller/ant-bot 0.4.0 → 0.4.2

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/CHANGELOG.md CHANGED
@@ -4,6 +4,29 @@ All notable changes to ant-bot are recorded here. The format follows
4
4
  [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and versions follow
5
5
  [semantic versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [0.4.2] — 2026-08-24
8
+
9
+ ### Changed
10
+
11
+ - **JSON stays out of the thread.** A tool that returns structured data — a mail search, a thread
12
+ fetch — now shows one line saying what came back (`Result — 50 threads · 82.1 KB`) with the JSON
13
+ behind it, instead of a page of it between you and the Bot's actual reply. Plain-text results
14
+ stay visible, because that is usually the thing you wanted to see.
15
+ - **Tool arguments read as words.** `gmail: search_threads query: is:unread, maxResults: 50`
16
+ rather than a JSON object, in the thread and on every approval card. Lists are counted and
17
+ nested objects collapse to `{…}`.
18
+
19
+ ## [0.4.1] — 2026-08-24
20
+
21
+ ### Fixed
22
+
23
+ - **A Google MCP URL now says what works.** Adding `https://gmailmcp.googleapis.com/…` used to
24
+ report `needs sign-in`, take a client ID, complete the sign-in, and then have every call refused
25
+ with "The caller does not have permission" — Google's endpoint admits only clients Google has
26
+ allowlisted. The check now recognises a Google sign-in behind a custom URL and answers
27
+ "use the built-in instead: `antbot mcp add gmail`", in the CLI and on the Connectors screen,
28
+ without prompting for a client that could not help.
29
+
7
30
  ## [0.4.0] — 2026-08-24
8
31
 
9
32
  Connectors, redesigned. Getting an MCP server usable by a Bot took up to eleven steps and eight
package/README.md CHANGED
@@ -281,10 +281,10 @@ Current totals, as run against this checkout:
281
281
  | Package | Test files | Tests |
282
282
  |---|---|---|
283
283
  | `@antbot/contract` | 1 | 34 |
284
- | `@antbot/daemon` | 29 | 609 |
285
- | `@antbot/ui` | 10 | 98 |
286
- | `@antbot/cli` | 8 | 141 |
287
- | **Total** | **48** | **882** |
284
+ | `@antbot/daemon` | 29 | 614 |
285
+ | `@antbot/ui` | 10 | 105 |
286
+ | `@antbot/cli` | 8 | 142 |
287
+ | **Total** | **48** | **895** |
288
288
 
289
289
  ## Status / not built
290
290
 
@@ -206,7 +206,13 @@ var ConnectorCheckSchema = z.object({
206
206
  /** Who is asking for the sign-in, when known — "Google", "accounts.example.com". */
207
207
  provider: z.string().optional(),
208
208
  tools: z.array(z.object({ name: z.string(), description: z.string() })).default([]),
209
- detail: z.string().optional()
209
+ detail: z.string().optional(),
210
+ /**
211
+ * A built-in that does the same job, when the URL is a provider's own MCP endpoint that admits
212
+ * only clients the provider allowlisted (Google). Sign-in there can succeed and every call
213
+ * still be refused, so the honest verdict names the way that works.
214
+ */
215
+ alternative: z.string().optional()
210
216
  });
211
217
  var RoutineSchema = z.object({
212
218
  id: z.string(),
@@ -425,4 +431,4 @@ export {
425
431
  SettingsSchema,
426
432
  SettingsPatchSchema
427
433
  };
428
- //# sourceMappingURL=chunk-BKF7CUVN.js.map
434
+ //# sourceMappingURL=chunk-G4IIENWF.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../contract/src/limits.ts", "../../contract/src/entities.ts", "../../contract/src/events.ts", "../../contract/src/api.ts"],
4
+ "sourcesContent": ["/** Operational limits \u2014 mirrors grok-bot-system-outline.md \u00A713. */\nexport const LIMITS = {\n MAX_BOTS_AND_GROUPS: 50,\n MIN_GROUP_MEMBERS: 2,\n MAX_GROUP_MEMBERS: 6,\n MAX_ROUTINES_PER_BOT: 50,\n ROUTINE_RUNS_RETAINED: 20,\n MAX_ATTACHMENTS_PER_MESSAGE: 6,\n MAX_ATTACHMENT_BYTES: 25 * 1024 * 1024,\n MAX_VIDEO_ATTACHMENT_BYTES: 200 * 1024 * 1024,\n MAX_BOT_TO_BOT_HOPS: 5,\n DEFAULT_MAX_CONCURRENT_SESSIONS: 2,\n APPROVAL_TIMEOUT_MS: 15 * 60 * 1000,\n TEACH_RECORDING_MAX_MS: 10 * 60 * 1000,\n} as const;\n\n/** Error codes returned by the service layer when a limit is violated. */\nexport const LIMIT_ERROR = {\n TOO_MANY_BOTS: 'TOO_MANY_BOTS',\n GROUP_SIZE: 'GROUP_SIZE',\n TOO_MANY_ROUTINES: 'TOO_MANY_ROUTINES',\n TOO_MANY_ATTACHMENTS: 'TOO_MANY_ATTACHMENTS',\n ATTACHMENT_TOO_LARGE: 'ATTACHMENT_TOO_LARGE',\n HOP_LIMIT: 'HOP_LIMIT',\n} as const;\nexport type LimitErrorCode = (typeof LIMIT_ERROR)[keyof typeof LIMIT_ERROR];\n\nexport class LimitError extends Error {\n constructor(\n public code: LimitErrorCode,\n message: string,\n ) {\n super(message);\n this.name = 'LimitError';\n }\n}\n", "import { z } from 'zod';\n\nexport const BotStateSchema = z.enum([\n 'idle',\n 'queued',\n 'running',\n 'waiting_approval',\n 'waiting_input',\n 'interrupted',\n]);\nexport type BotState = z.infer<typeof BotStateSchema>;\n\nexport const AttentionSchema = z.enum(['none', 'unread', 'needs_attention']);\nexport type Attention = z.infer<typeof AttentionSchema>;\n\n/**\n * Model tiers a Bot can run on, ordered most to least capable \u2014 this is also the order the UI\n * renders them in, so both pickers stay consistent without repeating the list.\n *\n * Each value is a `claude` CLI model alias, passed through verbatim by `resolveModel()`. Adding a\n * tier here means adding an alias the CLI accepts (`claude --model`), not an API model ID.\n */\nexport const MODEL_TIERS = ['fable', 'opus', 'sonnet', 'haiku'] as const;\nexport const ModelTierSchema = z.enum(MODEL_TIERS);\nexport type ModelTier = z.infer<typeof ModelTierSchema>;\n\nexport const BotSchema = z.object({\n id: z.string(),\n slug: z.string().regex(/^[a-z0-9][a-z0-9-]*$/),\n name: z.string().min(1).max(60),\n title: z.string().max(120).default(''),\n description: z.string().max(8000).default(''),\n avatarEmoji: z.string().max(8).default('\uD83E\uDD16'),\n modelTier: ModelTierSchema.default('sonnet'),\n pinned: z.boolean().default(false),\n hidden: z.boolean().default(false),\n notifications: z.boolean().default(true),\n sessionId: z.string().nullable().default(null),\n state: BotStateSchema.default('idle'),\n attention: AttentionSchema.default('none'),\n threadId: z.string().nullable().default(null),\n createdAt: z.number(),\n deletedAt: z.number().nullable().default(null),\n});\nexport type Bot = z.infer<typeof BotSchema>;\n\nexport const ThreadKindSchema = z.enum(['dm', 'group']);\nexport type ThreadKind = z.infer<typeof ThreadKindSchema>;\n\nexport const ThreadSchema = z.object({\n id: z.string(),\n kind: ThreadKindSchema,\n title: z.string().default(''),\n memberBotIds: z.array(z.string()).default([]),\n pinned: z.boolean().default(false),\n hidden: z.boolean().default(false),\n lastReadAt: z.number().default(0),\n createdAt: z.number(),\n});\nexport type Thread = z.infer<typeof ThreadSchema>;\n\n/** Cards render structured, non-prose content inside a message. */\nexport const CardSchema = z.discriminatedUnion('type', [\n z.object({\n type: z.literal('tool'),\n toolName: z.string(),\n summary: z.string(),\n input: z.unknown().optional(),\n result: z.string().optional(),\n status: z.enum(['running', 'ok', 'error', 'denied']),\n }),\n z.object({\n type: z.literal('file'),\n path: z.string(),\n name: z.string(),\n mime: z.string(),\n bytes: z.number(),\n action: z.enum(['created', 'modified']).default('created'),\n }),\n z.object({ type: z.literal('approval'), approvalId: z.string() }),\n z.object({ type: z.literal('handoff'), fromBotId: z.string(), toBotId: z.string(), note: z.string() }),\n z.object({ type: z.literal('error'), message: z.string() }),\n /** A connector asked for a sign-in mid-turn. The link is the provider's; the bot never sees it. */\n z.object({ type: z.literal('signin'), serverName: z.string(), url: z.string() }),\n]);\nexport type Card = z.infer<typeof CardSchema>;\n\nexport const AuthorKindSchema = z.enum(['user', 'bot', 'system']);\nexport type AuthorKind = z.infer<typeof AuthorKindSchema>;\n\nexport const MessageSchema = z.object({\n id: z.string(),\n threadId: z.string(),\n authorKind: AuthorKindSchema,\n authorBotId: z.string().nullable().default(null),\n replyToId: z.string().nullable().default(null),\n contentMd: z.string().default(''),\n cards: z.array(CardSchema).default([]),\n streaming: z.boolean().default(false),\n createdAt: z.number(),\n});\nexport type Message = z.infer<typeof MessageSchema>;\n\nexport const AttachmentSchema = z.object({\n id: z.string(),\n messageId: z.string().nullable(),\n path: z.string(),\n name: z.string(),\n mime: z.string(),\n bytes: z.number(),\n createdAt: z.number(),\n});\nexport type Attachment = z.infer<typeof AttachmentSchema>;\n\nexport const ApprovalStatusSchema = z.enum(['pending', 'allowed', 'denied', 'expired']);\nexport type ApprovalStatus = z.infer<typeof ApprovalStatusSchema>;\n\nexport const ApprovalSchema = z.object({\n id: z.string(),\n botId: z.string(),\n threadId: z.string(),\n toolName: z.string(),\n inputSummary: z.string(),\n rawInput: z.unknown(),\n status: ApprovalStatusSchema.default('pending'),\n decidedBy: z.enum(['user', 'rule', 'auto_review']).nullable().default(null),\n reason: z.string().default(''),\n ruleId: z.string().nullable().default(null),\n createdAt: z.number(),\n decidedAt: z.number().nullable().default(null),\n});\nexport type Approval = z.infer<typeof ApprovalSchema>;\n\nexport const RuleKindSchema = z.enum(['require', 'allow']);\nexport type RuleKind = z.infer<typeof RuleKindSchema>;\n\nexport const RuleSchema = z.object({\n id: z.string(),\n kind: RuleKindSchema,\n /** Glob over tool name, e.g. \"Bash\", \"browser_*\", \"*\" */\n toolPattern: z.string().default('*'),\n /** Optional regex tested against the serialized tool input. */\n inputPattern: z.string().default(''),\n scopeNote: z.string().default(''),\n builtin: z.boolean().default(false),\n enabled: z.boolean().default(true),\n createdAt: z.number(),\n});\nexport type Rule = z.infer<typeof RuleSchema>;\n\nexport const SkillSchema = z.object({\n id: z.string(),\n slug: z.string(),\n name: z.string(),\n description: z.string().default(''),\n path: z.string(),\n source: z.enum(['user', 'taught', 'imported']).default('user'),\n createdAt: z.number(),\n});\nexport type Skill = z.infer<typeof SkillSchema>;\n\n/* ------------------------------ MCP connectors ------------------------------ */\n\n/**\n * Connector names become the middle segment of every tool name the model sees:\n * `mcp__<name>__<tool>`. Underscores are banned outright because `toolNameAliases()`\n * splits on the first `__` pair \u2014 a name containing one would make a connector's tools\n * unmatchable by the rules that are supposed to gate them.\n */\nexport const CONNECTOR_NAME_RE = /^[a-z0-9][a-z0-9-]{0,31}$/;\n\n/** Taken by the built-in servers; a connector using one would overwrite it in the turn's server map. */\nexport const RESERVED_CONNECTOR_NAMES = ['antbot', 'browser'] as const;\n\n/**\n * How to reach an MCP server. Mirrors the Agent SDK's own `McpServerConfig` minus the\n * in-process `sdk` variant, which only the built-in servers use.\n *\n * Secret values are never stored here. An env value or header may embed `{{secret:NAME}}`,\n * resolved against the keychain at mount time \u2014 see `daemon/src/bots/connectors.ts`.\n */\nexport const ConnectorConfigSchema = z.discriminatedUnion('transport', [\n z.object({\n transport: z.literal('stdio'),\n command: z.string().min(1),\n args: z.array(z.string()).default([]),\n env: z.record(z.string(), z.string()).default({}),\n }),\n z.object({\n transport: z.literal('http'),\n url: z.string().url(),\n headers: z.record(z.string(), z.string()).default({}),\n /** Optional allowlist passed through to the SDK. Omit to expose every tool the server offers. */\n tools: z.array(z.string()).optional(),\n }),\n z.object({\n transport: z.literal('sse'),\n url: z.string().url(),\n headers: z.record(z.string(), z.string()).default({}),\n tools: z.array(z.string()).optional(),\n }),\n]);\nexport type ConnectorConfig = z.infer<typeof ConnectorConfigSchema>;\n\nexport const ConnectorSchema = z.object({\n id: z.string(),\n name: z\n .string()\n .regex(CONNECTOR_NAME_RE, 'lowercase letters, digits and hyphens only, max 32 characters')\n .refine((n) => !(RESERVED_CONNECTOR_NAMES as readonly string[]).includes(n), {\n message: `\"antbot\" and \"browser\" are reserved for the built-in servers`,\n }),\n description: z.string().default(''),\n /** Account-wide switch. A disabled connector mounts for nobody, whatever the assignments say. */\n enabled: z.boolean().default(true),\n /**\n * `builtin` \u2014 served by the daemon itself (Gmail\u2026), credentials held by the daemon, config\n * points at the daemon's own `/mcp/<name>`. `custom` \u2014 a command or URL the user added.\n */\n kind: z.enum(['custom', 'builtin']).default('custom'),\n config: ConnectorConfigSchema,\n /** Last verdict from a check or a turn: ready | needs-sign-in | needs-credential | unreachable | connected | failed\u2026 */\n lastStatus: z.string().nullable().default(null),\n lastError: z.string().nullable().default(null),\n checkedAt: z.number().nullable().default(null),\n createdAt: z.number(),\n});\nexport type Connector = z.infer<typeof ConnectorSchema>;\n\n/** The verdict `POST /api/connectors/:id/check` returns, and what `add` prints. */\nexport const ConnectorCheckSchema = z.object({\n status: z.enum(['ready', 'needs-sign-in', 'needs-credential', 'unreachable']),\n /** For needs-sign-in: whether the provider lets ant-bot register itself (no client ID needed). */\n selfRegistration: z.boolean().optional(),\n /** Who is asking for the sign-in, when known \u2014 \"Google\", \"accounts.example.com\". */\n provider: z.string().optional(),\n tools: z.array(z.object({ name: z.string(), description: z.string() })).default([]),\n detail: z.string().optional(),\n /**\n * A built-in that does the same job, when the URL is a provider's own MCP endpoint that admits\n * only clients the provider allowlisted (Google). Sign-in there can succeed and every call\n * still be refused, so the honest verdict names the way that works.\n */\n alternative: z.string().optional(),\n});\nexport type ConnectorCheck = z.infer<typeof ConnectorCheckSchema>;\n\nexport const RoutineSchema = z.object({\n id: z.string(),\n botId: z.string(),\n name: z.string().min(1),\n cronExpr: z.string(),\n timezone: z.string().default('UTC'),\n instructionMd: z.string(),\n enabled: z.boolean().default(true),\n lastRunAt: z.number().nullable().default(null),\n nextRunAt: z.number().nullable().default(null),\n createdAt: z.number(),\n});\nexport type Routine = z.infer<typeof RoutineSchema>;\n\nexport const RoutineRunSchema = z.object({\n id: z.string(),\n routineId: z.string(),\n startedAt: z.number(),\n finishedAt: z.number().nullable().default(null),\n status: z.enum(['running', 'ok', 'failed', 'interrupted']),\n summary: z.string().default(''),\n threadId: z.string().nullable().default(null),\n isTest: z.boolean().default(false),\n});\nexport type RoutineRun = z.infer<typeof RoutineRunSchema>;\n\nexport const MailboxEntrySchema = z.object({\n id: z.string(),\n fromBotId: z.string(),\n toBotId: z.string(),\n contentMd: z.string(),\n hops: z.number().default(1),\n delivered: z.boolean().default(false),\n createdAt: z.number(),\n});\nexport type MailboxEntry = z.infer<typeof MailboxEntrySchema>;\n\nexport const UsageRowSchema = z.object({\n id: z.string(),\n botId: z.string(),\n turnId: z.string(),\n model: z.string(),\n inputTokens: z.number().default(0),\n outputTokens: z.number().default(0),\n cacheReadTokens: z.number().default(0),\n costEstimate: z.number().default(0),\n createdAt: z.number(),\n});\nexport type UsageRow = z.infer<typeof UsageRowSchema>;\n\nexport const TurnOriginSchema = z.enum(['user', 'bot', 'routine', 'system']);\nexport type TurnOrigin = z.infer<typeof TurnOriginSchema>;\n", "import { z } from 'zod';\nimport { BotStateSchema, AttentionSchema, CardSchema, MessageSchema, ApprovalSchema, RoutineRunSchema } from './entities.js';\n\n/** Every server\u2192client event carries {threadId, botId, seq} for ordering/reconciliation. */\nconst base = { seq: z.number(), threadId: z.string().nullable(), botId: z.string().nullable() };\n\nexport const ServerEventSchema = z.discriminatedUnion('type', [\n /** Connection handshake. Carries the current seq so a client can detect gaps. */\n z.object({ ...base, type: z.literal('hello') }),\n z.object({ ...base, type: z.literal('message.created'), message: MessageSchema }),\n z.object({ ...base, type: z.literal('message.delta'), messageId: z.string(), delta: z.string() }),\n z.object({ ...base, type: z.literal('message.done'), messageId: z.string(), contentMd: z.string() }),\n z.object({ ...base, type: z.literal('message.card'), messageId: z.string(), card: CardSchema, cardIndex: z.number() }),\n z.object({ ...base, type: z.literal('bot.state'), state: BotStateSchema, attention: AttentionSchema }),\n z.object({ ...base, type: z.literal('approval.pending'), approval: ApprovalSchema }),\n z.object({ ...base, type: z.literal('approval.resolved'), approval: ApprovalSchema }),\n z.object({ ...base, type: z.literal('routine.run'), run: RoutineRunSchema }),\n z.object({ ...base, type: z.literal('usage.tick'), inputTokens: z.number(), outputTokens: z.number(), model: z.string() }),\n z.object({ ...base, type: z.literal('notify'), title: z.string(), body: z.string(), level: z.enum(['info', 'warn', 'error']) }),\n z.object({ ...base, type: z.literal('secret.request'), requestId: z.string(), name: z.string(), reason: z.string() }),\n z.object({ ...base, type: z.literal('thread.updated'), threadId2: z.string() }),\n]);\nexport type ServerEvent = z.infer<typeof ServerEventSchema>;\nexport type ServerEventType = ServerEvent['type'];\n\n/* ------------------------- screencast input (client \u2192 server) ------------------------- */\n\n/**\n * Human input forwarded over the screencast websocket while a screen is taken over.\n *\n * Coordinates are **normalised** (0\u20131, fractions of the rendered frame) rather than pixels: the\n * screencast is capped at 1280px wide and the browser then scales the image to fit the pane, so\n * the client cannot know the page's real viewport and the server cannot know the client's. Each\n * side converts against what it does know.\n *\n * The daemon dispatches these only while `takeOver()` is active for that bot \u2014 see\n * `docs/SECURITY.md`. Input is a human acting as themselves, so it does not pass the Permission\n * Gateway; the gateway governs what *bots* do.\n */\nexport const ScreencastInputSchema = z.discriminatedUnion('kind', [\n z.object({\n kind: z.literal('mouse'),\n action: z.enum(['move', 'down', 'up', 'wheel']),\n x: z.number().min(0).max(1),\n y: z.number().min(0).max(1),\n button: z.enum(['left', 'middle', 'right']).default('left'),\n clickCount: z.number().int().min(0).max(3).default(1),\n /** Wheel deltas, in CSS pixels. Only read for `action: 'wheel'`. */\n deltaX: z.number().default(0),\n deltaY: z.number().default(0),\n }),\n z.object({\n kind: z.literal('key'),\n action: z.enum(['down', 'up']),\n /** A KeyboardEvent.key value \u2014 Playwright's keyboard maps these to the right key codes. */\n key: z.string().min(1).max(32),\n }),\n z.object({\n kind: z.literal('text'),\n /** Committed text (IME, paste, or a printable keypress), inserted verbatim. */\n text: z.string().min(1).max(4096),\n }),\n]);\nexport type ScreencastInput = z.infer<typeof ScreencastInputSchema>;\n\n/** Frames the client may send on the screencast socket. */\nexport const ScreencastClientFrameSchema = z.discriminatedUnion('type', [\n z.object({ type: z.literal('input'), input: ScreencastInputSchema }),\n /**\n * Asks for the remote page's current text selection, so the human can copy out of it.\n *\n * A round trip is needed because the two clipboards are different: pressing Ctrl+C in the\n * viewer copies whatever is selected in *your* browser (nothing \u2014 the page is a JPEG), and\n * forwarding Ctrl+C to the page would write to the headless browser's clipboard, which you\n * have no way to read. So the daemon reads the selection and hands the text back for the\n * viewer to put on your clipboard.\n */\n z.object({ type: z.literal('selection-request') }),\n]);\nexport type ScreencastClientFrame = z.infer<typeof ScreencastClientFrameSchema>;\n", "import { z } from 'zod';\nimport {\n BotSchema, ThreadSchema, MessageSchema, ApprovalSchema, RuleSchema,\n SkillSchema, RoutineSchema, RoutineRunSchema, UsageRowSchema, ModelTierSchema,\n ConnectorSchema, ConnectorConfigSchema, type Connector,\n} from './entities.js';\n\nexport const CreateBotRequest = z.object({\n name: z.string().min(1).max(60),\n title: z.string().max(120).optional(),\n description: z.string().max(8000).optional(),\n avatarEmoji: z.string().max(8).optional(),\n modelTier: ModelTierSchema.optional(),\n});\nexport type CreateBotRequest = z.infer<typeof CreateBotRequest>;\n\nexport const UpdateBotRequest = CreateBotRequest.partial().extend({\n pinned: z.boolean().optional(),\n hidden: z.boolean().optional(),\n notifications: z.boolean().optional(),\n});\nexport type UpdateBotRequest = z.infer<typeof UpdateBotRequest>;\n\nexport const CreateThreadRequest = z.object({\n kind: z.enum(['dm', 'group']),\n title: z.string().optional(),\n memberBotIds: z.array(z.string()),\n});\nexport type CreateThreadRequest = z.infer<typeof CreateThreadRequest>;\n\nexport const PostMessageRequest = z.object({\n contentMd: z.string(),\n attachmentIds: z.array(z.string()).optional(),\n replyToId: z.string().nullable().optional(),\n /** explicit @-mention targets resolved by the client */\n mentionBotIds: z.array(z.string()).optional(),\n mentionEveryone: z.boolean().optional(),\n});\nexport type PostMessageRequest = z.infer<typeof PostMessageRequest>;\n\nexport const ApprovalDecisionRequest = z.object({\n decision: z.enum(['allow', 'deny']),\n alwaysRule: z\n .object({ toolPattern: z.string(), inputPattern: z.string().default(''), scopeNote: z.string().default('') })\n .optional(),\n});\nexport type ApprovalDecisionRequest = z.infer<typeof ApprovalDecisionRequest>;\n\nexport const CreateRuleRequest = z.object({\n kind: z.enum(['require', 'allow']),\n toolPattern: z.string().min(1),\n inputPattern: z.string().default(''),\n scopeNote: z.string().default(''),\n});\nexport type CreateRuleRequest = z.infer<typeof CreateRuleRequest>;\n\nexport const CreateRoutineRequest = z.object({\n botId: z.string(),\n name: z.string().min(1),\n cronExpr: z.string().min(1),\n timezone: z.string().optional(),\n instructionMd: z.string().min(1),\n enabled: z.boolean().optional(),\n});\nexport type CreateRoutineRequest = z.infer<typeof CreateRoutineRequest>;\n\nexport const CreateSkillRequest = z.object({\n name: z.string().min(1),\n description: z.string().default(''),\n bodyMd: z.string().min(1),\n source: z.enum(['user', 'taught', 'imported']).optional(),\n});\nexport type CreateSkillRequest = z.infer<typeof CreateSkillRequest>;\n\n/**\n * Either a custom server (`config`) or a built-in one (`builtin`, a catalog name \u2014 the daemon\n * fills in the config). `botIds` assigns it in the same call so adding is one step.\n */\nexport const CreateConnectorRequest = z\n .object({\n name: ConnectorSchema.shape.name,\n description: z.string().default(''),\n config: ConnectorConfigSchema.optional(),\n builtin: z.string().optional(),\n enabled: z.boolean().optional(),\n botIds: z.array(z.string()).optional(),\n })\n .refine((v) => Boolean(v.config) !== Boolean(v.builtin), { message: 'Give either config or builtin, not both' });\nexport type CreateConnectorRequest = z.infer<typeof CreateConnectorRequest>;\n\n/**\n * No `name`: renaming a connector renames every tool the model and the rules see\n * (`mcp__<name>__<tool>`), silently orphaning any rule written against the old one.\n * Delete and re-add instead.\n */\nexport const UpdateConnectorRequest = z.object({\n description: z.string().optional(),\n config: ConnectorConfigSchema.optional(),\n enabled: z.boolean().optional(),\n});\nexport type UpdateConnectorRequest = z.infer<typeof UpdateConnectorRequest>;\n\n/**\n * A connector as the API returns it. `missingSecrets` names the `{{secret:\u2026}}` references\n * that have nothing behind them \u2014 surfaced so a connector that will silently fail to mount\n * says so in the UI before a turn runs, rather than going quiet at turn time.\n */\nexport type ApiConnector = Connector & {\n missingSecrets: string[];\n /** Whether an interactive sign-in has been completed and stored for this connector. */\n signedIn: boolean;\n};\n\n/** A catalog entry as the API describes it: what it is and what setting it up will involve. */\nexport interface ApiCatalogEntry {\n name: string;\n displayName: string;\n description: string;\n provider: string;\n /** Whether the provider needs a client ID/secret the user creates (Google) or self-registers. */\n needsClientCredentials: boolean;\n setupSteps: string[];\n}\n\n/**\n * A raw probe: did the server answer, and what did it list. Tool names and descriptions only \u2014\n * never config. Reachable is not usable; `ConnectorCheck` is the verdict a person should read.\n */\nexport interface ConnectorProbeResult {\n ok: boolean;\n tools: { name: string; description: string }[];\n error?: string;\n}\n\n/**\n * Field types, declared once and without defaults. `SettingsSchema` layers the\n * defaults on for reads; `SettingsPatchSchema` deliberately leaves them off.\n */\nconst settingsFields = {\n timezone: z.string(),\n maxConcurrentSessions: z.number().min(1).max(8),\n autoReviewEnabled: z.boolean(),\n theme: z.enum(['system', 'light', 'dark']),\n localExecution: z.enum(['ask', 'always', 'never']),\n dailyTokenBudget: z.number(),\n notificationsEnabled: z.boolean(),\n billingMode: z.enum(['subscription', 'api']),\n computerMode: z.enum(['host', 'container']),\n};\n\nexport const SettingsSchema = z.object({\n timezone: settingsFields.timezone.default('UTC'),\n maxConcurrentSessions: settingsFields.maxConcurrentSessions.default(2),\n autoReviewEnabled: settingsFields.autoReviewEnabled.default(true),\n theme: settingsFields.theme.default('system'),\n localExecution: settingsFields.localExecution.default('ask'),\n dailyTokenBudget: settingsFields.dailyTokenBudget.default(0),\n notificationsEnabled: settingsFields.notificationsEnabled.default(true),\n billingMode: settingsFields.billingMode.default('subscription'),\n computerMode: settingsFields.computerMode.default('host'),\n});\nexport type Settings = z.infer<typeof SettingsSchema>;\n\n/**\n * Body schema for `PATCH /api/settings`. It must NOT carry defaults: parsing a\n * one-field patch through a defaulted schema yields a complete object, and\n * persisting that would reset every setting the client didn't mention \u2014 including\n * `localExecution`, which is a security control (see docs/SECURITY.md).\n */\nexport const SettingsPatchSchema = z.object(settingsFields).partial();\nexport type SettingsPatch = z.infer<typeof SettingsPatchSchema>;\n\nexport const SearchResultSchema = z.object({\n kind: z.enum(['message', 'file', 'routine', 'bot']),\n id: z.string(),\n threadId: z.string().nullable(),\n botId: z.string().nullable(),\n title: z.string(),\n snippet: z.string(),\n createdAt: z.number(),\n});\nexport type SearchResult = z.infer<typeof SearchResultSchema>;\n\nexport type ApiBot = z.infer<typeof BotSchema>;\nexport type ApiThread = z.infer<typeof ThreadSchema>;\nexport type ApiMessage = z.infer<typeof MessageSchema>;\nexport type ApiApproval = z.infer<typeof ApprovalSchema>;\nexport type ApiRule = z.infer<typeof RuleSchema>;\nexport type ApiSkill = z.infer<typeof SkillSchema>;\nexport type ApiRoutine = z.infer<typeof RoutineSchema>;\nexport type ApiRoutineRun = z.infer<typeof RoutineRunSchema>;\nexport type ApiUsageRow = z.infer<typeof UsageRowSchema>;\n\nexport interface RosterEntry { bot: ApiBot; thread: ApiThread | null; lastMessageAt: number }\nexport interface ThreadWithMessages { thread: ApiThread; messages: ApiMessage[] }\nexport interface UsageSummary {\n totals: { inputTokens: number; outputTokens: number; cacheReadTokens: number };\n byBot: Array<{ botId: string; botName: string; inputTokens: number; outputTokens: number }>;\n byDay: Array<{ day: string; inputTokens: number; outputTokens: number }>;\n byModel: Array<{ model: string; inputTokens: number; outputTokens: number }>;\n}\n"],
5
+ "mappings": ";;;;AACO,IAAM,SAAS;EACpB,qBAAqB;EACrB,mBAAmB;EACnB,mBAAmB;EACnB,sBAAsB;EACtB,uBAAuB;EACvB,6BAA6B;EAC7B,sBAAsB,KAAK,OAAO;EAClC,4BAA4B,MAAM,OAAO;EACzC,qBAAqB;EACrB,iCAAiC;EACjC,qBAAqB,KAAK,KAAK;EAC/B,wBAAwB,KAAK,KAAK;;AAI7B,IAAM,cAAc;EACzB,eAAe;EACf,YAAY;EACZ,mBAAmB;EACnB,sBAAsB;EACtB,sBAAsB;EACtB,WAAW;;AAIP,IAAO,aAAP,cAA0B,MAAK;EAE1B;EADT,YACS,MACP,SAAe;AAEf,UAAM,OAAO;AAHN,SAAA,OAAA;AAIP,SAAK,OAAO;EACd;;;;AClCF,SAAS,SAAS;AAEX,IAAM,iBAAiB,EAAE,KAAK;EACnC;EACA;EACA;EACA;EACA;EACA;CACD;AAGM,IAAM,kBAAkB,EAAE,KAAK,CAAC,QAAQ,UAAU,iBAAiB,CAAC;AAUpE,IAAM,cAAc,CAAC,SAAS,QAAQ,UAAU,OAAO;AACvD,IAAM,kBAAkB,EAAE,KAAK,WAAW;AAG1C,IAAM,YAAY,EAAE,OAAO;EAChC,IAAI,EAAE,OAAM;EACZ,MAAM,EAAE,OAAM,EAAG,MAAM,sBAAsB;EAC7C,MAAM,EAAE,OAAM,EAAG,IAAI,CAAC,EAAE,IAAI,EAAE;EAC9B,OAAO,EAAE,OAAM,EAAG,IAAI,GAAG,EAAE,QAAQ,EAAE;EACrC,aAAa,EAAE,OAAM,EAAG,IAAI,GAAI,EAAE,QAAQ,EAAE;EAC5C,aAAa,EAAE,OAAM,EAAG,IAAI,CAAC,EAAE,QAAQ,WAAI;EAC3C,WAAW,gBAAgB,QAAQ,QAAQ;EAC3C,QAAQ,EAAE,QAAO,EAAG,QAAQ,KAAK;EACjC,QAAQ,EAAE,QAAO,EAAG,QAAQ,KAAK;EACjC,eAAe,EAAE,QAAO,EAAG,QAAQ,IAAI;EACvC,WAAW,EAAE,OAAM,EAAG,SAAQ,EAAG,QAAQ,IAAI;EAC7C,OAAO,eAAe,QAAQ,MAAM;EACpC,WAAW,gBAAgB,QAAQ,MAAM;EACzC,UAAU,EAAE,OAAM,EAAG,SAAQ,EAAG,QAAQ,IAAI;EAC5C,WAAW,EAAE,OAAM;EACnB,WAAW,EAAE,OAAM,EAAG,SAAQ,EAAG,QAAQ,IAAI;CAC9C;AAGM,IAAM,mBAAmB,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC;AAG/C,IAAM,eAAe,EAAE,OAAO;EACnC,IAAI,EAAE,OAAM;EACZ,MAAM;EACN,OAAO,EAAE,OAAM,EAAG,QAAQ,EAAE;EAC5B,cAAc,EAAE,MAAM,EAAE,OAAM,CAAE,EAAE,QAAQ,CAAA,CAAE;EAC5C,QAAQ,EAAE,QAAO,EAAG,QAAQ,KAAK;EACjC,QAAQ,EAAE,QAAO,EAAG,QAAQ,KAAK;EACjC,YAAY,EAAE,OAAM,EAAG,QAAQ,CAAC;EAChC,WAAW,EAAE,OAAM;CACpB;AAIM,IAAM,aAAa,EAAE,mBAAmB,QAAQ;EACrD,EAAE,OAAO;IACP,MAAM,EAAE,QAAQ,MAAM;IACtB,UAAU,EAAE,OAAM;IAClB,SAAS,EAAE,OAAM;IACjB,OAAO,EAAE,QAAO,EAAG,SAAQ;IAC3B,QAAQ,EAAE,OAAM,EAAG,SAAQ;IAC3B,QAAQ,EAAE,KAAK,CAAC,WAAW,MAAM,SAAS,QAAQ,CAAC;GACpD;EACD,EAAE,OAAO;IACP,MAAM,EAAE,QAAQ,MAAM;IACtB,MAAM,EAAE,OAAM;IACd,MAAM,EAAE,OAAM;IACd,MAAM,EAAE,OAAM;IACd,OAAO,EAAE,OAAM;IACf,QAAQ,EAAE,KAAK,CAAC,WAAW,UAAU,CAAC,EAAE,QAAQ,SAAS;GAC1D;EACD,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,UAAU,GAAG,YAAY,EAAE,OAAM,EAAE,CAAE;EAChE,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,SAAS,GAAG,WAAW,EAAE,OAAM,GAAI,SAAS,EAAE,OAAM,GAAI,MAAM,EAAE,OAAM,EAAE,CAAE;EACrG,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,OAAO,GAAG,SAAS,EAAE,OAAM,EAAE,CAAE;;EAE1D,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,QAAQ,GAAG,YAAY,EAAE,OAAM,GAAI,KAAK,EAAE,OAAM,EAAE,CAAE;CAChF;AAGM,IAAM,mBAAmB,EAAE,KAAK,CAAC,QAAQ,OAAO,QAAQ,CAAC;AAGzD,IAAM,gBAAgB,EAAE,OAAO;EACpC,IAAI,EAAE,OAAM;EACZ,UAAU,EAAE,OAAM;EAClB,YAAY;EACZ,aAAa,EAAE,OAAM,EAAG,SAAQ,EAAG,QAAQ,IAAI;EAC/C,WAAW,EAAE,OAAM,EAAG,SAAQ,EAAG,QAAQ,IAAI;EAC7C,WAAW,EAAE,OAAM,EAAG,QAAQ,EAAE;EAChC,OAAO,EAAE,MAAM,UAAU,EAAE,QAAQ,CAAA,CAAE;EACrC,WAAW,EAAE,QAAO,EAAG,QAAQ,KAAK;EACpC,WAAW,EAAE,OAAM;CACpB;AAGM,IAAM,mBAAmB,EAAE,OAAO;EACvC,IAAI,EAAE,OAAM;EACZ,WAAW,EAAE,OAAM,EAAG,SAAQ;EAC9B,MAAM,EAAE,OAAM;EACd,MAAM,EAAE,OAAM;EACd,MAAM,EAAE,OAAM;EACd,OAAO,EAAE,OAAM;EACf,WAAW,EAAE,OAAM;CACpB;AAGM,IAAM,uBAAuB,EAAE,KAAK,CAAC,WAAW,WAAW,UAAU,SAAS,CAAC;AAG/E,IAAM,iBAAiB,EAAE,OAAO;EACrC,IAAI,EAAE,OAAM;EACZ,OAAO,EAAE,OAAM;EACf,UAAU,EAAE,OAAM;EAClB,UAAU,EAAE,OAAM;EAClB,cAAc,EAAE,OAAM;EACtB,UAAU,EAAE,QAAO;EACnB,QAAQ,qBAAqB,QAAQ,SAAS;EAC9C,WAAW,EAAE,KAAK,CAAC,QAAQ,QAAQ,aAAa,CAAC,EAAE,SAAQ,EAAG,QAAQ,IAAI;EAC1E,QAAQ,EAAE,OAAM,EAAG,QAAQ,EAAE;EAC7B,QAAQ,EAAE,OAAM,EAAG,SAAQ,EAAG,QAAQ,IAAI;EAC1C,WAAW,EAAE,OAAM;EACnB,WAAW,EAAE,OAAM,EAAG,SAAQ,EAAG,QAAQ,IAAI;CAC9C;AAGM,IAAM,iBAAiB,EAAE,KAAK,CAAC,WAAW,OAAO,CAAC;AAGlD,IAAM,aAAa,EAAE,OAAO;EACjC,IAAI,EAAE,OAAM;EACZ,MAAM;;EAEN,aAAa,EAAE,OAAM,EAAG,QAAQ,GAAG;;EAEnC,cAAc,EAAE,OAAM,EAAG,QAAQ,EAAE;EACnC,WAAW,EAAE,OAAM,EAAG,QAAQ,EAAE;EAChC,SAAS,EAAE,QAAO,EAAG,QAAQ,KAAK;EAClC,SAAS,EAAE,QAAO,EAAG,QAAQ,IAAI;EACjC,WAAW,EAAE,OAAM;CACpB;AAGM,IAAM,cAAc,EAAE,OAAO;EAClC,IAAI,EAAE,OAAM;EACZ,MAAM,EAAE,OAAM;EACd,MAAM,EAAE,OAAM;EACd,aAAa,EAAE,OAAM,EAAG,QAAQ,EAAE;EAClC,MAAM,EAAE,OAAM;EACd,QAAQ,EAAE,KAAK,CAAC,QAAQ,UAAU,UAAU,CAAC,EAAE,QAAQ,MAAM;EAC7D,WAAW,EAAE,OAAM;CACpB;AAWM,IAAM,oBAAoB;AAG1B,IAAM,2BAA2B,CAAC,UAAU,SAAS;AASrD,IAAM,wBAAwB,EAAE,mBAAmB,aAAa;EACrE,EAAE,OAAO;IACP,WAAW,EAAE,QAAQ,OAAO;IAC5B,SAAS,EAAE,OAAM,EAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,EAAE,OAAM,CAAE,EAAE,QAAQ,CAAA,CAAE;IACpC,KAAK,EAAE,OAAO,EAAE,OAAM,GAAI,EAAE,OAAM,CAAE,EAAE,QAAQ,CAAA,CAAE;GACjD;EACD,EAAE,OAAO;IACP,WAAW,EAAE,QAAQ,MAAM;IAC3B,KAAK,EAAE,OAAM,EAAG,IAAG;IACnB,SAAS,EAAE,OAAO,EAAE,OAAM,GAAI,EAAE,OAAM,CAAE,EAAE,QAAQ,CAAA,CAAE;;IAEpD,OAAO,EAAE,MAAM,EAAE,OAAM,CAAE,EAAE,SAAQ;GACpC;EACD,EAAE,OAAO;IACP,WAAW,EAAE,QAAQ,KAAK;IAC1B,KAAK,EAAE,OAAM,EAAG,IAAG;IACnB,SAAS,EAAE,OAAO,EAAE,OAAM,GAAI,EAAE,OAAM,CAAE,EAAE,QAAQ,CAAA,CAAE;IACpD,OAAO,EAAE,MAAM,EAAE,OAAM,CAAE,EAAE,SAAQ;GACpC;CACF;AAGM,IAAM,kBAAkB,EAAE,OAAO;EACtC,IAAI,EAAE,OAAM;EACZ,MAAM,EACH,OAAM,EACN,MAAM,mBAAmB,+DAA+D,EACxF,OAAO,CAAC,MAAM,CAAE,yBAA+C,SAAS,CAAC,GAAG;IAC3E,SAAS;GACV;EACH,aAAa,EAAE,OAAM,EAAG,QAAQ,EAAE;;EAElC,SAAS,EAAE,QAAO,EAAG,QAAQ,IAAI;;;;;EAKjC,MAAM,EAAE,KAAK,CAAC,UAAU,SAAS,CAAC,EAAE,QAAQ,QAAQ;EACpD,QAAQ;;EAER,YAAY,EAAE,OAAM,EAAG,SAAQ,EAAG,QAAQ,IAAI;EAC9C,WAAW,EAAE,OAAM,EAAG,SAAQ,EAAG,QAAQ,IAAI;EAC7C,WAAW,EAAE,OAAM,EAAG,SAAQ,EAAG,QAAQ,IAAI;EAC7C,WAAW,EAAE,OAAM;CACpB;AAIM,IAAM,uBAAuB,EAAE,OAAO;EAC3C,QAAQ,EAAE,KAAK,CAAC,SAAS,iBAAiB,oBAAoB,aAAa,CAAC;;EAE5E,kBAAkB,EAAE,QAAO,EAAG,SAAQ;;EAEtC,UAAU,EAAE,OAAM,EAAG,SAAQ;EAC7B,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAM,GAAI,aAAa,EAAE,OAAM,EAAE,CAAE,CAAC,EAAE,QAAQ,CAAA,CAAE;EAClF,QAAQ,EAAE,OAAM,EAAG,SAAQ;;;;;;EAM3B,aAAa,EAAE,OAAM,EAAG,SAAQ;CACjC;AAGM,IAAM,gBAAgB,EAAE,OAAO;EACpC,IAAI,EAAE,OAAM;EACZ,OAAO,EAAE,OAAM;EACf,MAAM,EAAE,OAAM,EAAG,IAAI,CAAC;EACtB,UAAU,EAAE,OAAM;EAClB,UAAU,EAAE,OAAM,EAAG,QAAQ,KAAK;EAClC,eAAe,EAAE,OAAM;EACvB,SAAS,EAAE,QAAO,EAAG,QAAQ,IAAI;EACjC,WAAW,EAAE,OAAM,EAAG,SAAQ,EAAG,QAAQ,IAAI;EAC7C,WAAW,EAAE,OAAM,EAAG,SAAQ,EAAG,QAAQ,IAAI;EAC7C,WAAW,EAAE,OAAM;CACpB;AAGM,IAAM,mBAAmB,EAAE,OAAO;EACvC,IAAI,EAAE,OAAM;EACZ,WAAW,EAAE,OAAM;EACnB,WAAW,EAAE,OAAM;EACnB,YAAY,EAAE,OAAM,EAAG,SAAQ,EAAG,QAAQ,IAAI;EAC9C,QAAQ,EAAE,KAAK,CAAC,WAAW,MAAM,UAAU,aAAa,CAAC;EACzD,SAAS,EAAE,OAAM,EAAG,QAAQ,EAAE;EAC9B,UAAU,EAAE,OAAM,EAAG,SAAQ,EAAG,QAAQ,IAAI;EAC5C,QAAQ,EAAE,QAAO,EAAG,QAAQ,KAAK;CAClC;AAGM,IAAM,qBAAqB,EAAE,OAAO;EACzC,IAAI,EAAE,OAAM;EACZ,WAAW,EAAE,OAAM;EACnB,SAAS,EAAE,OAAM;EACjB,WAAW,EAAE,OAAM;EACnB,MAAM,EAAE,OAAM,EAAG,QAAQ,CAAC;EAC1B,WAAW,EAAE,QAAO,EAAG,QAAQ,KAAK;EACpC,WAAW,EAAE,OAAM;CACpB;AAGM,IAAM,iBAAiB,EAAE,OAAO;EACrC,IAAI,EAAE,OAAM;EACZ,OAAO,EAAE,OAAM;EACf,QAAQ,EAAE,OAAM;EAChB,OAAO,EAAE,OAAM;EACf,aAAa,EAAE,OAAM,EAAG,QAAQ,CAAC;EACjC,cAAc,EAAE,OAAM,EAAG,QAAQ,CAAC;EAClC,iBAAiB,EAAE,OAAM,EAAG,QAAQ,CAAC;EACrC,cAAc,EAAE,OAAM,EAAG,QAAQ,CAAC;EAClC,WAAW,EAAE,OAAM;CACpB;AAGM,IAAM,mBAAmB,EAAE,KAAK,CAAC,QAAQ,OAAO,WAAW,QAAQ,CAAC;;;ACzS3E,SAAS,KAAAA,UAAS;AAIlB,IAAM,OAAO,EAAE,KAAKC,GAAE,OAAM,GAAI,UAAUA,GAAE,OAAM,EAAG,SAAQ,GAAI,OAAOA,GAAE,OAAM,EAAG,SAAQ,EAAE;AAEtF,IAAM,oBAAoBA,GAAE,mBAAmB,QAAQ;;EAE5DA,GAAE,OAAO,EAAE,GAAG,MAAM,MAAMA,GAAE,QAAQ,OAAO,EAAC,CAAE;EAC9CA,GAAE,OAAO,EAAE,GAAG,MAAM,MAAMA,GAAE,QAAQ,iBAAiB,GAAG,SAAS,cAAa,CAAE;EAChFA,GAAE,OAAO,EAAE,GAAG,MAAM,MAAMA,GAAE,QAAQ,eAAe,GAAG,WAAWA,GAAE,OAAM,GAAI,OAAOA,GAAE,OAAM,EAAE,CAAE;EAChGA,GAAE,OAAO,EAAE,GAAG,MAAM,MAAMA,GAAE,QAAQ,cAAc,GAAG,WAAWA,GAAE,OAAM,GAAI,WAAWA,GAAE,OAAM,EAAE,CAAE;EACnGA,GAAE,OAAO,EAAE,GAAG,MAAM,MAAMA,GAAE,QAAQ,cAAc,GAAG,WAAWA,GAAE,OAAM,GAAI,MAAM,YAAY,WAAWA,GAAE,OAAM,EAAE,CAAE;EACrHA,GAAE,OAAO,EAAE,GAAG,MAAM,MAAMA,GAAE,QAAQ,WAAW,GAAG,OAAO,gBAAgB,WAAW,gBAAe,CAAE;EACrGA,GAAE,OAAO,EAAE,GAAG,MAAM,MAAMA,GAAE,QAAQ,kBAAkB,GAAG,UAAU,eAAc,CAAE;EACnFA,GAAE,OAAO,EAAE,GAAG,MAAM,MAAMA,GAAE,QAAQ,mBAAmB,GAAG,UAAU,eAAc,CAAE;EACpFA,GAAE,OAAO,EAAE,GAAG,MAAM,MAAMA,GAAE,QAAQ,aAAa,GAAG,KAAK,iBAAgB,CAAE;EAC3EA,GAAE,OAAO,EAAE,GAAG,MAAM,MAAMA,GAAE,QAAQ,YAAY,GAAG,aAAaA,GAAE,OAAM,GAAI,cAAcA,GAAE,OAAM,GAAI,OAAOA,GAAE,OAAM,EAAE,CAAE;EACzHA,GAAE,OAAO,EAAE,GAAG,MAAM,MAAMA,GAAE,QAAQ,QAAQ,GAAG,OAAOA,GAAE,OAAM,GAAI,MAAMA,GAAE,OAAM,GAAI,OAAOA,GAAE,KAAK,CAAC,QAAQ,QAAQ,OAAO,CAAC,EAAC,CAAE;EAC9HA,GAAE,OAAO,EAAE,GAAG,MAAM,MAAMA,GAAE,QAAQ,gBAAgB,GAAG,WAAWA,GAAE,OAAM,GAAI,MAAMA,GAAE,OAAM,GAAI,QAAQA,GAAE,OAAM,EAAE,CAAE;EACpHA,GAAE,OAAO,EAAE,GAAG,MAAM,MAAMA,GAAE,QAAQ,gBAAgB,GAAG,WAAWA,GAAE,OAAM,EAAE,CAAE;CAC/E;AAkBM,IAAM,wBAAwBA,GAAE,mBAAmB,QAAQ;EAChEA,GAAE,OAAO;IACP,MAAMA,GAAE,QAAQ,OAAO;IACvB,QAAQA,GAAE,KAAK,CAAC,QAAQ,QAAQ,MAAM,OAAO,CAAC;IAC9C,GAAGA,GAAE,OAAM,EAAG,IAAI,CAAC,EAAE,IAAI,CAAC;IAC1B,GAAGA,GAAE,OAAM,EAAG,IAAI,CAAC,EAAE,IAAI,CAAC;IAC1B,QAAQA,GAAE,KAAK,CAAC,QAAQ,UAAU,OAAO,CAAC,EAAE,QAAQ,MAAM;IAC1D,YAAYA,GAAE,OAAM,EAAG,IAAG,EAAG,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC;;IAEpD,QAAQA,GAAE,OAAM,EAAG,QAAQ,CAAC;IAC5B,QAAQA,GAAE,OAAM,EAAG,QAAQ,CAAC;GAC7B;EACDA,GAAE,OAAO;IACP,MAAMA,GAAE,QAAQ,KAAK;IACrB,QAAQA,GAAE,KAAK,CAAC,QAAQ,IAAI,CAAC;;IAE7B,KAAKA,GAAE,OAAM,EAAG,IAAI,CAAC,EAAE,IAAI,EAAE;GAC9B;EACDA,GAAE,OAAO;IACP,MAAMA,GAAE,QAAQ,MAAM;;IAEtB,MAAMA,GAAE,OAAM,EAAG,IAAI,CAAC,EAAE,IAAI,IAAI;GACjC;CACF;AAIM,IAAM,8BAA8BA,GAAE,mBAAmB,QAAQ;EACtEA,GAAE,OAAO,EAAE,MAAMA,GAAE,QAAQ,OAAO,GAAG,OAAO,sBAAqB,CAAE;;;;;;;;;;EAUnEA,GAAE,OAAO,EAAE,MAAMA,GAAE,QAAQ,mBAAmB,EAAC,CAAE;CAClD;;;AC9ED,SAAS,KAAAC,UAAS;AAOX,IAAM,mBAAmBC,GAAE,OAAO;EACvC,MAAMA,GAAE,OAAM,EAAG,IAAI,CAAC,EAAE,IAAI,EAAE;EAC9B,OAAOA,GAAE,OAAM,EAAG,IAAI,GAAG,EAAE,SAAQ;EACnC,aAAaA,GAAE,OAAM,EAAG,IAAI,GAAI,EAAE,SAAQ;EAC1C,aAAaA,GAAE,OAAM,EAAG,IAAI,CAAC,EAAE,SAAQ;EACvC,WAAW,gBAAgB,SAAQ;CACpC;AAGM,IAAM,mBAAmB,iBAAiB,QAAO,EAAG,OAAO;EAChE,QAAQA,GAAE,QAAO,EAAG,SAAQ;EAC5B,QAAQA,GAAE,QAAO,EAAG,SAAQ;EAC5B,eAAeA,GAAE,QAAO,EAAG,SAAQ;CACpC;AAGM,IAAM,sBAAsBA,GAAE,OAAO;EAC1C,MAAMA,GAAE,KAAK,CAAC,MAAM,OAAO,CAAC;EAC5B,OAAOA,GAAE,OAAM,EAAG,SAAQ;EAC1B,cAAcA,GAAE,MAAMA,GAAE,OAAM,CAAE;CACjC;AAGM,IAAM,qBAAqBA,GAAE,OAAO;EACzC,WAAWA,GAAE,OAAM;EACnB,eAAeA,GAAE,MAAMA,GAAE,OAAM,CAAE,EAAE,SAAQ;EAC3C,WAAWA,GAAE,OAAM,EAAG,SAAQ,EAAG,SAAQ;;EAEzC,eAAeA,GAAE,MAAMA,GAAE,OAAM,CAAE,EAAE,SAAQ;EAC3C,iBAAiBA,GAAE,QAAO,EAAG,SAAQ;CACtC;AAGM,IAAM,0BAA0BA,GAAE,OAAO;EAC9C,UAAUA,GAAE,KAAK,CAAC,SAAS,MAAM,CAAC;EAClC,YAAYA,GACT,OAAO,EAAE,aAAaA,GAAE,OAAM,GAAI,cAAcA,GAAE,OAAM,EAAG,QAAQ,EAAE,GAAG,WAAWA,GAAE,OAAM,EAAG,QAAQ,EAAE,EAAC,CAAE,EAC3G,SAAQ;CACZ;AAGM,IAAM,oBAAoBA,GAAE,OAAO;EACxC,MAAMA,GAAE,KAAK,CAAC,WAAW,OAAO,CAAC;EACjC,aAAaA,GAAE,OAAM,EAAG,IAAI,CAAC;EAC7B,cAAcA,GAAE,OAAM,EAAG,QAAQ,EAAE;EACnC,WAAWA,GAAE,OAAM,EAAG,QAAQ,EAAE;CACjC;AAGM,IAAM,uBAAuBA,GAAE,OAAO;EAC3C,OAAOA,GAAE,OAAM;EACf,MAAMA,GAAE,OAAM,EAAG,IAAI,CAAC;EACtB,UAAUA,GAAE,OAAM,EAAG,IAAI,CAAC;EAC1B,UAAUA,GAAE,OAAM,EAAG,SAAQ;EAC7B,eAAeA,GAAE,OAAM,EAAG,IAAI,CAAC;EAC/B,SAASA,GAAE,QAAO,EAAG,SAAQ;CAC9B;AAGM,IAAM,qBAAqBA,GAAE,OAAO;EACzC,MAAMA,GAAE,OAAM,EAAG,IAAI,CAAC;EACtB,aAAaA,GAAE,OAAM,EAAG,QAAQ,EAAE;EAClC,QAAQA,GAAE,OAAM,EAAG,IAAI,CAAC;EACxB,QAAQA,GAAE,KAAK,CAAC,QAAQ,UAAU,UAAU,CAAC,EAAE,SAAQ;CACxD;AAOM,IAAM,yBAAyBA,GACnC,OAAO;EACN,MAAM,gBAAgB,MAAM;EAC5B,aAAaA,GAAE,OAAM,EAAG,QAAQ,EAAE;EAClC,QAAQ,sBAAsB,SAAQ;EACtC,SAASA,GAAE,OAAM,EAAG,SAAQ;EAC5B,SAASA,GAAE,QAAO,EAAG,SAAQ;EAC7B,QAAQA,GAAE,MAAMA,GAAE,OAAM,CAAE,EAAE,SAAQ;CACrC,EACA,OAAO,CAAC,MAAM,QAAQ,EAAE,MAAM,MAAM,QAAQ,EAAE,OAAO,GAAG,EAAE,SAAS,0CAAyC,CAAE;AAQ1G,IAAM,yBAAyBA,GAAE,OAAO;EAC7C,aAAaA,GAAE,OAAM,EAAG,SAAQ;EAChC,QAAQ,sBAAsB,SAAQ;EACtC,SAASA,GAAE,QAAO,EAAG,SAAQ;CAC9B;AAuCD,IAAM,iBAAiB;EACrB,UAAUA,GAAE,OAAM;EAClB,uBAAuBA,GAAE,OAAM,EAAG,IAAI,CAAC,EAAE,IAAI,CAAC;EAC9C,mBAAmBA,GAAE,QAAO;EAC5B,OAAOA,GAAE,KAAK,CAAC,UAAU,SAAS,MAAM,CAAC;EACzC,gBAAgBA,GAAE,KAAK,CAAC,OAAO,UAAU,OAAO,CAAC;EACjD,kBAAkBA,GAAE,OAAM;EAC1B,sBAAsBA,GAAE,QAAO;EAC/B,aAAaA,GAAE,KAAK,CAAC,gBAAgB,KAAK,CAAC;EAC3C,cAAcA,GAAE,KAAK,CAAC,QAAQ,WAAW,CAAC;;AAGrC,IAAM,iBAAiBA,GAAE,OAAO;EACrC,UAAU,eAAe,SAAS,QAAQ,KAAK;EAC/C,uBAAuB,eAAe,sBAAsB,QAAQ,CAAC;EACrE,mBAAmB,eAAe,kBAAkB,QAAQ,IAAI;EAChE,OAAO,eAAe,MAAM,QAAQ,QAAQ;EAC5C,gBAAgB,eAAe,eAAe,QAAQ,KAAK;EAC3D,kBAAkB,eAAe,iBAAiB,QAAQ,CAAC;EAC3D,sBAAsB,eAAe,qBAAqB,QAAQ,IAAI;EACtE,aAAa,eAAe,YAAY,QAAQ,cAAc;EAC9D,cAAc,eAAe,aAAa,QAAQ,MAAM;CACzD;AASM,IAAM,sBAAsBA,GAAE,OAAO,cAAc,EAAE,QAAO;AAG5D,IAAM,qBAAqBA,GAAE,OAAO;EACzC,MAAMA,GAAE,KAAK,CAAC,WAAW,QAAQ,WAAW,KAAK,CAAC;EAClD,IAAIA,GAAE,OAAM;EACZ,UAAUA,GAAE,OAAM,EAAG,SAAQ;EAC7B,OAAOA,GAAE,OAAM,EAAG,SAAQ;EAC1B,OAAOA,GAAE,OAAM;EACf,SAASA,GAAE,OAAM;EACjB,WAAWA,GAAE,OAAM;CACpB;",
6
+ "names": ["z", "z", "z", "z"]
7
+ }
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import { createRequire as __antbotCreateRequire } from 'node:module';
3
3
  const require = __antbotCreateRequire(import.meta.url);
4
4
  import {
5
5
  SettingsSchema
6
- } from "./chunk-BKF7CUVN.js";
6
+ } from "./chunk-G4IIENWF.js";
7
7
 
8
8
  // cli/src/index.ts
9
9
  import fs10 from "node:fs";
@@ -1261,6 +1261,7 @@ function describeVerdict(name, check) {
1261
1261
  case "ready":
1262
1262
  return green(`\u2713 ${name}: ready, ${n} tool${n === 1 ? "" : "s"}`);
1263
1263
  case "needs-sign-in":
1264
+ if (check.alternative) return red(`\u2717 ${name}: ${check.detail ?? `use the built-in instead: antbot mcp add ${check.alternative}`}`);
1264
1265
  return yellow(`! ${name}: needs sign-in${check.provider ? ` (${check.provider})` : ""}${n ? `, ${n} tools` : ""}`);
1265
1266
  case "needs-credential":
1266
1267
  return yellow(`! ${name}: ${check.detail ?? "needs a credential"}`);
@@ -1449,7 +1450,7 @@ async function runMcpCommand(argv, port) {
1449
1450
  return 1;
1450
1451
  }
1451
1452
  console.log(describeVerdict(name, created.check));
1452
- if (created.check.status === "needs-sign-in") {
1453
+ if (created.check.status === "needs-sign-in" && !created.check.alternative) {
1453
1454
  let creds = {};
1454
1455
  if (!created.check.selfRegistration) {
1455
1456
  const c = await collectClientCredentials(entry, created.check.provider);
@@ -1480,7 +1481,7 @@ async function runMcpCommand(argv, port) {
1480
1481
  const check = await postJson(port, `/api/connectors/${row.id}/check`, {});
1481
1482
  console.log(describeVerdict(name, check));
1482
1483
  for (const t of check.tools) console.log(` ${bold(`mcp__${name}__${t.name}`)}${t.description ? dim(` ${t.description.slice(0, 90)}`) : ""}`);
1483
- if (check.status === "needs-sign-in") console.log(dim(` Sign in with: antbot mcp login ${name}`));
1484
+ if (check.status === "needs-sign-in" && !check.alternative) console.log(dim(` Sign in with: antbot mcp login ${name}`));
1484
1485
  return check.status === "ready" ? 0 : 1;
1485
1486
  }
1486
1487
  case "login": {