@nekro-nxt/contracts 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/host-api.ts CHANGED
@@ -1,10 +1,21 @@
1
+ import { CommandCatalogEntrySchema, CommandExecutionRecordSchema, CommandPolicySchema } from './commands.js'
1
2
  import { z } from 'zod'
3
+ import {
4
+ hostLogDebugLeaseSchema,
5
+ hostLogDebugRequestSchema,
6
+ hostLogEntrySchema,
7
+ hostLogPageSchema,
8
+ hostLogSettingsSchema,
9
+ hostLogSourceSchema,
10
+ hostLogStatusSchema,
11
+ } from './logs.js'
2
12
  import { McpServerFormSchema } from './extension-capabilities.js'
3
13
  import { HostUpgradeSummarySchema, RuntimeCompatibilityDiagnosticSchema } from './runtime-compatibility.js'
4
14
  import {
5
15
  AgentIdSchema,
6
16
  AgentRevisionIdSchema,
7
17
  AuthoringAttemptIdSchema,
18
+ SubConversationIdSchema,
8
19
  AuthoringTaskIdSchema,
9
20
  AssetIdSchema,
10
21
  ChannelEventIdSchema,
@@ -38,9 +49,8 @@ import {
38
49
  CommunityReleaseIdSchema,
39
50
  CommunityReviewStatusSchema,
40
51
  CommunityStatusSchema,
41
- CommunitySourceSchema,
42
52
  CommunityEndpointSchema,
43
- CommunityInstalledSchema,
53
+ CommunitySyncSchema,
44
54
  CommunityMyExtensionSchema,
45
55
  CommunityReviewReportSchema,
46
56
  } from './community.js'
@@ -101,6 +111,9 @@ const DynamicAttemptErrorSchema = z
101
111
  phase: z.enum(['approval', 'host-load', 'host-apply', 'client-load', 'client-apply', 'client-render']),
102
112
  message: z.string(),
103
113
  stack: z.string().optional(),
114
+ /** A render failure also names the contribution slot that failed and whether its frame gave up. */
115
+ slot: NonEmptyStringSchema.optional(),
116
+ abdicated: z.boolean().optional(),
104
117
  pluginId: DynamicIdSchema,
105
118
  packageId: DynamicIdSchema,
106
119
  pluginRunId: DynamicIdSchema,
@@ -131,6 +144,7 @@ const AuthoringTaskStatusSchema = z.enum([
131
144
  'interrupted',
132
145
  'stopped',
133
146
  'completed',
147
+ 'paused',
134
148
  ])
135
149
 
136
150
  const AuthoringAttemptStateSchema = z.enum([
@@ -175,6 +189,8 @@ const AuthoringAttemptSummarySchema = z
175
189
  })
176
190
  .strict()
177
191
  .optional(),
192
+ /** Verified without loading its interface, because no browser was available; the interface itself is unchecked. */
193
+ uiUnverified: z.boolean().optional(),
178
194
  createdAt: z.number().int().nonnegative(),
179
195
  settledAt: z.number().int().nonnegative().optional(),
180
196
  })
@@ -189,6 +205,15 @@ const AuthoringTaskSummarySchema = z
189
205
  title: z.string(),
190
206
  requirementSummary: z.string(),
191
207
  status: AuthoringTaskStatusSchema,
208
+ /** `create` builds a new extension; `revise` changes `targetExtensionId` starting from `baseRevisionId`. */
209
+ kind: z.enum(['create', 'revise']).default('create'),
210
+ targetExtensionId: ExtensionIdSchema.optional(),
211
+ baseRevisionId: ExtensionRevisionIdSchema.optional(),
212
+ referenceRevisionId: ExtensionRevisionIdSchema.optional(),
213
+ /** Why the task is paused; it continues when the agent picks it up in a later conversation. */
214
+ pausedReason: z.string().optional(),
215
+ /** The conversation the task runs in is live, so its candidate can be previewed directly. */
216
+ live: z.boolean().default(false),
192
217
  approvalPolicy: z.enum(['risk-stable', 'fully-automatic']),
193
218
  approvedRiskDigest: z
194
219
  .string()
@@ -282,6 +307,20 @@ export const ImageUnderstandingPolicyApiSchema = z
282
307
  })
283
308
  .strict()
284
309
 
310
+ export const CommandAccountServiceSchema = z.enum(['github'])
311
+ export type CommandAccountService = z.output<typeof CommandAccountServiceSchema>
312
+
313
+ export const CommandAccountUsageSchema = z.enum(['read', 'issues', 'pull-requests', 'push'])
314
+
315
+ const CommandAccountGrantSchema = z
316
+ .object({
317
+ service: CommandAccountServiceSchema,
318
+ accountId: NonEmptyStringSchema.max(64),
319
+ /** Told to the agent as guidance, not enforced; empty gives no hint. */
320
+ usage: z.array(CommandAccountUsageSchema).max(4).default([]),
321
+ })
322
+ .strict()
323
+
285
324
  const AgentCapabilitiesSchema = z
286
325
  .object({
287
326
  subagents: z.boolean(),
@@ -296,12 +335,22 @@ const AgentCapabilitiesSchema = z
296
335
  codeRun: z.boolean().default(false),
297
336
  /** Network for commands; absent in older clients means on. */
298
337
  commandNetwork: z.boolean().default(true),
338
+ communityFeedbackAuto: z.boolean().default(false),
339
+ /** Accounts this agent's commands may act as; absent in older clients means none. */
340
+ commandAccounts: z.array(CommandAccountGrantSchema).max(8).default([]),
341
+ /**
342
+ * What the agent may do with extensions without the console: `manual` only develops and test-runs, `confirm` asks
343
+ * an administrator in the channel for every step, `autonomous` takes ordinary steps that only affect itself.
344
+ */
345
+ extensionAutonomy: z.enum(['manual', 'confirm', 'autonomous']).default('manual'),
346
+ /** Whose requests make the agent develop or change extensions: anyone in the channel, or administrators only. */
347
+ extensionRequesters: z.enum(['everyone', 'admins']).default('everyone'),
299
348
  })
300
349
  .strict()
301
350
 
302
351
  export const DynamicClientApprovalPolicySchema = z.enum(['manual', 'automatic'])
303
352
 
304
- export const NotificationEventKeySchema = z.enum(['dynamic-client-approval-requested'])
353
+ export const NotificationEventKeySchema = z.enum(['dynamic-client-approval-requested', 'community-feedback-update'])
305
354
  export type NotificationEventKey = z.output<typeof NotificationEventKeySchema>
306
355
 
307
356
  export const NotificationSettingsViewSchema = z
@@ -315,7 +364,12 @@ export const NotificationSettingsViewSchema = z
315
364
  deviceKeyConfigured: z.boolean(),
316
365
  })
317
366
  .strict(),
318
- events: z.record(NotificationEventKeySchema, z.boolean()),
367
+ events: z
368
+ .object({
369
+ 'dynamic-client-approval-requested': z.boolean(),
370
+ 'community-feedback-update': z.boolean().default(true),
371
+ })
372
+ .strict(),
319
373
  })
320
374
  .strict()
321
375
 
@@ -331,7 +385,9 @@ export const UpdateNotificationSettingsRequestSchema = z
331
385
  clearDeviceKey: z.boolean().optional(),
332
386
  })
333
387
  .strict(),
334
- events: z.record(NotificationEventKeySchema, z.boolean()),
388
+ events: z
389
+ .object({ 'dynamic-client-approval-requested': z.boolean(), 'community-feedback-update': z.boolean().optional() })
390
+ .strict(),
335
391
  })
336
392
  .strict()
337
393
  .refine((value) => !(value.bark.deviceKey !== undefined && value.bark.clearDeviceKey === true), {
@@ -390,13 +446,17 @@ const ReviseAgentRequestSchema = AgentRevisionRequestContentSchema.extend({
390
446
  validatePersonaDocumentProjection(value, context)
391
447
  })
392
448
 
393
- // The defaults that fill `scheduledTasks`, `codeRun` and `commandNetwork` for older clients must not reset them in a
394
- // partial update.
449
+ // Defaults that fill capabilities for older clients must not
450
+ // reset them in a partial update.
395
451
  const UpdateAgentCapabilitiesRequestSchema = AgentCapabilitiesSchema.partial()
396
452
  .extend({
397
453
  scheduledTasks: z.boolean().optional(),
398
454
  codeRun: z.boolean().optional(),
399
455
  commandNetwork: z.boolean().optional(),
456
+ communityFeedbackAuto: z.boolean().optional(),
457
+ commandAccounts: z.array(CommandAccountGrantSchema).max(8).optional(),
458
+ extensionAutonomy: z.enum(['manual', 'confirm', 'autonomous']).optional(),
459
+ extensionRequesters: z.enum(['everyone', 'admins']).optional(),
400
460
  })
401
461
  .strict()
402
462
  .refine((value) => Object.values(value).some((entry) => entry !== undefined), '至少提供一个能力。')
@@ -418,7 +478,14 @@ const SnapshotMessagePartSchema = z.discriminatedUnion('type', [
418
478
  z
419
479
  .object({ type: z.literal('mention'), memberId: ChannelMemberIdSchema, displayName: z.string().optional() })
420
480
  .strict(),
421
- z.object({ type: z.literal('image'), assetId: AssetIdSchema, alt: z.string().optional() }).strict(),
481
+ z
482
+ .object({
483
+ type: z.literal('image'),
484
+ assetId: AssetIdSchema,
485
+ alt: z.string().optional(),
486
+ sticker: z.literal(true).optional(),
487
+ })
488
+ .strict(),
422
489
  z.object({ type: z.literal('file'), assetId: AssetIdSchema, name: z.string().optional() }).strict(),
423
490
  z.object({ type: z.literal('audio'), assetId: AssetIdSchema }).strict(),
424
491
  z.object({ type: z.literal('quote'), messageId: LogicalMessageIdSchema }).strict(),
@@ -465,7 +532,10 @@ export const HostSnapshotMessageSchema = z
465
532
  })
466
533
  .strict()
467
534
  .optional(),
468
- origin: z.enum(['admin-console']).optional(),
535
+ origin: z.enum(['admin-console', 'command', 'extension-notice']).optional(),
536
+ command: CommandExecutionRecordSchema.optional(),
537
+ /** A host notice about extension work: a request an administrator must confirm, or what an action did. */
538
+ extensionNotice: z.object({ requestNumber: z.number().int().positive().optional() }).strict().optional(),
469
539
  /** What the agent's inbound hooks decided for this message, when anything differs from the default. */
470
540
  inboundHook: z
471
541
  .object({
@@ -535,6 +605,8 @@ export const PlatformUserListResponseSchema = z
535
605
  activeChannelCount: z.number().int().nonnegative(),
536
606
  channelPreview: z.array(PlatformUserChannelPreviewSchema).max(3),
537
607
  historicalOnly: z.boolean(),
608
+ /** Listed in Settings → Administrators. */
609
+ administrator: z.boolean().default(false),
538
610
  })
539
611
  .strict(),
540
612
  ),
@@ -945,6 +1017,40 @@ export const DEFAULT_MESSAGE_PACING: MessagePacing = 'normal'
945
1017
 
946
1018
  export const MessagePacingSettingsSchema = z.object({ pacing: MessagePacingSchema }).strict()
947
1019
 
1020
+ /**
1021
+ * A conversation of its own under a channel's conversation (docs/NekroNxt界面交互模型.md §5.6): the agent opens one
1022
+ * for a separate piece of work, and the host opens scripted ones to check creation candidates. It has its own log
1023
+ * and context, and is shown under its channel.
1024
+ */
1025
+ export const SubConversationSchema = z
1026
+ .object({
1027
+ id: SubConversationIdSchema,
1028
+ channelId: ChannelIdSchema,
1029
+ episodeId: EpisodeIdSchema,
1030
+ agentId: AgentIdSchema,
1031
+ title: z.string().min(1).max(200),
1032
+ /** `agent`: the agent opened it with a tool; `host`: NekroNXT opened it, such as to check a candidate. */
1033
+ openedBy: z.enum(['agent', 'host']),
1034
+ /** `model`: the agent's model talks in it; `script`: the host plays fixed tool calls. */
1035
+ driver: z.enum(['model', 'script']),
1036
+ status: z.enum(['open', 'closed']),
1037
+ closeReason: z.enum(['completed', 'closed-by-agent', 'closed-by-admin', 'failed', 'conversation-ended']).optional(),
1038
+ /** What it handed back to the channel's conversation when it ended. */
1039
+ summary: z.string().max(4000).optional(),
1040
+ authoringTaskId: AuthoringTaskIdSchema.optional(),
1041
+ createdAt: z.number().int().nonnegative(),
1042
+ closedAt: z.number().int().nonnegative().optional(),
1043
+ })
1044
+ .strict()
1045
+
1046
+ export type SubConversation = z.output<typeof SubConversationSchema>
1047
+
1048
+ /** How long ended sub-conversations are kept before they are cleaned up. */
1049
+ export const SubConversationRetentionSchema = z.enum(['1d', '3d', '7d', '30d', 'never'])
1050
+ export type SubConversationRetention = z.output<typeof SubConversationRetentionSchema>
1051
+ export const DEFAULT_SUB_CONVERSATION_RETENTION: SubConversationRetention = '7d'
1052
+ export const SubConversationSettingsSchema = z.object({ retention: SubConversationRetentionSchema }).strict()
1053
+
948
1054
  /** `keyword`: SQLite keyword search only; `builtin`: keywords fused with the built-in semantic model. */
949
1055
  export const RetrievalModeSchema = z.enum(['keyword', 'builtin'])
950
1056
  export type RetrievalMode = z.output<typeof RetrievalModeSchema>
@@ -985,6 +1091,23 @@ export const RetrievalStatusSchema = z
985
1091
  .strict()
986
1092
  export type RetrievalStatus = z.output<typeof RetrievalStatusSchema>
987
1093
 
1094
+ /** Where the Host keeps restore points it takes before an upgrade, or none. */
1095
+ export const UpgradeBackupModeSchema = z.enum(['data', 'directory', 'off'])
1096
+ export const UpgradeBackupSettingsSchema = z
1097
+ .object({
1098
+ mode: UpgradeBackupModeSchema,
1099
+ /** The chosen directory when `mode` is `directory`. */
1100
+ directory: z.string().nullable(),
1101
+ /** Set through the server's environment; the settings page cannot change it. */
1102
+ locked: z.boolean(),
1103
+ /** Restore points kept; older ones are removed after an upgrade succeeds. */
1104
+ keep: z.number().int().positive(),
1105
+ /** Restore points currently in the chosen place. */
1106
+ usage: z.object({ count: z.number().int().nonnegative(), bytes: z.number().int().nonnegative() }).strict(),
1107
+ })
1108
+ .strict()
1109
+ export type UpgradeBackupSettings = z.output<typeof UpgradeBackupSettingsSchema>
1110
+
988
1111
  /** What the agent keeps about individual members of one channel; each note comes with that member's messages. */
989
1112
  export const ChannelMemberNotesViewSchema = z
990
1113
  .object({
@@ -1145,11 +1268,13 @@ export const AttentionItemSchema = z
1145
1268
  'connection-unhealthy',
1146
1269
  'agent-model-unavailable',
1147
1270
  'agent-vision-unavailable',
1271
+ 'logs-unavailable',
1272
+ 'community-feedback',
1148
1273
  ]),
1149
1274
  severity: z.enum(['critical', 'warning', 'info']),
1150
1275
  subject: z
1151
1276
  .object({
1152
- kind: z.enum(['outbound', 'channel', 'authoring-task', 'connection', 'agent']),
1277
+ kind: z.enum(['outbound', 'channel', 'authoring-task', 'connection', 'agent', 'logs', 'community-feedback']),
1153
1278
  id: NonEmptyStringSchema,
1154
1279
  })
1155
1280
  .strict(),
@@ -1166,7 +1291,15 @@ export const AttentionItemSchema = z
1166
1291
  detail: z.string().max(400),
1167
1292
  action: z
1168
1293
  .object({
1169
- kind: z.enum(['open-channel', 'resolve-delivery', 'open-authoring-task', 'open-connection', 'open-agent']),
1294
+ kind: z.enum([
1295
+ 'open-channel',
1296
+ 'resolve-delivery',
1297
+ 'open-authoring-task',
1298
+ 'open-connection',
1299
+ 'open-agent',
1300
+ 'open-logs',
1301
+ 'open-community-feedback',
1302
+ ]),
1170
1303
  label: z.string().min(1).max(40),
1171
1304
  })
1172
1305
  .strict(),
@@ -1311,8 +1444,85 @@ export const CodeRunAvailabilitySchema = z
1311
1444
 
1312
1445
  export type CodeRunAvailability = z.output<typeof CodeRunAvailabilitySchema>
1313
1446
 
1447
+ /** The GitHub CLI commands call: found on this machine, or downloaded by NekroNXT where it can. */
1448
+ export const GithubCliAvailabilitySchema = CodeRunAvailabilitySchema
1449
+ export type GithubCliAvailability = z.output<typeof GithubCliAvailabilitySchema>
1450
+
1451
+ /** The optional headless Chromium that loads and checks creation candidates when no page is open. */
1452
+ export const VerificationBrowserAvailabilitySchema = CodeRunAvailabilitySchema
1453
+ export type VerificationBrowserAvailability = z.output<typeof VerificationBrowserAvailabilitySchema>
1454
+
1455
+ /**
1456
+ * One account in the host's library. The library only keeps accounts; an account takes effect only for the agents
1457
+ * whose capabilities grant it, which `usedBy` lists.
1458
+ */
1459
+ export const CommandAccountSchema = z
1460
+ .object({
1461
+ id: NonEmptyStringSchema.max(64),
1462
+ service: CommandAccountServiceSchema,
1463
+ /** The account name on the service. */
1464
+ login: NonEmptyStringSchema,
1465
+ source: z.enum(['token', 'gh-login']),
1466
+ /** Token scopes where the service reports them (classic tokens); absent for fine-grained tokens. */
1467
+ scopes: z.array(z.string()).optional(),
1468
+ createdAt: z.number().int().nonnegative(),
1469
+ usedBy: z.array(AgentIdSchema),
1470
+ })
1471
+ .strict()
1472
+
1473
+ export type CommandAccount = z.output<typeof CommandAccountSchema>
1474
+
1475
+ /** A login the local `gh` holds, offered as a quick way to add an account. */
1476
+ export const LocalGithubLoginSchema = z.object({ login: NonEmptyStringSchema, active: z.boolean() }).strict()
1477
+
1478
+ export const CommandAccountsViewSchema = z
1479
+ .object({
1480
+ accounts: z.array(CommandAccountSchema),
1481
+ /** Logins found in the local GitHub CLI; empty when it is missing or not logged in. */
1482
+ localLogins: z.array(LocalGithubLoginSchema),
1483
+ })
1484
+ .strict()
1485
+
1486
+ export type CommandAccountsView = z.output<typeof CommandAccountsViewSchema>
1487
+
1488
+ export const AddCommandAccountRequestSchema = z.discriminatedUnion('source', [
1489
+ z
1490
+ .object({ source: z.literal('token'), service: CommandAccountServiceSchema, token: NonEmptyStringSchema.max(512) })
1491
+ .strict(),
1492
+ z
1493
+ .object({
1494
+ source: z.literal('gh-login'),
1495
+ service: CommandAccountServiceSchema,
1496
+ login: NonEmptyStringSchema.max(128),
1497
+ })
1498
+ .strict(),
1499
+ ])
1500
+
1501
+ export type AddCommandAccountRequest = z.output<typeof AddCommandAccountRequestSchema>
1502
+
1503
+ /** An extension action an agent asked an administrator to confirm, or one it took on its own. */
1504
+ export const ExtensionRequestSchema = z
1505
+ .object({
1506
+ number: z.number().int().positive(),
1507
+ kind: z.string(),
1508
+ agentId: AgentIdSchema,
1509
+ channelId: ChannelIdSchema.nullable(),
1510
+ extensionId: ExtensionIdSchema.nullable(),
1511
+ summary: z.string(),
1512
+ status: z.enum(['pending', 'approved', 'rejected', 'expired', 'completed', 'failed']),
1513
+ autonomous: z.boolean(),
1514
+ resultMessage: z.string().nullable(),
1515
+ decidedBy: z.string().nullable(),
1516
+ createdAt: z.number().int().nonnegative(),
1517
+ expiresAt: z.number().int().nonnegative(),
1518
+ decidedAt: z.number().int().nonnegative().nullable(),
1519
+ })
1520
+ .strict()
1521
+ export type ExtensionRequestView = z.output<typeof ExtensionRequestSchema>
1522
+
1314
1523
  export const HostSnapshotSchema = z
1315
1524
  .object({
1525
+ communityFeedback: CommunityFeedbackSnapshotSchema.optional(),
1316
1526
  upgrade: HostUpgradeSummarySchema.optional(),
1317
1527
  cursor: HostSyncCursorSchema,
1318
1528
  diagnosticsSampledAt: z.number().int().nonnegative(),
@@ -1345,10 +1555,15 @@ export const HostSnapshotSchema = z
1345
1555
  subagents: z.object({ available: z.boolean() }).strict(),
1346
1556
  /** Optional in older hosts, which never offer `run_code`. */
1347
1557
  codeRun: CodeRunAvailabilitySchema.optional(),
1558
+ /** Optional in older hosts, which never offer command accounts. */
1559
+ githubCli: GithubCliAvailabilitySchema.optional(),
1560
+ /** Optional in older hosts, which check candidates only in an open page. */
1561
+ verificationBrowser: VerificationBrowserAvailabilitySchema.optional(),
1348
1562
  /** What this host can confine for commands beyond file writes; optional in older hosts. */
1349
1563
  commandConfinement: z.object({ readScope: z.boolean(), networkControl: z.boolean() }).strict().optional(),
1350
1564
  webSearch: z
1351
1565
  .object({
1566
+ unavailableReason: z.string().optional(),
1352
1567
  provider: z.literal('deepseek-official'),
1353
1568
  available: z.boolean(),
1354
1569
  credentialConfigured: z.boolean(),
@@ -1362,6 +1577,8 @@ export const HostSnapshotSchema = z
1362
1577
  .strict(),
1363
1578
  connectionAdapters: z.array(AdapterConnectionDescriptorSchema),
1364
1579
  notificationSettings: NotificationSettingsViewSchema,
1580
+ /** Optional in older hosts, which have no account library. */
1581
+ commandAccounts: z.array(CommandAccountSchema).optional(),
1365
1582
  agents: z.array(
1366
1583
  z
1367
1584
  .object({
@@ -1427,6 +1644,8 @@ export const HostSnapshotSchema = z
1427
1644
  platformChannelId: NonEmptyStringSchema,
1428
1645
  kind: z.enum(['internal', 'group', 'direct']),
1429
1646
  displayName: z.string().optional(),
1647
+ localDisplayName: z.string().optional(),
1648
+ platformDisplayName: z.string().optional(),
1430
1649
  boundAgentId: AgentIdSchema.optional(),
1431
1650
  runtimePhase: ChannelRuntimePhaseSchema.default('idle'),
1432
1651
  activity: ChannelActivitySummarySchema.default({ unreadCount: 0, unreadCapped: false }),
@@ -1438,6 +1657,8 @@ export const HostSnapshotSchema = z
1438
1657
  channelId: ChannelIdSchema,
1439
1658
  agentId: AgentIdSchema,
1440
1659
  triggerPolicy: TriggerPolicySchema,
1660
+ /** Channel pause, independent of the response rule. */
1661
+ paused: z.boolean().default(false),
1441
1662
  processingFeedback: z.enum(['auto', 'off']).default('auto'),
1442
1663
  /** Absent means `observe`. */
1443
1664
  localAgentMessages: z.enum(['observe', 'trigger']).optional(),
@@ -1462,6 +1683,7 @@ export const HostSnapshotSchema = z
1462
1683
  adapterKey: NonEmptyStringSchema,
1463
1684
  alias: ConnectionAliasOutputSchema.optional(),
1464
1685
  activityTriggerDefaults: z.array(AdapterActivityKeySchema).default([]),
1686
+ configuredSecrets: z.array(z.string()).optional(),
1465
1687
  status: z
1466
1688
  .object({
1467
1689
  state: z.enum(['stopped', 'connecting', 'connected', 'reconnecting', 'failed']),
@@ -1526,11 +1748,50 @@ export const HostSnapshotSchema = z
1526
1748
  displayName: z.string(),
1527
1749
  description: z.string(),
1528
1750
  createdByAgentId: AgentIdSchema.optional(),
1751
+ /** The Revision of another extension this one was branched from. */
1752
+ branchOf: z
1753
+ .object({
1754
+ extensionId: ExtensionIdSchema,
1755
+ revisionId: ExtensionRevisionIdSchema,
1756
+ /** Present while the original is on this machine. */
1757
+ displayName: z.string().optional(),
1758
+ })
1759
+ .strict()
1760
+ .optional(),
1761
+ /** Shape version of the data stored on this machine. */
1762
+ dataVersion: z.number().int().positive().default(1),
1763
+ /** The unfinished revise task of this extension, if any. */
1764
+ openRevisionTaskId: AuthoringTaskIdSchema.optional(),
1765
+ /** Whether this machine publishes (`owner`) or follows the line on each community. */
1766
+ communityLinks: z
1767
+ .array(z.object({ communityUrl: z.string(), role: z.enum(['owner', 'subscriber']) }).strict())
1768
+ .default([]),
1529
1769
  revisions: z.array(
1530
1770
  z
1531
1771
  .object({
1532
1772
  id: ExtensionRevisionIdSchema,
1533
1773
  revisionNumber: z.number().int().positive(),
1774
+ /** Version number from the lineage, `v3` (or `v3·2` for a second Revision of the same generation). */
1775
+ versionLabel: z.string(),
1776
+ parentRevisionId: ExtensionRevisionIdSchema.optional(),
1777
+ origin: z.enum(['authored', 'file', 'community', 'branch']),
1778
+ authoringTaskId: AuthoringTaskIdSchema.optional(),
1779
+ dataVersion: z.number().int().positive(),
1780
+ /** Community releases this Revision is; installs and publishes from here both record one. */
1781
+ releases: z
1782
+ .array(
1783
+ z
1784
+ .object({
1785
+ communityUrl: z.string(),
1786
+ releaseId: CommunityReleaseIdSchema,
1787
+ number: z.number().int().positive().nullable(),
1788
+ publisherHandle: z.string(),
1789
+ via: z.enum(['install', 'publish']),
1790
+ recordedAt: z.number().int().nonnegative(),
1791
+ })
1792
+ .strict(),
1793
+ )
1794
+ .default([]),
1534
1795
  format: z.enum(['current', 'unavailable']).optional(),
1535
1796
  ui: ExtensionUiContributionsSchema.default(EMPTY_EXTENSION_UI_CONTRIBUTIONS),
1536
1797
  /** The host instance's configuration form (`config.host`). */
@@ -1543,8 +1804,6 @@ export const HostSnapshotSchema = z
1543
1804
  .regex(/^\/api\/extensions\/[^/]+\/revisions\/[^/]+\/icon\/[a-f0-9]{64}\.(?:svg|png|webp)$/u)
1544
1805
  .optional(),
1545
1806
  createdAt: z.number().int().safe().nonnegative(),
1546
- /** 从社区安装的版本的来源;本机保存与文件导入没有来源。 */
1547
- source: CommunitySourceSchema.optional(),
1548
1807
  provides: z.array(ExtensionProvideSchema),
1549
1808
  /** Whether this Revision can be enabled for agents (agent-layer contributions or capabilities). */
1550
1809
  agentLayer: z.boolean(),
@@ -1712,18 +1971,36 @@ export const HostSnapshotSchema = z
1712
1971
  .strict(),
1713
1972
  ),
1714
1973
  authoringTasks: z.array(AuthoringTaskSummarySchema).default([]),
1974
+ /** Open sub-conversations, and the most recently ended ones of each channel. */
1975
+ subConversations: z.array(SubConversationSchema).default([]),
1715
1976
  scheduledTasks: z.array(ScheduledTaskSchema).default([]),
1977
+ /** Extension requests waiting for an administrator. */
1978
+ extensionRequests: z.array(ExtensionRequestSchema).default([]),
1716
1979
  })
1717
1980
  .strict()
1718
1981
 
1982
+ export const CHANNEL_COMPOSER_MAX_ATTACHMENTS = 20
1983
+ export const CHANNEL_COMPOSER_MAX_BYTES = 64 * 1024 * 1024
1984
+
1719
1985
  const MessageInputPartSchema = z.discriminatedUnion('type', [
1720
1986
  z.object({ type: z.literal('text'), text: z.string().trim().min(1) }).strict(),
1721
1987
  z.object({ type: z.literal('mention'), memberId: ChannelMemberIdSchema }).strict(),
1988
+ z.object({ type: z.literal('image'), assetId: AssetIdSchema, alt: z.string().trim().max(500).optional() }).strict(),
1989
+ z.object({ type: z.literal('file'), assetId: AssetIdSchema, name: z.string().trim().max(255).optional() }).strict(),
1722
1990
  ])
1723
1991
 
1724
1992
  const SendChannelMessageRequestSchema = z
1725
1993
  .object({
1726
- parts: z.array(MessageInputPartSchema).min(1),
1994
+ parts: z
1995
+ .array(MessageInputPartSchema)
1996
+ .min(1)
1997
+ .max(256)
1998
+ .refine(
1999
+ (parts) =>
2000
+ parts.filter((part) => part.type === 'image' || part.type === 'file').length <=
2001
+ CHANNEL_COMPOSER_MAX_ATTACHMENTS,
2002
+ '每条消息最多添加 20 个附件。',
2003
+ ),
1727
2004
  clientEventId: NonEmptyStringSchema.optional(),
1728
2005
  senderMemberId: ChannelMemberIdSchema.optional(),
1729
2006
  })
@@ -2163,6 +2440,142 @@ const connectionParam = z.object({ connectionId: ConnectionIdSchema }).strict()
2163
2440
  const agentExtensionParam = z.object({ agentId: AgentIdSchema, extensionId: ExtensionIdSchema }).strict()
2164
2441
 
2165
2442
  const PermissionApprovalSchema = z.object({ permissionDigest: z.string().regex(/^[a-f0-9]{64}$/u) }).strict()
2443
+
2444
+ /** One version of one line in the lineage view of an extension family. */
2445
+ export const ExtensionLineageNodeSchema = z
2446
+ .object({
2447
+ revisionId: ExtensionRevisionIdSchema,
2448
+ extensionId: ExtensionIdSchema,
2449
+ label: z.string(),
2450
+ parentRevisionId: ExtensionRevisionIdSchema.optional(),
2451
+ origin: z.enum(['authored', 'file', 'community', 'branch']),
2452
+ createdAt: z.number().int().nonnegative(),
2453
+ current: z.boolean(),
2454
+ releaseNumbers: z.array(z.number().int().positive()),
2455
+ })
2456
+ .strict()
2457
+
2458
+ /** Every line of the family an extension belongs to: the original and every branch of a branch on this machine. */
2459
+ export const ExtensionLineageSchema = z
2460
+ .object({
2461
+ lines: z.array(
2462
+ z
2463
+ .object({
2464
+ extensionId: ExtensionIdSchema,
2465
+ displayName: z.string(),
2466
+ branchOf: z
2467
+ .object({ extensionId: ExtensionIdSchema, revisionId: ExtensionRevisionIdSchema })
2468
+ .strict()
2469
+ .optional(),
2470
+ nodes: z.array(ExtensionLineageNodeSchema),
2471
+ })
2472
+ .strict(),
2473
+ ),
2474
+ })
2475
+ .strict()
2476
+
2477
+ const DataChangeCountSchema = z
2478
+ .object({
2479
+ added: z.number().int().nonnegative(),
2480
+ overwritten: z.number().int().nonnegative(),
2481
+ removed: z.number().int().nonnegative(),
2482
+ unchanged: z.number().int().nonnegative(),
2483
+ })
2484
+ .strict()
2485
+
2486
+ /** Where a data migration takes data from. */
2487
+ export const ExtensionDataSourceSchema = z.discriminatedUnion('kind', [
2488
+ z.object({ kind: z.literal('extension'), extensionId: ExtensionIdSchema }).strict(),
2489
+ z.object({ kind: z.literal('snapshot'), snapshotId: z.string().min(1).max(80) }).strict(),
2490
+ z.object({ kind: z.literal('package'), token: z.string().min(1).max(80) }).strict(),
2491
+ ])
2492
+
2493
+ export const ExtensionDataMigrationInputSchema = z
2494
+ .object({
2495
+ source: ExtensionDataSourceSchema,
2496
+ mode: z.enum(['overwrite', 'replace']),
2497
+ /** Storage of a source agent goes to the mapped agent here; unmapped agents are skipped. */
2498
+ agentMap: z.record(z.string(), AgentIdSchema).optional(),
2499
+ /** Also move the host and agent configuration (never credentials) the same way. */
2500
+ includeConfig: z.boolean().optional(),
2501
+ })
2502
+ .strict()
2503
+
2504
+ export const ExtensionDataPreviewSchema = z
2505
+ .object({
2506
+ diff: z
2507
+ .object({ storage: DataChangeCountSchema, index: DataChangeCountSchema, library: DataChangeCountSchema })
2508
+ .strict(),
2509
+ destructive: z.boolean(),
2510
+ sourceDataVersion: z.number().int().positive(),
2511
+ targetDataVersion: z.number().int().positive(),
2512
+ needsMigration: z.boolean(),
2513
+ /** Configuration fields that would change, when configuration moves too. */
2514
+ config: z
2515
+ .object({
2516
+ hostFields: z.array(z.string()),
2517
+ agents: z.array(z.object({ agentId: AgentIdSchema, fields: z.array(z.string()) }).strict()),
2518
+ })
2519
+ .strict()
2520
+ .optional(),
2521
+ })
2522
+ .strict()
2523
+
2524
+ export const ExtensionDataStateSchema = z
2525
+ .object({
2526
+ dataVersion: z.number().int().positive(),
2527
+ counts: z
2528
+ .object({
2529
+ storage: z.number().int().nonnegative(),
2530
+ index: z.number().int().nonnegative(),
2531
+ library: z.number().int().nonnegative(),
2532
+ })
2533
+ .strict(),
2534
+ snapshots: z.array(
2535
+ z
2536
+ .object({
2537
+ id: z.string(),
2538
+ reason: z.enum(['switch', 'migration', 'manual']),
2539
+ label: z.string(),
2540
+ dataVersion: z.number().int().positive(),
2541
+ byteSize: z.number().int().nonnegative(),
2542
+ createdAt: z.number().int().nonnegative(),
2543
+ })
2544
+ .strict(),
2545
+ ),
2546
+ })
2547
+ .strict()
2548
+
2549
+ export const ExtensionDataPackageInspectionSchema = z
2550
+ .object({
2551
+ token: z.string(),
2552
+ extensionId: z.string(),
2553
+ displayName: z.string(),
2554
+ dataVersion: z.number().int().positive(),
2555
+ exportedAt: z.number().int().nonnegative(),
2556
+ agents: z.array(z.object({ id: z.string(), name: z.string() }).strict()),
2557
+ counts: z
2558
+ .object({
2559
+ storage: z.number().int().nonnegative(),
2560
+ index: z.number().int().nonnegative(),
2561
+ library: z.number().int().nonnegative(),
2562
+ })
2563
+ .strict(),
2564
+ })
2565
+ .strict()
2566
+
2567
+ export const AdministratorSchema = z
2568
+ .object({
2569
+ connectionId: ConnectionIdSchema,
2570
+ connectionName: z.string(),
2571
+ platformUserId: z.string(),
2572
+ identityId: PlatformIdentityIdSchema.optional(),
2573
+ displayName: z.string(),
2574
+ addedVia: z.enum(['console', 'claim']),
2575
+ addedAt: z.number().int().nonnegative(),
2576
+ })
2577
+ .strict()
2578
+
2166
2579
  const extensionParam = z.object({ extensionId: ExtensionIdSchema }).strict()
2167
2580
  const dshPluginPackageParam = z.object({ packageId: DshPluginPackageIdSchema }).strict()
2168
2581
  const dshPluginEntryParam = z.object({ entryId: DshPluginEntryIdSchema }).strict()
@@ -2173,6 +2586,7 @@ const dshSettingsParam = z.object({ namespace: NonEmptyStringSchema }).strict()
2173
2586
  const dshCredentialParam = z.object({ ref: DshCredentialRefSchema }).strict()
2174
2587
  const llmProviderParam = z.object({ provider: NonEmptyStringSchema }).strict()
2175
2588
  const authoringTaskParam = z.object({ taskId: AuthoringTaskIdSchema }).strict()
2589
+ const subConversationParam = z.object({ conversationId: SubConversationIdSchema }).strict()
2176
2590
  const scheduledTaskParam = z.object({ taskId: ScheduledTaskIdSchema }).strict()
2177
2591
  const authoringAttemptParam = z.object({ taskId: AuthoringTaskIdSchema, attemptId: AuthoringAttemptIdSchema }).strict()
2178
2592
 
@@ -2216,6 +2630,178 @@ const encodeBinaryUpload = (input: z.output<typeof BinaryUploadRequestSchema>) =
2216
2630
  })
2217
2631
 
2218
2632
  export const HostApiContracts = {
2633
+ listCommands: defineContract({
2634
+ method: 'GET',
2635
+ path: '/api/commands',
2636
+ params: z.object({ channelId: ChannelIdSchema.optional() }).strict(),
2637
+ request: NoRequestBodySchema,
2638
+ response: z
2639
+ .object({
2640
+ commands: z.array(CommandCatalogEntrySchema),
2641
+ problems: z.array(z.string()),
2642
+ /** Host-wide behavior: whether platform members without a grant are told so. */
2643
+ settings: z.object({ unauthorizedFeedback: z.boolean() }).strict(),
2644
+ /** Present when a channel was requested. */
2645
+ channel: z
2646
+ .object({
2647
+ kind: z.enum(['internal', 'direct', 'group']),
2648
+ /** The channel is an external group where commands must address the account. */
2649
+ requiresMention: z.boolean(),
2650
+ bareCommands: z.boolean(),
2651
+ })
2652
+ .strict()
2653
+ .optional(),
2654
+ })
2655
+ .strict(),
2656
+ error: HostApiErrorSchema,
2657
+ }),
2658
+ executeCommand: defineContract({
2659
+ method: 'POST',
2660
+ path: '/api/commands/execute',
2661
+ params: EmptyParamsSchema,
2662
+ request: z
2663
+ .object({ channelId: ChannelIdSchema, text: z.string().min(1).max(16000), requestId: z.string().min(1).max(200) })
2664
+ .strict(),
2665
+ response: CommandExecutionRecordSchema,
2666
+ error: HostApiErrorSchema,
2667
+ invalidatesSnapshot: true,
2668
+ }),
2669
+ getCommandExecution: defineContract({
2670
+ method: 'GET',
2671
+ path: '/api/commands/executions/:executionId',
2672
+ params: z.object({ executionId: z.string().min(1) }).strict(),
2673
+ request: NoRequestBodySchema,
2674
+ response: CommandExecutionRecordSchema,
2675
+ error: HostApiErrorSchema,
2676
+ }),
2677
+ setCommandPolicy: defineContract({
2678
+ method: 'PUT',
2679
+ path: '/api/commands/policy',
2680
+ params: EmptyParamsSchema,
2681
+ request: z
2682
+ .object({
2683
+ scope: z.union([z.literal('global'), ChannelIdSchema]),
2684
+ name: z.string().min(1),
2685
+ policy: CommandPolicySchema,
2686
+ })
2687
+ .strict(),
2688
+ response: z.object({ saved: z.literal(true) }).strict(),
2689
+ error: HostApiErrorSchema,
2690
+ invalidatesSnapshot: true,
2691
+ }),
2692
+ listCommandMembers: defineContract({
2693
+ method: 'GET',
2694
+ path: '/api/commands/members/:channelId',
2695
+ params: z.object({ channelId: ChannelIdSchema }).strict(),
2696
+ request: NoRequestBodySchema,
2697
+ response: z
2698
+ .object({
2699
+ members: z.array(
2700
+ z
2701
+ .object({
2702
+ identityId: PlatformIdentityIdSchema,
2703
+ displayName: z.string(),
2704
+ platformUserId: z.string(),
2705
+ authorized: z.boolean(),
2706
+ })
2707
+ .strict(),
2708
+ ),
2709
+ })
2710
+ .strict(),
2711
+ error: HostApiErrorSchema,
2712
+ }),
2713
+ setCommandSettings: defineContract({
2714
+ method: 'PUT',
2715
+ path: '/api/commands/settings',
2716
+ params: EmptyParamsSchema,
2717
+ request: z.object({ unauthorizedFeedback: z.boolean() }).strict(),
2718
+ response: z.object({ saved: z.literal(true) }).strict(),
2719
+ error: HostApiErrorSchema,
2720
+ }),
2721
+ setCommandChannelSettings: defineContract({
2722
+ method: 'PUT',
2723
+ path: '/api/commands/channel-settings',
2724
+ params: EmptyParamsSchema,
2725
+ request: z.object({ channelId: ChannelIdSchema, bareCommands: z.boolean() }).strict(),
2726
+ response: z.object({ saved: z.literal(true) }).strict(),
2727
+ error: HostApiErrorSchema,
2728
+ invalidatesSnapshot: true,
2729
+ }),
2730
+ setCommandGrant: defineContract({
2731
+ method: 'PUT',
2732
+ path: '/api/commands/grants',
2733
+ params: EmptyParamsSchema,
2734
+ request: z
2735
+ .object({ channelId: ChannelIdSchema, identityId: PlatformIdentityIdSchema, enabled: z.boolean() })
2736
+ .strict(),
2737
+ response: z.object({ saved: z.literal(true) }).strict(),
2738
+ error: HostApiErrorSchema,
2739
+ invalidatesSnapshot: true,
2740
+ }),
2741
+ queryLogs: defineContract({
2742
+ method: 'GET',
2743
+ path: '/api/logs',
2744
+ params: z.object({ query: z.string().max(32_768).optional() }).strict(),
2745
+ request: NoRequestBodySchema,
2746
+ response: hostLogPageSchema,
2747
+ error: HostApiErrorSchema,
2748
+ }),
2749
+ getLog: defineContract({
2750
+ method: 'GET',
2751
+ path: '/api/logs/:id',
2752
+ params: z.object({ id: z.string().min(1).max(256) }).strict(),
2753
+ request: NoRequestBodySchema,
2754
+ response: z.object({ entry: hostLogEntrySchema }).strict(),
2755
+ error: HostApiErrorSchema,
2756
+ }),
2757
+ logSources: defineContract({
2758
+ method: 'GET',
2759
+ path: '/api/logs/sources',
2760
+ params: EmptyParamsSchema,
2761
+ request: NoRequestBodySchema,
2762
+ response: z.object({ sources: z.array(hostLogSourceSchema) }).strict(),
2763
+ error: HostApiErrorSchema,
2764
+ }),
2765
+ logStatus: defineContract({
2766
+ method: 'GET',
2767
+ path: '/api/logs/status',
2768
+ params: EmptyParamsSchema,
2769
+ request: NoRequestBodySchema,
2770
+ response: hostLogStatusSchema,
2771
+ error: HostApiErrorSchema,
2772
+ }),
2773
+ logSettings: defineContract({
2774
+ method: 'GET',
2775
+ path: '/api/logs/settings',
2776
+ params: EmptyParamsSchema,
2777
+ request: NoRequestBodySchema,
2778
+ response: hostLogSettingsSchema,
2779
+ error: HostApiErrorSchema,
2780
+ }),
2781
+ updateLogSettings: defineContract({
2782
+ method: 'PUT',
2783
+ path: '/api/logs/settings',
2784
+ params: EmptyParamsSchema,
2785
+ request: hostLogSettingsSchema,
2786
+ response: hostLogSettingsSchema,
2787
+ error: HostApiErrorSchema,
2788
+ }),
2789
+ startLogDebug: defineContract({
2790
+ method: 'POST',
2791
+ path: '/api/logs/debug',
2792
+ params: EmptyParamsSchema,
2793
+ request: hostLogDebugRequestSchema,
2794
+ response: z.object({ lease: hostLogDebugLeaseSchema }).strict(),
2795
+ error: HostApiErrorSchema,
2796
+ }),
2797
+ stopLogDebug: defineContract({
2798
+ method: 'DELETE',
2799
+ path: '/api/logs/debug/:id',
2800
+ params: z.object({ id: z.string().min(1).max(256) }).strict(),
2801
+ request: NoRequestBodySchema,
2802
+ response: z.object({ stopped: z.literal(true) }).strict(),
2803
+ error: HostApiErrorSchema,
2804
+ }),
2219
2805
  retryRuntimeCompatibility: defineContract({
2220
2806
  method: 'POST',
2221
2807
  path: '/api/runtime/compatibility/retry',
@@ -2508,6 +3094,7 @@ export const HostApiContracts = {
2508
3094
  channelId: ChannelIdSchema,
2509
3095
  agentId: AgentIdSchema,
2510
3096
  triggerPolicy: TriggerPolicySchema,
3097
+ paused: z.boolean().default(false),
2511
3098
  processingFeedback: z.enum(['auto', 'off']).default('auto'),
2512
3099
  localAgentMessages: z.enum(['observe', 'trigger']).optional(),
2513
3100
  activityTriggerOverrides: ActivityTriggerOverridesSchema.default({}),
@@ -2569,16 +3156,48 @@ export const HostApiContracts = {
2569
3156
  .strict(),
2570
3157
  error: HostApiErrorSchema,
2571
3158
  }),
2572
- renameChannel: defineContract({
2573
- invalidatesSnapshot: true,
3159
+ uploadChannelAsset: defineContract({
2574
3160
  method: 'POST',
2575
- path: '/api/channels/:channelId/display-name',
3161
+ path: '/api/channels/:channelId/assets',
2576
3162
  params: channelParam,
2577
- request: z.object({ displayName: z.string().trim().min(1).max(120) }).strict(),
2578
- response: z.object({ channelId: ChannelIdSchema, displayName: z.string().trim().min(1).max(120) }).strict(),
3163
+ request: BinaryUploadRequestSchema,
3164
+ encodeRequest: (input) => ({
3165
+ body: input.bytes,
3166
+ headers: {
3167
+ 'content-type': 'application/octet-stream',
3168
+ 'x-file-name': encodeURIComponent(input.fileName ?? '附件'),
3169
+ },
3170
+ }),
3171
+ response: z
3172
+ .object({
3173
+ assetId: AssetIdSchema,
3174
+ mediaType: z.string().min(1),
3175
+ byteSize: z.number().int().nonnegative(),
3176
+ fileName: z.string().min(1).max(255),
3177
+ partType: z.enum(['image', 'file']),
3178
+ })
3179
+ .strict(),
2579
3180
  error: HostApiErrorSchema,
2580
3181
  }),
2581
- getChannelRuntime: defineContract({
3182
+ deleteChannelAsset: defineContract({
3183
+ method: 'DELETE',
3184
+ path: '/api/channels/:channelId/assets/:assetId',
3185
+ params: z.object({ channelId: ChannelIdSchema, assetId: AssetIdSchema }).strict(),
3186
+ request: NoRequestBodySchema,
3187
+ response: z.object({ assetId: AssetIdSchema, revoked: z.literal(true) }).strict(),
3188
+ error: HostApiErrorSchema,
3189
+ }),
3190
+ renameChannel: defineContract({
3191
+ invalidatesSnapshot: true,
3192
+ method: 'POST',
3193
+ path: '/api/channels/:channelId/display-name',
3194
+ params: channelParam,
3195
+ /** Empty selects the known platform name for an external channel. */
3196
+ request: z.object({ displayName: z.string().trim().max(120) }).strict(),
3197
+ response: z.object({ channelId: ChannelIdSchema, displayName: z.string().trim().min(1).max(120) }).strict(),
3198
+ error: HostApiErrorSchema,
3199
+ }),
3200
+ getChannelRuntime: defineContract({
2582
3201
  method: 'GET',
2583
3202
  path: '/api/channels/:channelId/runtime',
2584
3203
  params: channelParam,
@@ -2616,6 +3235,57 @@ export const HostApiContracts = {
2616
3235
  response: ChannelRuntimeContextSchema,
2617
3236
  error: HostApiErrorSchema,
2618
3237
  }),
3238
+ listSubConversations: defineContract({
3239
+ method: 'GET',
3240
+ path: '/api/sub-conversations/channels/:channelId',
3241
+ params: channelParam,
3242
+ request: NoRequestBodySchema,
3243
+ response: z.object({ items: z.array(SubConversationSchema) }).strict(),
3244
+ error: HostApiErrorSchema,
3245
+ }),
3246
+ getSubConversationRuntime: defineContract({
3247
+ method: 'GET',
3248
+ path: '/api/sub-conversations/:conversationId/runtime',
3249
+ params: subConversationParam,
3250
+ request: NoRequestBodySchema,
3251
+ // Read from memory while it runs and from its stored log after it ended.
3252
+ response: z.object({ conversation: SubConversationSchema, runtime: ChannelRuntimeProjectionSchema }).strict(),
3253
+ error: HostApiErrorSchema,
3254
+ }),
3255
+ closeSubConversation: defineContract({
3256
+ invalidatesSnapshot: true,
3257
+ method: 'POST',
3258
+ path: '/api/sub-conversations/:conversationId/close',
3259
+ params: subConversationParam,
3260
+ request: z.object({}).strict(),
3261
+ response: SubConversationSchema,
3262
+ error: HostApiErrorSchema,
3263
+ }),
3264
+ deleteSubConversation: defineContract({
3265
+ invalidatesSnapshot: true,
3266
+ method: 'DELETE',
3267
+ path: '/api/sub-conversations/:conversationId',
3268
+ params: subConversationParam,
3269
+ request: NoRequestBodySchema,
3270
+ response: z.object({ deleted: z.literal(true) }).strict(),
3271
+ error: HostApiErrorSchema,
3272
+ }),
3273
+ getSubConversationSettings: defineContract({
3274
+ method: 'GET',
3275
+ path: '/api/settings/sub-conversations',
3276
+ params: EmptyParamsSchema,
3277
+ request: NoRequestBodySchema,
3278
+ response: SubConversationSettingsSchema,
3279
+ error: HostApiErrorSchema,
3280
+ }),
3281
+ updateSubConversationSettings: defineContract({
3282
+ method: 'PUT',
3283
+ path: '/api/settings/sub-conversations',
3284
+ params: EmptyParamsSchema,
3285
+ request: SubConversationSettingsSchema,
3286
+ response: SubConversationSettingsSchema,
3287
+ error: HostApiErrorSchema,
3288
+ }),
2619
3289
  getChannelRuntimeInput: defineContract({
2620
3290
  method: 'GET',
2621
3291
  path: '/api/channels/:channelId/runtime/inputs/:messageId',
@@ -2699,6 +3369,24 @@ export const HostApiContracts = {
2699
3369
  response: MessagePacingSettingsSchema,
2700
3370
  error: HostApiErrorSchema,
2701
3371
  }),
3372
+ getUpgradeBackupSettings: defineContract({
3373
+ method: 'GET',
3374
+ path: '/api/settings/upgrade-backup',
3375
+ params: EmptyParamsSchema,
3376
+ request: NoRequestBodySchema,
3377
+ response: UpgradeBackupSettingsSchema,
3378
+ error: HostApiErrorSchema,
3379
+ }),
3380
+ updateUpgradeBackupSettings: defineContract({
3381
+ method: 'PUT',
3382
+ path: '/api/settings/upgrade-backup',
3383
+ params: EmptyParamsSchema,
3384
+ request: z
3385
+ .object({ mode: UpgradeBackupModeSchema, directory: z.string().trim().min(1).max(1024).optional() })
3386
+ .strict(),
3387
+ response: UpgradeBackupSettingsSchema,
3388
+ error: HostApiErrorSchema,
3389
+ }),
2702
3390
  getRetrievalStatus: defineContract({
2703
3391
  method: 'GET',
2704
3392
  path: '/api/settings/retrieval',
@@ -2749,6 +3437,77 @@ export const HostApiContracts = {
2749
3437
  response: CodeRunAvailabilitySchema,
2750
3438
  error: HostApiErrorSchema,
2751
3439
  }),
3440
+ downloadGithubCli: defineContract({
3441
+ invalidatesSnapshot: true,
3442
+ method: 'POST',
3443
+ path: '/api/runtimes/github-cli/download',
3444
+ params: EmptyParamsSchema,
3445
+ request: NoRequestBodySchema,
3446
+ response: GithubCliAvailabilitySchema,
3447
+ error: HostApiErrorSchema,
3448
+ }),
3449
+ removeGithubCli: defineContract({
3450
+ invalidatesSnapshot: true,
3451
+ method: 'DELETE',
3452
+ path: '/api/runtimes/github-cli',
3453
+ params: EmptyParamsSchema,
3454
+ request: NoRequestBodySchema,
3455
+ response: GithubCliAvailabilitySchema,
3456
+ error: HostApiErrorSchema,
3457
+ }),
3458
+ downloadVerificationBrowser: defineContract({
3459
+ invalidatesSnapshot: true,
3460
+ method: 'POST',
3461
+ path: '/api/runtimes/verification-browser/download',
3462
+ params: EmptyParamsSchema,
3463
+ request: NoRequestBodySchema,
3464
+ response: VerificationBrowserAvailabilitySchema,
3465
+ error: HostApiErrorSchema,
3466
+ }),
3467
+ removeVerificationBrowser: defineContract({
3468
+ invalidatesSnapshot: true,
3469
+ method: 'DELETE',
3470
+ path: '/api/runtimes/verification-browser',
3471
+ params: EmptyParamsSchema,
3472
+ request: NoRequestBodySchema,
3473
+ response: VerificationBrowserAvailabilitySchema,
3474
+ error: HostApiErrorSchema,
3475
+ }),
3476
+ getCommandAccounts: defineContract({
3477
+ method: 'GET',
3478
+ path: '/api/settings/command-accounts',
3479
+ params: EmptyParamsSchema,
3480
+ request: NoRequestBodySchema,
3481
+ response: CommandAccountsViewSchema,
3482
+ error: HostApiErrorSchema,
3483
+ }),
3484
+ addCommandAccount: defineContract({
3485
+ invalidatesSnapshot: true,
3486
+ method: 'POST',
3487
+ path: '/api/settings/command-accounts',
3488
+ params: EmptyParamsSchema,
3489
+ request: AddCommandAccountRequestSchema,
3490
+ response: CommandAccountsViewSchema,
3491
+ error: HostApiErrorSchema,
3492
+ }),
3493
+ replaceCommandAccountToken: defineContract({
3494
+ invalidatesSnapshot: true,
3495
+ method: 'PUT',
3496
+ path: '/api/settings/command-accounts/:accountId',
3497
+ params: z.object({ accountId: NonEmptyStringSchema.max(64) }).strict(),
3498
+ request: AddCommandAccountRequestSchema,
3499
+ response: CommandAccountsViewSchema,
3500
+ error: HostApiErrorSchema,
3501
+ }),
3502
+ removeCommandAccount: defineContract({
3503
+ invalidatesSnapshot: true,
3504
+ method: 'DELETE',
3505
+ path: '/api/settings/command-accounts/:accountId',
3506
+ params: z.object({ accountId: NonEmptyStringSchema.max(64) }).strict(),
3507
+ request: NoRequestBodySchema,
3508
+ response: CommandAccountsViewSchema,
3509
+ error: HostApiErrorSchema,
3510
+ }),
2752
3511
  getChannelMemberNotes: defineContract({
2753
3512
  method: 'GET',
2754
3513
  path: '/api/channels/:channelId/member-notes',
@@ -2899,7 +3658,13 @@ export const HostApiContracts = {
2899
3658
  method: 'POST',
2900
3659
  path: '/api/connections/:connectionId/configuration',
2901
3660
  params: connectionParam,
2902
- request: z.object({ configuration: z.record(z.string(), z.union([z.string(), z.number(), z.boolean()])) }).strict(),
3661
+ request: z
3662
+ .object({
3663
+ configuration: z.record(z.string(), z.union([z.string(), z.number(), z.boolean()])),
3664
+ /** Omitted keys keep their value; null explicitly clears an optional credential. */
3665
+ credentials: z.record(z.string().min(1), z.string().min(1).max(16_384).nullable()).optional(),
3666
+ })
3667
+ .strict(),
2903
3668
  response: z
2904
3669
  .object({
2905
3670
  connectionId: ConnectionIdSchema,
@@ -3072,6 +3837,139 @@ export const HostApiContracts = {
3072
3837
  response: CommunityStatusSchema,
3073
3838
  error: HostApiErrorSchema,
3074
3839
  }),
3840
+ getCommunityFeedbackSettings: defineContract({
3841
+ method: 'GET',
3842
+ path: '/api/community/feedback/settings',
3843
+ params: EmptyParamsSchema,
3844
+ request: NoRequestBodySchema,
3845
+ response: CommunityFeedbackSettingsSchema,
3846
+ error: HostApiErrorSchema,
3847
+ }),
3848
+ updateCommunityFeedbackSettings: defineContract({
3849
+ method: 'PUT',
3850
+ path: '/api/community/feedback/settings',
3851
+ params: EmptyParamsSchema,
3852
+ request: CommunityFeedbackSettingsUpdateSchema,
3853
+ response: CommunityFeedbackSettingsSchema,
3854
+ error: HostApiErrorSchema,
3855
+ invalidatesSnapshot: true,
3856
+ }),
3857
+ listCommunityFeedback: defineContract({
3858
+ timeoutMs: 60_000,
3859
+ method: 'GET',
3860
+ path: '/api/community/feedback',
3861
+ params: z.object({ refresh: z.literal('1').optional() }).strict(),
3862
+ request: NoRequestBodySchema,
3863
+ response: CommunityFeedbackLocalListSchema,
3864
+ error: HostApiErrorSchema,
3865
+ }),
3866
+ getCommunityFeedback: defineContract({
3867
+ timeoutMs: 60_000,
3868
+ method: 'GET',
3869
+ path: '/api/community/feedback/items/:ref',
3870
+ params: z.object({ ref: CommunityFeedbackRefSchema }).strict(),
3871
+ request: NoRequestBodySchema,
3872
+ response: CommunityFeedbackSchema,
3873
+ error: HostApiErrorSchema,
3874
+ }),
3875
+ createCommunityFeedbackDraft: defineContract({
3876
+ method: 'POST',
3877
+ path: '/api/community/feedback/drafts',
3878
+ params: EmptyParamsSchema,
3879
+ request: CommunityFeedbackDraftInputSchema,
3880
+ response: CommunityFeedbackDraftSchema,
3881
+ error: HostApiErrorSchema,
3882
+ invalidatesSnapshot: true,
3883
+ }),
3884
+ updateCommunityFeedbackDraft: defineContract({
3885
+ method: 'PUT',
3886
+ path: '/api/community/feedback/drafts/:draftId',
3887
+ params: z.object({ draftId: CommunityFeedbackDraftIdSchema }).strict(),
3888
+ request: CommunityFeedbackDraftUpdateSchema,
3889
+ response: CommunityFeedbackDraftSchema,
3890
+ error: HostApiErrorSchema,
3891
+ invalidatesSnapshot: true,
3892
+ }),
3893
+ sendCommunityFeedbackDraft: defineContract({
3894
+ timeoutMs: 60_000,
3895
+ method: 'POST',
3896
+ path: '/api/community/feedback/drafts/:draftId/send',
3897
+ params: z.object({ draftId: CommunityFeedbackDraftIdSchema }).strict(),
3898
+ request: z.object({ consent: z.boolean().default(false) }).strict(),
3899
+ response: CommunityFeedbackDraftSchema,
3900
+ error: HostApiErrorSchema,
3901
+ invalidatesSnapshot: true,
3902
+ }),
3903
+ discardCommunityFeedbackDraft: defineContract({
3904
+ method: 'DELETE',
3905
+ path: '/api/community/feedback/drafts/:draftId',
3906
+ params: z.object({ draftId: CommunityFeedbackDraftIdSchema }).strict(),
3907
+ request: NoRequestBodySchema,
3908
+ response: CommunityFeedbackDraftSchema,
3909
+ error: HostApiErrorSchema,
3910
+ invalidatesSnapshot: true,
3911
+ }),
3912
+ previewCommunityFeedbackPayload: defineContract({
3913
+ method: 'GET',
3914
+ path: '/api/community/feedback/drafts/:draftId/preview',
3915
+ params: z.object({ draftId: CommunityFeedbackDraftIdSchema }).strict(),
3916
+ request: NoRequestBodySchema,
3917
+ response: CommunityFeedbackPayloadSchema,
3918
+ error: HostApiErrorSchema,
3919
+ }),
3920
+ getLastSentCommunityFeedbackPayload: defineContract({
3921
+ method: 'GET',
3922
+ path: '/api/community/feedback/last-sent',
3923
+ params: EmptyParamsSchema,
3924
+ request: NoRequestBodySchema,
3925
+ response: CommunityFeedbackLastPayloadSchema,
3926
+ error: HostApiErrorSchema,
3927
+ }),
3928
+ replyCommunityFeedback: defineContract({
3929
+ method: 'POST',
3930
+ path: '/api/community/feedback/items/:ref/messages',
3931
+ params: z.object({ ref: CommunityFeedbackRefSchema }).strict(),
3932
+ request: z.object({ body: z.string().trim().min(1).max(4000) }).strict(),
3933
+ response: CommunityFeedbackSchema,
3934
+ error: HostApiErrorSchema,
3935
+ invalidatesSnapshot: true,
3936
+ }),
3937
+ withdrawCommunityFeedback: defineContract({
3938
+ method: 'POST',
3939
+ path: '/api/community/feedback/items/:ref/withdraw',
3940
+ params: z.object({ ref: CommunityFeedbackRefSchema }).strict(),
3941
+ request: CommunityFeedbackWithdrawSchema,
3942
+ response: CommunityFeedbackSchema,
3943
+ error: HostApiErrorSchema,
3944
+ invalidatesSnapshot: true,
3945
+ }),
3946
+ reopenCommunityFeedback: defineContract({
3947
+ method: 'POST',
3948
+ path: '/api/community/feedback/items/:ref/reopen',
3949
+ params: z.object({ ref: CommunityFeedbackRefSchema }).strict(),
3950
+ request: CommunityFeedbackReopenSchema,
3951
+ response: CommunityFeedbackSchema,
3952
+ error: HostApiErrorSchema,
3953
+ invalidatesSnapshot: true,
3954
+ }),
3955
+ markCommunityFeedbackAffected: defineContract({
3956
+ method: 'POST',
3957
+ path: '/api/community/feedback/items/:ref/affected',
3958
+ params: z.object({ ref: CommunityFeedbackRefSchema }).strict(),
3959
+ request: z.object({ affected: z.boolean().default(true), consent: z.boolean().default(false) }).strict(),
3960
+ response: CommunityFeedbackSchema,
3961
+ error: HostApiErrorSchema,
3962
+ invalidatesSnapshot: true,
3963
+ }),
3964
+ confirmCommunityFeedbackFixed: defineContract({
3965
+ method: 'POST',
3966
+ path: '/api/community/feedback/items/:ref/confirm-fixed',
3967
+ params: z.object({ ref: CommunityFeedbackRefSchema }).strict(),
3968
+ request: z.object({}).strict(),
3969
+ response: CommunityFeedbackSchema,
3970
+ error: HostApiErrorSchema,
3971
+ invalidatesSnapshot: true,
3972
+ }),
3075
3973
  startCommunityLogin: defineContract({
3076
3974
  method: 'POST',
3077
3975
  path: '/api/community/login',
@@ -3151,13 +4049,13 @@ export const HostApiContracts = {
3151
4049
  .strict(),
3152
4050
  error: HostApiErrorSchema,
3153
4051
  }),
3154
- listCommunityInstalled: defineContract({
3155
- timeoutMs: 30_000,
4052
+ listCommunitySync: defineContract({
4053
+ timeoutMs: 60_000,
3156
4054
  method: 'GET',
3157
- path: '/api/community/installed',
4055
+ path: '/api/community/sync',
3158
4056
  params: z.object({ refresh: z.enum(['1']).optional() }).strict(),
3159
4057
  request: NoRequestBodySchema,
3160
- response: CommunityInstalledSchema,
4058
+ response: CommunitySyncSchema,
3161
4059
  error: HostApiErrorSchema,
3162
4060
  }),
3163
4061
  listCommunityMine: defineContract({
@@ -3222,6 +4120,7 @@ export const HostApiContracts = {
3222
4120
  response: z
3223
4121
  .object({
3224
4122
  releaseId: CommunityReleaseIdSchema,
4123
+ releaseNumber: z.number().int().positive(),
3225
4124
  reviewStatus: CommunityReviewStatusSchema,
3226
4125
  pageUrl: z.string().url(),
3227
4126
  reportUrl: z.string().url(),
@@ -3594,7 +4493,19 @@ export const HostApiContracts = {
3594
4493
  path: '/api/dynamic/:agentId/decline',
3595
4494
  params: agentParam,
3596
4495
  request: z
3597
- .object({ episodeId: EpisodeIdSchema, requestId: DynamicIdSchema, pluginRunId: DynamicIdSchema.optional() })
4496
+ .object({
4497
+ episodeId: EpisodeIdSchema,
4498
+ requestId: DynamicIdSchema,
4499
+ pluginRunId: DynamicIdSchema.optional(),
4500
+ /**
4501
+ * Why the run did not go ahead: the user declined it, or the page could not start one of its halves. A failed
4502
+ * half is settled as a failed attempt (its Host is retracted and the agent hears about it), not as a decline.
4503
+ */
4504
+ reason: z.enum(['rejected', 'host-half-failed', 'client-half-failed']).optional(),
4505
+ startedHere: z.boolean().optional(),
4506
+ message: z.string().max(4000).optional(),
4507
+ stack: z.string().max(16000).optional(),
4508
+ })
3598
4509
  .strict(),
3599
4510
  response: z.object({ accepted: z.boolean() }).strict(),
3600
4511
  error: HostApiErrorSchema,
@@ -3750,36 +4661,20 @@ export const HostApiContracts = {
3750
4661
  method: 'POST',
3751
4662
  path: '/api/extensions/save-from-dynamic',
3752
4663
  params: EmptyParamsSchema,
3753
- request: z.union([
3754
- z
3755
- .object({
3756
- taskId: AuthoringTaskIdSchema,
3757
- attemptId: AuthoringAttemptIdSchema,
3758
- displayName: z.string().trim().min(1).max(80),
3759
- slug: z
3760
- .string()
3761
- .trim()
3762
- .regex(/^[a-z0-9][a-z0-9-]{1,62}[a-z0-9]$/u),
3763
- description: z.string().max(500).default(''),
3764
- targetExtensionId: ExtensionIdSchema.optional(),
3765
- })
3766
- .strict(),
3767
- z
3768
- .object({
3769
- agentId: AgentIdSchema,
3770
- episodeId: EpisodeIdSchema,
3771
- pluginId: DynamicIdSchema,
3772
- packageId: DynamicIdSchema,
3773
- displayName: z.string().trim().min(1).max(80),
3774
- slug: z
3775
- .string()
3776
- .trim()
3777
- .regex(/^[a-z0-9][a-z0-9-]{1,62}[a-z0-9]$/u),
3778
- description: z.string().max(500).default(''),
3779
- targetExtensionId: ExtensionIdSchema.optional(),
3780
- })
3781
- .strict(),
3782
- ]),
4664
+ request: z
4665
+ .object({
4666
+ taskId: AuthoringTaskIdSchema,
4667
+ /** The candidate the user saw; saving refuses when a newer one appeared since. */
4668
+ attemptId: AuthoringAttemptIdSchema,
4669
+ displayName: z.string().trim().min(1).max(80),
4670
+ slug: z
4671
+ .string()
4672
+ .trim()
4673
+ .regex(/^[a-z0-9][a-z0-9-]{1,62}[a-z0-9]$/u),
4674
+ description: z.string().max(500).default(''),
4675
+ targetExtensionId: ExtensionIdSchema.optional(),
4676
+ })
4677
+ .strict(),
3783
4678
  response: z
3784
4679
  .object({
3785
4680
  extensionId: ExtensionIdSchema,
@@ -3924,6 +4819,8 @@ export const HostApiContracts = {
3924
4819
  permissionApproval: PermissionApprovalSchema.optional(),
3925
4820
  /** Approval of expanded agent-layer capabilities for the agents that move to this Revision. */
3926
4821
  agentPermissionApproval: PermissionApprovalSchema.optional(),
4822
+ /** Data copy to put back first, when the target Revision only reads an older data version. */
4823
+ restoreDataSnapshotId: z.string().min(1).max(80).optional(),
3927
4824
  })
3928
4825
  .strict(),
3929
4826
  response: z
@@ -4040,6 +4937,15 @@ export const HostApiContracts = {
4040
4937
  .strict(),
4041
4938
  error: HostApiErrorSchema,
4042
4939
  }),
4940
+ setChannelPaused: defineContract({
4941
+ method: 'POST',
4942
+ path: '/api/channels/:channelId/pause',
4943
+ params: channelParam,
4944
+ request: z.object({ paused: z.boolean() }).strict(),
4945
+ response: z.object({ paused: z.boolean(), changed: z.boolean(), stopped: z.boolean() }).strict(),
4946
+ error: HostApiErrorSchema,
4947
+ invalidatesSnapshot: true,
4948
+ }),
4043
4949
  resolveOutbound: defineContract({
4044
4950
  method: 'POST',
4045
4951
  path: '/api/outbound/:outboundId/resolve',
@@ -4114,6 +5020,196 @@ export const HostApiContracts = {
4114
5020
  response: z.object({ deleted: z.literal(true) }).strict(),
4115
5021
  error: HostApiErrorSchema,
4116
5022
  }),
5023
+ getExtensionLineage: defineContract({
5024
+ method: 'GET',
5025
+ path: '/api/extensions/:extensionId/lineage',
5026
+ params: extensionParam,
5027
+ request: NoRequestBodySchema,
5028
+ response: ExtensionLineageSchema,
5029
+ error: HostApiErrorSchema,
5030
+ }),
5031
+ branchExtension: defineContract({
5032
+ invalidatesSnapshot: true,
5033
+ timeoutMs: 300_000,
5034
+ method: 'POST',
5035
+ path: '/api/extensions/:extensionId/branch',
5036
+ params: extensionParam,
5037
+ request: z
5038
+ .object({
5039
+ revisionId: ExtensionRevisionIdSchema,
5040
+ name: z.string().trim().min(1).max(80),
5041
+ slug: z
5042
+ .string()
5043
+ .trim()
5044
+ .regex(/^[a-z0-9][a-z0-9-]{1,62}[a-z0-9]$/u)
5045
+ .optional(),
5046
+ copyData: z.boolean(),
5047
+ })
5048
+ .strict(),
5049
+ response: z.object({ extensionId: ExtensionIdSchema, revisionId: ExtensionRevisionIdSchema }).strict(),
5050
+ error: HostApiErrorSchema,
5051
+ }),
5052
+ rollbackExtension: defineContract({
5053
+ invalidatesSnapshot: true,
5054
+ timeoutMs: 300_000,
5055
+ method: 'POST',
5056
+ path: '/api/extensions/:extensionId/revert',
5057
+ params: extensionParam,
5058
+ request: NoRequestBodySchema,
5059
+ response: z.object({ message: z.string() }).strict(),
5060
+ error: HostApiErrorSchema,
5061
+ }),
5062
+ getExtensionData: defineContract({
5063
+ method: 'GET',
5064
+ path: '/api/extensions/:extensionId/data',
5065
+ params: extensionParam,
5066
+ request: NoRequestBodySchema,
5067
+ response: ExtensionDataStateSchema,
5068
+ error: HostApiErrorSchema,
5069
+ }),
5070
+ previewExtensionDataMigration: defineContract({
5071
+ timeoutMs: 60_000,
5072
+ method: 'POST',
5073
+ path: '/api/extensions/:extensionId/data/preview',
5074
+ params: extensionParam,
5075
+ request: ExtensionDataMigrationInputSchema,
5076
+ response: ExtensionDataPreviewSchema,
5077
+ error: HostApiErrorSchema,
5078
+ }),
5079
+ migrateExtensionData: defineContract({
5080
+ invalidatesSnapshot: true,
5081
+ timeoutMs: 300_000,
5082
+ method: 'POST',
5083
+ path: '/api/extensions/:extensionId/data/migrate',
5084
+ params: extensionParam,
5085
+ request: ExtensionDataMigrationInputSchema,
5086
+ response: z.object({ snapshotId: z.string(), preview: ExtensionDataPreviewSchema }).strict(),
5087
+ error: HostApiErrorSchema,
5088
+ }),
5089
+ exportExtensionData: defineContract({
5090
+ method: 'GET',
5091
+ timeoutMs: 300_000,
5092
+ path: '/api/extensions/:extensionId/data/export',
5093
+ params: extensionParam,
5094
+ request: NoRequestBodySchema,
5095
+ responseFormat: 'bytes',
5096
+ response: z.instanceof(Uint8Array),
5097
+ error: HostApiErrorSchema,
5098
+ }),
5099
+ /** The same package with the host and agent configuration; secrets are left out. */
5100
+ exportExtensionDataWithConfig: defineContract({
5101
+ method: 'GET',
5102
+ timeoutMs: 300_000,
5103
+ path: '/api/extensions/:extensionId/data/export-config',
5104
+ params: extensionParam,
5105
+ request: NoRequestBodySchema,
5106
+ responseFormat: 'bytes',
5107
+ response: z.instanceof(Uint8Array),
5108
+ error: HostApiErrorSchema,
5109
+ }),
5110
+ createExtensionDataSnapshot: defineContract({
5111
+ method: 'POST',
5112
+ path: '/api/extensions/:extensionId/data/snapshots',
5113
+ params: extensionParam,
5114
+ request: z.object({ label: z.string().trim().min(1).max(80) }).strict(),
5115
+ response: z.object({ snapshotId: z.string() }).strict(),
5116
+ error: HostApiErrorSchema,
5117
+ }),
5118
+ inspectExtensionDataPackage: defineContract({
5119
+ timeoutMs: 300_000,
5120
+ method: 'POST',
5121
+ path: '/api/extensions/data/inspect',
5122
+ params: EmptyParamsSchema,
5123
+ request: BinaryUploadRequestSchema,
5124
+ encodeRequest: encodeBinaryUpload,
5125
+ response: ExtensionDataPackageInspectionSchema,
5126
+ error: HostApiErrorSchema,
5127
+ }),
5128
+ listExtensionRequests: defineContract({
5129
+ method: 'GET',
5130
+ path: '/api/extension-requests',
5131
+ params: EmptyParamsSchema,
5132
+ request: NoRequestBodySchema,
5133
+ response: z.object({ requests: z.array(ExtensionRequestSchema) }).strict(),
5134
+ error: HostApiErrorSchema,
5135
+ }),
5136
+ approveExtensionRequest: defineContract({
5137
+ invalidatesSnapshot: true,
5138
+ timeoutMs: 300_000,
5139
+ method: 'POST',
5140
+ path: '/api/extension-requests/:number/approve',
5141
+ params: z.object({ number: z.coerce.number().int().positive() }).strict(),
5142
+ request: NoRequestBodySchema,
5143
+ response: z.object({ message: z.string() }).strict(),
5144
+ error: HostApiErrorSchema,
5145
+ }),
5146
+ rejectExtensionRequest: defineContract({
5147
+ method: 'POST',
5148
+ path: '/api/extension-requests/:number/reject',
5149
+ params: z.object({ number: z.coerce.number().int().positive() }).strict(),
5150
+ request: z.object({ reason: z.string().trim().max(500).optional() }).strict(),
5151
+ response: z.object({ ok: z.literal(true) }).strict(),
5152
+ error: HostApiErrorSchema,
5153
+ }),
5154
+ listAdministrators: defineContract({
5155
+ method: 'GET',
5156
+ path: '/api/administrators',
5157
+ params: EmptyParamsSchema,
5158
+ request: NoRequestBodySchema,
5159
+ response: z.object({ administrators: z.array(AdministratorSchema) }).strict(),
5160
+ error: HostApiErrorSchema,
5161
+ }),
5162
+ addAdministrator: defineContract({
5163
+ method: 'POST',
5164
+ path: '/api/administrators',
5165
+ params: EmptyParamsSchema,
5166
+ request: z.object({ identityId: PlatformIdentityIdSchema }).strict(),
5167
+ response: AdministratorSchema,
5168
+ error: HostApiErrorSchema,
5169
+ }),
5170
+ removeAdministrator: defineContract({
5171
+ method: 'POST',
5172
+ path: '/api/administrators/remove',
5173
+ params: EmptyParamsSchema,
5174
+ request: z.object({ connectionId: ConnectionIdSchema, platformUserId: z.string().min(1) }).strict(),
5175
+ response: z.object({ ok: z.literal(true) }).strict(),
5176
+ error: HostApiErrorSchema,
5177
+ }),
5178
+ createAdministratorClaimCode: defineContract({
5179
+ method: 'POST',
5180
+ path: '/api/administrators/claim-code',
5181
+ params: EmptyParamsSchema,
5182
+ request: NoRequestBodySchema,
5183
+ response: z.object({ code: z.string(), expiresAt: z.number().int().nonnegative() }).strict(),
5184
+ error: HostApiErrorSchema,
5185
+ }),
5186
+ dismissCommunityRelease: defineContract({
5187
+ method: 'POST',
5188
+ path: '/api/community/sync/:extensionId/dismiss',
5189
+ params: extensionParam,
5190
+ request: z.object({ releaseId: CommunityReleaseIdSchema.nullable() }).strict(),
5191
+ response: z.object({ ok: z.literal(true) }).strict(),
5192
+ error: HostApiErrorSchema,
5193
+ }),
5194
+ updateFromCommunity: defineContract({
5195
+ invalidatesSnapshot: true,
5196
+ timeoutMs: 300_000,
5197
+ method: 'POST',
5198
+ path: '/api/community/sync/:extensionId/update',
5199
+ params: extensionParam,
5200
+ request: NoRequestBodySchema,
5201
+ response: z.object({ message: z.string() }).strict(),
5202
+ error: HostApiErrorSchema,
5203
+ }),
5204
+ archiveAuthoringTask: defineContract({
5205
+ invalidatesSnapshot: true,
5206
+ method: 'POST',
5207
+ path: '/api/authoring/tasks/:taskId/archive',
5208
+ params: z.object({ taskId: AuthoringTaskIdSchema }).strict(),
5209
+ request: NoRequestBodySchema,
5210
+ response: z.object({ ok: z.literal(true) }).strict(),
5211
+ error: HostApiErrorSchema,
5212
+ }),
4117
5213
  } as const
4118
5214
 
4119
5215
  export type HostApiContractName = keyof typeof HostApiContracts
@@ -4173,3 +5269,21 @@ export function buildHostApiContractPath<Params extends AnySchema>(
4173
5269
  export function buildHostApiPath<Name extends HostApiContractName>(name: Name, input: HostApiParams<Name>): string {
4174
5270
  return buildValidatedHostApiPath(HostApiContracts[name], input)
4175
5271
  }
5272
+ import {
5273
+ CommunityFeedbackDraftIdSchema,
5274
+ CommunityFeedbackDraftInputSchema,
5275
+ CommunityFeedbackDraftSchema,
5276
+ CommunityFeedbackDraftUpdateSchema,
5277
+ CommunityFeedbackLastPayloadSchema,
5278
+ CommunityFeedbackLocalListSchema,
5279
+ CommunityFeedbackPayloadSchema,
5280
+ CommunityFeedbackSettingsSchema,
5281
+ CommunityFeedbackSettingsUpdateSchema,
5282
+ CommunityFeedbackSnapshotSchema,
5283
+ } from './community-feedback-host.js'
5284
+ import {
5285
+ CommunityFeedbackRefSchema,
5286
+ CommunityFeedbackSchema,
5287
+ CommunityFeedbackWithdrawSchema,
5288
+ CommunityFeedbackReopenSchema,
5289
+ } from './community-feedback.js'