@synoikia/core 0.1.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.
Files changed (209) hide show
  1. package/LICENSE +21 -0
  2. package/dist/app.d.ts +79 -0
  3. package/dist/app.js +155 -0
  4. package/dist/app.js.map +1 -0
  5. package/dist/approvals/links.d.ts +23 -0
  6. package/dist/approvals/links.js +49 -0
  7. package/dist/approvals/links.js.map +1 -0
  8. package/dist/approvals/service.d.ts +110 -0
  9. package/dist/approvals/service.js +182 -0
  10. package/dist/approvals/service.js.map +1 -0
  11. package/dist/audit-query.d.ts +52 -0
  12. package/dist/audit-query.js +116 -0
  13. package/dist/audit-query.js.map +1 -0
  14. package/dist/audit.d.ts +5 -0
  15. package/dist/audit.js +8 -0
  16. package/dist/audit.js.map +1 -0
  17. package/dist/auth/mcp-auth.d.ts +50 -0
  18. package/dist/auth/mcp-auth.js +160 -0
  19. package/dist/auth/mcp-auth.js.map +1 -0
  20. package/dist/auth/mcp-tokens.d.ts +57 -0
  21. package/dist/auth/mcp-tokens.js +143 -0
  22. package/dist/auth/mcp-tokens.js.map +1 -0
  23. package/dist/auth/oauth.d.ts +188 -0
  24. package/dist/auth/oauth.js +470 -0
  25. package/dist/auth/oauth.js.map +1 -0
  26. package/dist/auth/oidc.d.ts +110 -0
  27. package/dist/auth/oidc.js +221 -0
  28. package/dist/auth/oidc.js.map +1 -0
  29. package/dist/auth/sessions.d.ts +34 -0
  30. package/dist/auth/sessions.js +83 -0
  31. package/dist/auth/sessions.js.map +1 -0
  32. package/dist/auth/throttle.d.ts +31 -0
  33. package/dist/auth/throttle.js +52 -0
  34. package/dist/auth/throttle.js.map +1 -0
  35. package/dist/auth/tokens.d.ts +7 -0
  36. package/dist/auth/tokens.js +40 -0
  37. package/dist/auth/tokens.js.map +1 -0
  38. package/dist/auth/totp.d.ts +14 -0
  39. package/dist/auth/totp.js +81 -0
  40. package/dist/auth/totp.js.map +1 -0
  41. package/dist/auth/users.d.ts +70 -0
  42. package/dist/auth/users.js +296 -0
  43. package/dist/auth/users.js.map +1 -0
  44. package/dist/catalog/groups.d.ts +102 -0
  45. package/dist/catalog/groups.js +363 -0
  46. package/dist/catalog/groups.js.map +1 -0
  47. package/dist/catalog/registry.d.ts +25 -0
  48. package/dist/catalog/registry.js +80 -0
  49. package/dist/catalog/registry.js.map +1 -0
  50. package/dist/catalog/rules.d.ts +128 -0
  51. package/dist/catalog/rules.js +178 -0
  52. package/dist/catalog/rules.js.map +1 -0
  53. package/dist/catalog/sync.d.ts +29 -0
  54. package/dist/catalog/sync.js +222 -0
  55. package/dist/catalog/sync.js.map +1 -0
  56. package/dist/cli.d.ts +3 -0
  57. package/dist/cli.js +83 -0
  58. package/dist/cli.js.map +1 -0
  59. package/dist/config/env.d.ts +40 -0
  60. package/dist/config/env.js +71 -0
  61. package/dist/config/env.js.map +1 -0
  62. package/dist/crypto/index.d.ts +28 -0
  63. package/dist/crypto/index.js +88 -0
  64. package/dist/crypto/index.js.map +1 -0
  65. package/dist/crypto/rotate.d.ts +15 -0
  66. package/dist/crypto/rotate.js +61 -0
  67. package/dist/crypto/rotate.js.map +1 -0
  68. package/dist/db/index.d.ts +17 -0
  69. package/dist/db/index.js +29 -0
  70. package/dist/db/index.js.map +1 -0
  71. package/dist/db/schema.d.ts +4389 -0
  72. package/dist/db/schema.js +372 -0
  73. package/dist/db/schema.js.map +1 -0
  74. package/dist/endpoints/slug.d.ts +3 -0
  75. package/dist/endpoints/slug.js +7 -0
  76. package/dist/endpoints/slug.js.map +1 -0
  77. package/dist/errors.d.ts +16 -0
  78. package/dist/errors.js +29 -0
  79. package/dist/errors.js.map +1 -0
  80. package/dist/events.d.ts +43 -0
  81. package/dist/events.js +16 -0
  82. package/dist/events.js.map +1 -0
  83. package/dist/gate/access.d.ts +47 -0
  84. package/dist/gate/access.js +48 -0
  85. package/dist/gate/access.js.map +1 -0
  86. package/dist/gate/attestation.d.ts +23 -0
  87. package/dist/gate/attestation.js +33 -0
  88. package/dist/gate/attestation.js.map +1 -0
  89. package/dist/gate/canonical.d.ts +3 -0
  90. package/dist/gate/canonical.js +11 -0
  91. package/dist/gate/canonical.js.map +1 -0
  92. package/dist/gate/match.d.ts +67 -0
  93. package/dist/gate/match.js +133 -0
  94. package/dist/gate/match.js.map +1 -0
  95. package/dist/gate/pipeline.d.ts +61 -0
  96. package/dist/gate/pipeline.js +284 -0
  97. package/dist/gate/pipeline.js.map +1 -0
  98. package/dist/gate/preapproval.d.ts +24 -0
  99. package/dist/gate/preapproval.js +48 -0
  100. package/dist/gate/preapproval.js.map +1 -0
  101. package/dist/gate/rate-limit.d.ts +35 -0
  102. package/dist/gate/rate-limit.js +82 -0
  103. package/dist/gate/rate-limit.js.map +1 -0
  104. package/dist/gate/redact.d.ts +23 -0
  105. package/dist/gate/redact.js +87 -0
  106. package/dist/gate/redact.js.map +1 -0
  107. package/dist/http/admin/auth.d.ts +33 -0
  108. package/dist/http/admin/auth.js +338 -0
  109. package/dist/http/admin/auth.js.map +1 -0
  110. package/dist/http/admin/instances.d.ts +5 -0
  111. package/dist/http/admin/instances.js +193 -0
  112. package/dist/http/admin/instances.js.map +1 -0
  113. package/dist/http/admin/system.d.ts +5 -0
  114. package/dist/http/admin/system.js +225 -0
  115. package/dist/http/admin/system.js.map +1 -0
  116. package/dist/http/admin-app.d.ts +9 -0
  117. package/dist/http/admin-app.js +51 -0
  118. package/dist/http/admin-app.js.map +1 -0
  119. package/dist/http/common.d.ts +32 -0
  120. package/dist/http/common.js +80 -0
  121. package/dist/http/common.js.map +1 -0
  122. package/dist/http/mcp/approval-routes.d.ts +11 -0
  123. package/dist/http/mcp/approval-routes.js +117 -0
  124. package/dist/http/mcp/approval-routes.js.map +1 -0
  125. package/dist/http/mcp/endpoint.d.ts +32 -0
  126. package/dist/http/mcp/endpoint.js +293 -0
  127. package/dist/http/mcp/endpoint.js.map +1 -0
  128. package/dist/http/mcp/oauth-routes.d.ts +29 -0
  129. package/dist/http/mcp/oauth-routes.js +465 -0
  130. package/dist/http/mcp/oauth-routes.js.map +1 -0
  131. package/dist/http/mcp/pages.d.ts +63 -0
  132. package/dist/http/mcp/pages.js +200 -0
  133. package/dist/http/mcp/pages.js.map +1 -0
  134. package/dist/http/mcp-app.d.ts +7 -0
  135. package/dist/http/mcp-app.js +30 -0
  136. package/dist/http/mcp-app.js.map +1 -0
  137. package/dist/instances/connection.d.ts +37 -0
  138. package/dist/instances/connection.js +109 -0
  139. package/dist/instances/connection.js.map +1 -0
  140. package/dist/instances/manager.d.ts +313 -0
  141. package/dist/instances/manager.js +600 -0
  142. package/dist/instances/manager.js.map +1 -0
  143. package/dist/instances/settings.d.ts +42 -0
  144. package/dist/instances/settings.js +57 -0
  145. package/dist/instances/settings.js.map +1 -0
  146. package/dist/lenient.d.ts +16 -0
  147. package/dist/lenient.js +51 -0
  148. package/dist/lenient.js.map +1 -0
  149. package/dist/lock.d.ts +28 -0
  150. package/dist/lock.js +77 -0
  151. package/dist/lock.js.map +1 -0
  152. package/dist/main.d.ts +1 -0
  153. package/dist/main.js +38 -0
  154. package/dist/main.js.map +1 -0
  155. package/dist/maintenance.d.ts +10 -0
  156. package/dist/maintenance.js +48 -0
  157. package/dist/maintenance.js.map +1 -0
  158. package/dist/notify/service.d.ts +149 -0
  159. package/dist/notify/service.js +358 -0
  160. package/dist/notify/service.js.map +1 -0
  161. package/dist/plugins/discovery.d.ts +39 -0
  162. package/dist/plugins/discovery.js +157 -0
  163. package/dist/plugins/discovery.js.map +1 -0
  164. package/dist/plugins/minisign.d.ts +25 -0
  165. package/dist/plugins/minisign.js +49 -0
  166. package/dist/plugins/minisign.js.map +1 -0
  167. package/dist/plugins/process.d.ts +55 -0
  168. package/dist/plugins/process.js +162 -0
  169. package/dist/plugins/process.js.map +1 -0
  170. package/dist/plugins/repos.d.ts +198 -0
  171. package/dist/plugins/repos.js +612 -0
  172. package/dist/plugins/repos.js.map +1 -0
  173. package/dist/plugins/supervisor.d.ts +50 -0
  174. package/dist/plugins/supervisor.js +125 -0
  175. package/dist/plugins/supervisor.js.map +1 -0
  176. package/dist/runtime/index.d.ts +28 -0
  177. package/dist/runtime/index.js +248 -0
  178. package/dist/runtime/index.js.map +1 -0
  179. package/dist/sandbox/index.d.ts +53 -0
  180. package/dist/sandbox/index.js +197 -0
  181. package/dist/sandbox/index.js.map +1 -0
  182. package/dist/server.d.ts +16 -0
  183. package/dist/server.js +36 -0
  184. package/dist/server.js.map +1 -0
  185. package/dist/settings.d.ts +43 -0
  186. package/dist/settings.js +99 -0
  187. package/dist/settings.js.map +1 -0
  188. package/dist/testing/index.d.ts +73 -0
  189. package/dist/testing/index.js +174 -0
  190. package/dist/testing/index.js.map +1 -0
  191. package/dist/version.d.ts +2 -0
  192. package/dist/version.js +4 -0
  193. package/dist/version.js.map +1 -0
  194. package/drizzle/0000_init.sql +334 -0
  195. package/drizzle/0001_totp_last_step.sql +1 -0
  196. package/drizzle/0002_access_levels.sql +16 -0
  197. package/drizzle/0003_drop_exclusion_flags.sql +2 -0
  198. package/drizzle/0004_grant_instance_ids.sql +1 -0
  199. package/drizzle/0005_rule_strict_miss.sql +1 -0
  200. package/drizzle/0006_attestation_waived.sql +1 -0
  201. package/drizzle/meta/0000_snapshot.json +2318 -0
  202. package/drizzle/meta/0001_snapshot.json +2325 -0
  203. package/drizzle/meta/0002_snapshot.json +2348 -0
  204. package/drizzle/meta/0003_snapshot.json +2332 -0
  205. package/drizzle/meta/0004_snapshot.json +2339 -0
  206. package/drizzle/meta/0005_snapshot.json +2346 -0
  207. package/drizzle/meta/0006_snapshot.json +2354 -0
  208. package/drizzle/meta/_journal.json +55 -0
  209. package/package.json +58 -0
@@ -0,0 +1,372 @@
1
+ import { sql } from 'drizzle-orm';
2
+ import { blob, index, integer, sqliteTable, text, uniqueIndex } from 'drizzle-orm/sqlite-core';
3
+ /**
4
+ * Single SQLite schema for the whole server (design §7.1). JSON is stored as TEXT, timestamps as
5
+ * epoch milliseconds, encrypted values as AES-256-GCM blobs (design §7.2).
6
+ */
7
+ const id = () => text('id').primaryKey();
8
+ const ts = (name) => integer(name, { mode: 'timestamp_ms' });
9
+ const createdAt = () => ts('created_at')
10
+ .notNull()
11
+ .default(sql `(unixepoch() * 1000)`);
12
+ const flag = (name) => integer(name, { mode: 'boolean' });
13
+ const json = (name) => text(name, { mode: 'json' });
14
+ // ── identity & admin auth ────────────────────────────────────────────────────────────────────────
15
+ export const users = sqliteTable('users', {
16
+ id: id(),
17
+ username: text('username').notNull().unique(),
18
+ passwordHash: text('password_hash'),
19
+ totpSecretEnc: blob('totp_secret_enc', { mode: 'buffer' }),
20
+ totpEnabled: flag('totp_enabled').notNull().default(false),
21
+ /** Last accepted TOTP time step, so a code can't be replayed within its window. */
22
+ totpLastStep: integer('totp_last_step'),
23
+ recoveryCodesHash: json('recovery_codes_hash').$type(),
24
+ oidcIssuer: text('oidc_issuer'),
25
+ oidcSubject: text('oidc_subject'),
26
+ createdAt: createdAt(),
27
+ lastLoginAt: ts('last_login_at'),
28
+ disabled: flag('disabled').notNull().default(false),
29
+ });
30
+ export const sessions = sqliteTable('sessions', {
31
+ idHash: text('id_hash').primaryKey(),
32
+ userId: text('user_id')
33
+ .notNull()
34
+ .references(() => users.id, { onDelete: 'cascade' }),
35
+ kind: text('kind', { enum: ['admin', 'oauth_ui', 'approval_ui'] }).notNull(),
36
+ createdAt: createdAt(),
37
+ lastSeenAt: ts('last_seen_at').notNull(),
38
+ expiresAt: ts('expires_at').notNull(),
39
+ ip: text('ip'),
40
+ userAgent: text('user_agent'),
41
+ }, (t) => [index('sessions_user_idx').on(t.userId)]);
42
+ export const settings = sqliteTable('settings', {
43
+ key: text('key').primaryKey(),
44
+ value: json('value').notNull(),
45
+ });
46
+ export const oidcConfig = sqliteTable('oidc_config', {
47
+ id: integer('id').primaryKey(),
48
+ issuer: text('issuer').notNull(),
49
+ clientId: text('client_id').notNull(),
50
+ clientSecretEnc: blob('client_secret_enc', { mode: 'buffer' }),
51
+ scopes: text('scopes').notNull().default('openid email profile'),
52
+ allowPolicy: json('allow_policy').$type(),
53
+ autoProvision: flag('auto_provision').notNull().default(false),
54
+ enabled: flag('enabled').notNull().default(false),
55
+ });
56
+ // ── plugins ──────────────────────────────────────────────────────────────────────────────────────
57
+ export const pluginRepos = sqliteTable('plugin_repos', {
58
+ id: id(),
59
+ url: text('url').notNull().unique(),
60
+ name: text('name'),
61
+ signingMode: text('signing_mode', { enum: ['signed', 'unsigned'] }).notNull(),
62
+ publicKey: text('public_key'),
63
+ keyFingerprint: text('key_fingerprint'),
64
+ keyStatus: text('key_status', { enum: ['ok', 'key_changed'] })
65
+ .notNull()
66
+ .default('ok'),
67
+ indexCache: json('index_cache'),
68
+ lastFetchedAt: ts('last_fetched_at'),
69
+ lastFetchError: text('last_fetch_error'),
70
+ });
71
+ export const plugins = sqliteTable('plugins', {
72
+ id: id(),
73
+ pluginId: text('plugin_id').notNull().unique(),
74
+ version: text('version').notNull(),
75
+ source: text('source', { enum: ['core', 'repo'] }).notNull(),
76
+ repoId: text('repo_id').references(() => pluginRepos.id),
77
+ path: text('path').notNull(),
78
+ sha256: text('sha256'),
79
+ signatureVerified: flag('signature_verified').notNull().default(false),
80
+ manifest: json('manifest').notNull(),
81
+ status: text('status', { enum: ['ok', 'invalid', 'incompatible'] }).notNull(),
82
+ statusError: text('status_error'),
83
+ enabled: flag('enabled').notNull().default(false),
84
+ installedAt: createdAt(),
85
+ });
86
+ export const pluginInstances = sqliteTable('plugin_instances', {
87
+ id: id(),
88
+ pluginId: text('plugin_id')
89
+ .notNull()
90
+ .references(() => plugins.id),
91
+ slug: text('slug').notNull().unique(),
92
+ displayName: text('display_name').notNull(),
93
+ enabled: flag('enabled').notNull().default(true),
94
+ config: json('config').notNull().default({}),
95
+ secretsEnc: blob('secrets_enc', { mode: 'buffer' }),
96
+ /** NULL = inherit the global default (design §6.2). */
97
+ authMode: text('auth_mode', { enum: ['external', 'bearer', 'oauth', 'bearer+oauth'] }),
98
+ settings: json('settings').notNull().default({}),
99
+ status: text('status', { enum: ['stopped', 'starting', 'ready', 'error'] })
100
+ .notNull()
101
+ .default('stopped'),
102
+ statusError: text('status_error'),
103
+ upstreamVersion: text('upstream_version'),
104
+ sourceRef: text('source_ref'),
105
+ lastSyncedAt: ts('last_synced_at'),
106
+ lastSyncStatus: text('last_sync_status'),
107
+ createdAt: createdAt(),
108
+ });
109
+ // ── catalog ──────────────────────────────────────────────────────────────────────────────────────
110
+ /** One none/read/ask/write level per group; operations follow it unless they carry their own level (design §5.2). */
111
+ export const operationGroups = sqliteTable('operation_groups', {
112
+ id: id(),
113
+ instanceId: text('instance_id')
114
+ .notNull()
115
+ .references(() => pluginInstances.id, { onDelete: 'cascade' }),
116
+ key: text('key').notNull(),
117
+ label: text('label').notNull(),
118
+ /** New groups start read-only. */
119
+ level: text('level', { enum: ['none', 'read', 'ask', 'write'] })
120
+ .notNull()
121
+ .default('read'),
122
+ levelChangedAt: ts('level_changed_at'),
123
+ levelChangedBy: text('level_changed_by').references(() => users.id),
124
+ firstSeenAt: ts('first_seen_at').notNull(),
125
+ stale: flag('stale').notNull().default(false),
126
+ }, (t) => [uniqueIndex('operation_groups_instance_key_idx').on(t.instanceId, t.key)]);
127
+ /** Admin regrouping: maps a plugin-derived group onto a (possibly merged) group key; survives syncs. */
128
+ export const operationGroupAliases = sqliteTable('operation_group_aliases', {
129
+ instanceId: text('instance_id')
130
+ .notNull()
131
+ .references(() => pluginInstances.id, { onDelete: 'cascade' }),
132
+ pluginGroup: text('plugin_group').notNull(),
133
+ groupKey: text('group_key').notNull(),
134
+ }, (t) => [uniqueIndex('operation_group_aliases_idx').on(t.instanceId, t.pluginGroup)]);
135
+ export const operations = sqliteTable('operations', {
136
+ id: id(),
137
+ instanceId: text('instance_id')
138
+ .notNull()
139
+ .references(() => pluginInstances.id, { onDelete: 'cascade' }),
140
+ key: text('key').notNull(),
141
+ displayName: text('display_name'),
142
+ kind: text('kind').notNull(),
143
+ /** Group as derived by the plugin, before admin aliases are applied. */
144
+ pluginGroup: text('plugin_group').notNull(),
145
+ groupId: text('group_id')
146
+ .notNull()
147
+ .references(() => operationGroups.id),
148
+ tag: text('tag'),
149
+ /** Effective classification; locked implies write. */
150
+ classification: text('classification', { enum: ['read', 'write'] }).notNull(),
151
+ classificationSource: text('classification_source', { enum: ['locked', 'override', 'inferred'] }).notNull(),
152
+ inferredClassification: text('inferred_classification', { enum: ['read', 'write'] }).notNull(),
153
+ inferredReason: text('inferred_reason').notNull(),
154
+ locked: flag('locked').notNull().default(false),
155
+ /** Admin-set level for this operation; null follows the group. Locked ops only become callable at `ask`. */
156
+ levelOverride: text('level_override', { enum: ['none', 'read', 'ask', 'write'] }),
157
+ /** Writes at level `write` still ask for approval until an admin acknowledges them. */
158
+ writeAcknowledged: flag('write_acknowledged').notNull().default(false),
159
+ acknowledgedAt: ts('acknowledged_at'),
160
+ acknowledgedBy: text('acknowledged_by').references(() => users.id),
161
+ typedConfirmation: flag('typed_confirmation').notNull().default(false),
162
+ attestationRequired: flag('attestation_required').notNull().default(false),
163
+ /** An admin turned the attestation requirement off; the plugin's request no longer re-adds it. */
164
+ attestationWaived: flag('attestation_waived').notNull().default(false),
165
+ needsReview: flag('needs_review').notNull().default(false),
166
+ matchProfile: text('match_profile'),
167
+ paramsSchema: json('params_schema'),
168
+ docs: json('docs'),
169
+ firstSeenAt: ts('first_seen_at').notNull(),
170
+ lastSeenAt: ts('last_seen_at').notNull(),
171
+ stale: flag('stale').notNull().default(false),
172
+ }, (t) => [
173
+ uniqueIndex('operations_instance_key_idx').on(t.instanceId, t.key),
174
+ index('operations_group_idx').on(t.groupId),
175
+ ]);
176
+ export const registryEntries = sqliteTable('registry_entries', {
177
+ id: id(),
178
+ instanceId: text('instance_id')
179
+ .notNull()
180
+ .references(() => pluginInstances.id, { onDelete: 'cascade' }),
181
+ kind: text('kind').notNull(),
182
+ extId: text('ext_id').notNull(),
183
+ name: text('name').notNull(),
184
+ parentExtId: text('parent_ext_id'),
185
+ domain: text('domain'),
186
+ attrs: json('attrs'),
187
+ stale: flag('stale').notNull().default(false),
188
+ lastSyncedAt: ts('last_synced_at').notNull(),
189
+ }, (t) => [uniqueIndex('registry_instance_kind_ext_idx').on(t.instanceId, t.kind, t.extId)]);
190
+ export const guides = sqliteTable('guides', {
191
+ id: id(),
192
+ instanceId: text('instance_id')
193
+ .notNull()
194
+ .references(() => pluginInstances.id, { onDelete: 'cascade' }),
195
+ operationId: text('operation_id')
196
+ .notNull()
197
+ .references(() => operations.id, { onDelete: 'cascade' }),
198
+ version: text('version').notNull(),
199
+ content: text('content').notNull(),
200
+ fetchedAt: ts('fetched_at').notNull(),
201
+ });
202
+ // ── permission gate ──────────────────────────────────────────────────────────────────────────────
203
+ export const preApprovalRules = sqliteTable('pre_approval_rules', {
204
+ id: id(),
205
+ instanceId: text('instance_id')
206
+ .notNull()
207
+ .references(() => pluginInstances.id, { onDelete: 'cascade' }),
208
+ operationId: text('operation_id')
209
+ .notNull()
210
+ .references(() => operations.id),
211
+ match: json('match').notNull().default([]),
212
+ rateLimit: integer('rate_limit'),
213
+ windowSeconds: integer('window_seconds'),
214
+ expiresAt: ts('expires_at'),
215
+ reason: text('reason').notNull(),
216
+ enabled: flag('enabled').notNull().default(true),
217
+ createdBy: text('created_by').references(() => users.id),
218
+ createdAt: createdAt(),
219
+ updatedAt: ts('updated_at'),
220
+ lastTriggeredAt: ts('last_triggered_at'),
221
+ /** Last time the conditions held but the call had parameters the rule doesn't accept (strict match). */
222
+ strictMissAt: ts('strict_miss_at'),
223
+ });
224
+ export const preApprovalHits = sqliteTable('pre_approval_hits', {
225
+ id: integer('id').primaryKey({ autoIncrement: true }),
226
+ ruleId: text('rule_id')
227
+ .notNull()
228
+ .references(() => preApprovalRules.id, { onDelete: 'cascade' }),
229
+ occurredAt: ts('occurred_at').notNull(),
230
+ }, (t) => [index('hits_rule_time_idx').on(t.ruleId, t.occurredAt)]);
231
+ export const pendingApprovals = sqliteTable('pending_approvals', {
232
+ id: id(),
233
+ instanceId: text('instance_id')
234
+ .notNull()
235
+ .references(() => pluginInstances.id),
236
+ operationId: text('operation_id')
237
+ .notNull()
238
+ .references(() => operations.id),
239
+ /** Redacted copy for display; the real params live only in memory while pending (design §5.5). */
240
+ paramsDisplay: json('params_display'),
241
+ paramsHash: text('params_hash').notNull(),
242
+ resolvedTargets: json('resolved_targets'),
243
+ summary: text('summary').notNull(),
244
+ confirmLiteral: text('confirm_literal'),
245
+ diff: json('diff'),
246
+ expectedHash: text('expected_hash'),
247
+ clientKind: text('client_kind'),
248
+ clientId: text('client_id'),
249
+ mcpSessionId: text('mcp_session_id'),
250
+ requestedAt: ts('requested_at').notNull(),
251
+ expiresAt: ts('expires_at').notNull(),
252
+ status: text('status', { enum: ['pending', 'approved', 'denied', 'timed_out', 'cancelled'] })
253
+ .notNull()
254
+ .default('pending'),
255
+ decidedBy: text('decided_by'),
256
+ /** `url`: decided by a signed-in human on the approval page; `elicitation`: by the MCP client (opt-in). */
257
+ decidedVia: text('decided_via', { enum: ['elicitation', 'url'] }),
258
+ decidedAt: ts('decided_at'),
259
+ });
260
+ /** Append-only: no API updates or deletes rows (design §7.3). */
261
+ export const auditLog = sqliteTable('audit_log', {
262
+ id: integer('id').primaryKey({ autoIncrement: true }),
263
+ at: ts('at').notNull(),
264
+ kind: text('kind', { enum: ['call', 'search', 'config', 'auth', 'plugin'] }).notNull(),
265
+ instanceId: text('instance_id'),
266
+ operationKey: text('operation_key'),
267
+ classification: text('classification'),
268
+ decision: text('decision'),
269
+ actorKind: text('actor_kind', { enum: ['mcp_client', 'user', 'system'] }).notNull(),
270
+ actorId: text('actor_id'),
271
+ decidedBy: text('decided_by'),
272
+ decidedVia: text('decided_via'),
273
+ params: json('params'),
274
+ resolvedTargets: json('resolved_targets'),
275
+ resultStatus: text('result_status'),
276
+ durationMs: integer('duration_ms'),
277
+ detail: json('detail'),
278
+ }, (t) => [index('audit_at_idx').on(t.at), index('audit_instance_at_idx').on(t.instanceId, t.at)]);
279
+ // ── MCP client auth ──────────────────────────────────────────────────────────────────────────────
280
+ export const mcpTokens = sqliteTable('mcp_tokens', {
281
+ id: id(),
282
+ name: text('name').notNull(),
283
+ tokenHash: text('token_hash').notNull().unique(),
284
+ /** Instance ids, or ['*']. */
285
+ scope: json('scope').$type().notNull(),
286
+ /** Ceiling on what the token can reach: `read` hides and blocks every write. */
287
+ access: text('access', { enum: ['read', 'write'] })
288
+ .notNull()
289
+ .default('read'),
290
+ createdBy: text('created_by').references(() => users.id),
291
+ createdAt: createdAt(),
292
+ expiresAt: ts('expires_at'),
293
+ lastUsedAt: ts('last_used_at'),
294
+ revokedAt: ts('revoked_at'),
295
+ });
296
+ export const oauthClients = sqliteTable('oauth_clients', {
297
+ id: id(),
298
+ clientId: text('client_id').notNull().unique(),
299
+ clientSecretHash: text('client_secret_hash'),
300
+ name: text('name').notNull(),
301
+ redirectUris: json('redirect_uris').$type().notNull(),
302
+ registeredVia: text('registered_via', { enum: ['dcr', 'admin'] }).notNull(),
303
+ createdAt: createdAt(),
304
+ revokedAt: ts('revoked_at'),
305
+ });
306
+ export const oauthGrants = sqliteTable('oauth_grants', {
307
+ id: id(),
308
+ clientId: text('client_id')
309
+ .notNull()
310
+ .references(() => oauthClients.id, { onDelete: 'cascade' }),
311
+ userId: text('user_id')
312
+ .notNull()
313
+ .references(() => users.id, { onDelete: 'cascade' }),
314
+ resources: json('resources').$type().notNull(),
315
+ /**
316
+ * The instance each consented resource URL named at consent time (same order as `resources`).
317
+ * Tokens are checked against these ids, so renaming a slug or re-using it for another instance
318
+ * never carries a grant over (design §6.2). NULL only for grants from before this column.
319
+ */
320
+ instanceIds: json('instance_ids').$type(),
321
+ /** Chosen on the consent page (design §6.3); `read` hides and blocks every write. */
322
+ access: text('access', { enum: ['read', 'write'] })
323
+ .notNull()
324
+ .default('read'),
325
+ createdAt: createdAt(),
326
+ revokedAt: ts('revoked_at'),
327
+ });
328
+ export const oauthCodes = sqliteTable('oauth_codes', {
329
+ codeHash: text('code_hash').primaryKey(),
330
+ grantId: text('grant_id')
331
+ .notNull()
332
+ .references(() => oauthGrants.id, { onDelete: 'cascade' }),
333
+ codeChallenge: text('code_challenge').notNull(),
334
+ redirectUri: text('redirect_uri').notNull(),
335
+ resources: json('resources').$type().notNull(),
336
+ expiresAt: ts('expires_at').notNull(),
337
+ usedAt: ts('used_at'),
338
+ });
339
+ export const oauthTokens = sqliteTable('oauth_tokens', {
340
+ tokenHash: text('token_hash').primaryKey(),
341
+ grantId: text('grant_id')
342
+ .notNull()
343
+ .references(() => oauthGrants.id, { onDelete: 'cascade' }),
344
+ kind: text('kind', { enum: ['access', 'refresh'] }).notNull(),
345
+ familyId: text('family_id').notNull(),
346
+ resources: json('resources').$type().notNull(),
347
+ expiresAt: ts('expires_at').notNull(),
348
+ revokedAt: ts('revoked_at'),
349
+ });
350
+ // ── notifications ────────────────────────────────────────────────────────────────────────────────
351
+ export const notifierChannels = sqliteTable('notifier_channels', {
352
+ id: id(),
353
+ kind: text('kind', { enum: ['ntfy', 'webhook'] }).notNull(),
354
+ name: text('name').notNull(),
355
+ config: json('config').notNull(),
356
+ secretsEnc: blob('secrets_enc', { mode: 'buffer' }),
357
+ events: json('events').$type().notNull(),
358
+ instanceFilter: json('instance_filter').$type(),
359
+ enabled: flag('enabled').notNull().default(true),
360
+ lastSentAt: ts('last_sent_at'),
361
+ lastError: text('last_error'),
362
+ });
363
+ export const approvalLinks = sqliteTable('approval_links', {
364
+ tokenHash: text('token_hash').primaryKey(),
365
+ approvalId: text('approval_id')
366
+ .notNull()
367
+ .references(() => pendingApprovals.id, { onDelete: 'cascade' }),
368
+ action: text('action', { enum: ['approve', 'deny', 'view'] }).notNull(),
369
+ expiresAt: ts('expires_at').notNull(),
370
+ usedAt: ts('used_at'),
371
+ });
372
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** Top-level paths on the MCP listener that can never be used as an instance slug (design §2.2). */
2
+ export declare const RESERVED_SLUGS: readonly ["oauth", "a", "healthz", ".well-known", "api", "auth", "static"];
3
+ export declare function isValidSlug(slug: string): boolean;
@@ -0,0 +1,7 @@
1
+ /** Top-level paths on the MCP listener that can never be used as an instance slug (design §2.2). */
2
+ export const RESERVED_SLUGS = ['oauth', 'a', 'healthz', '.well-known', 'api', 'auth', 'static'];
3
+ const SLUG_PATTERN = /^[a-z0-9][a-z0-9-]{0,62}$/;
4
+ export function isValidSlug(slug) {
5
+ return SLUG_PATTERN.test(slug) && !RESERVED_SLUGS.includes(slug);
6
+ }
7
+ //# sourceMappingURL=slug.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slug.js","sourceRoot":"","sources":["../../src/endpoints/slug.ts"],"names":[],"mappings":"AAAA,oGAAoG;AACpG,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAU,CAAC;AAEzG,MAAM,YAAY,GAAG,2BAA2B,CAAC;AAEjD,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAE,cAAoC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAC1F,CAAC"}
@@ -0,0 +1,16 @@
1
+ /** Service-layer errors that the Admin API maps onto HTTP status codes. */
2
+ export declare class ServiceError extends Error {
3
+ readonly status: 400 | 404 | 409;
4
+ readonly code: string;
5
+ readonly details?: unknown | undefined;
6
+ constructor(status: 400 | 404 | 409, code: string, message: string, details?: unknown | undefined);
7
+ }
8
+ export declare class ValidationError extends ServiceError {
9
+ constructor(code: string, message: string, details?: unknown);
10
+ }
11
+ export declare class NotFoundError extends ServiceError {
12
+ constructor(code: string, message: string, details?: unknown);
13
+ }
14
+ export declare class ConflictError extends ServiceError {
15
+ constructor(code: string, message: string, details?: unknown);
16
+ }
package/dist/errors.js ADDED
@@ -0,0 +1,29 @@
1
+ /** Service-layer errors that the Admin API maps onto HTTP status codes. */
2
+ export class ServiceError extends Error {
3
+ status;
4
+ code;
5
+ details;
6
+ constructor(status, code, message, details) {
7
+ super(message);
8
+ this.status = status;
9
+ this.code = code;
10
+ this.details = details;
11
+ this.name = new.target.name;
12
+ }
13
+ }
14
+ export class ValidationError extends ServiceError {
15
+ constructor(code, message, details) {
16
+ super(400, code, message, details);
17
+ }
18
+ }
19
+ export class NotFoundError extends ServiceError {
20
+ constructor(code, message, details) {
21
+ super(404, code, message, details);
22
+ }
23
+ }
24
+ export class ConflictError extends ServiceError {
25
+ constructor(code, message, details) {
26
+ super(409, code, message, details);
27
+ }
28
+ }
29
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,MAAM,OAAO,YAAa,SAAQ,KAAK;IAE1B;IACA;IAEA;IAJX,YACW,MAAuB,EACvB,IAAY,EACrB,OAAe,EACN,OAAiB;QAE1B,KAAK,CAAC,OAAO,CAAC,CAAC;QALN,WAAM,GAAN,MAAM,CAAiB;QACvB,SAAI,GAAJ,IAAI,CAAQ;QAEZ,YAAO,GAAP,OAAO,CAAU;QAG1B,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;IAC9B,CAAC;CACF;AAED,MAAM,OAAO,eAAgB,SAAQ,YAAY;IAC/C,YAAY,IAAY,EAAE,OAAe,EAAE,OAAiB;QAC1D,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACrC,CAAC;CACF;AAED,MAAM,OAAO,aAAc,SAAQ,YAAY;IAC7C,YAAY,IAAY,EAAE,OAAe,EAAE,OAAiB;QAC1D,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACrC,CAAC;CACF;AAED,MAAM,OAAO,aAAc,SAAQ,YAAY;IAC7C,YAAY,IAAY,EAAE,OAAe,EAAE,OAAiB;QAC1D,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACrC,CAAC;CACF"}
@@ -0,0 +1,43 @@
1
+ import { EventEmitter } from 'node:events';
2
+ /**
3
+ * In-process event bus (design §9.1). Notifiers and the admin SSE stream subscribe here; producers
4
+ * never need to know who is listening. Payloads never carry raw params or secrets.
5
+ */
6
+ export interface CoreEventMap {
7
+ 'instance.status': [{
8
+ instanceId: string;
9
+ slug: string;
10
+ status: string;
11
+ error?: string;
12
+ }];
13
+ 'plugin.crashed': [{
14
+ instanceId: string;
15
+ slug: string;
16
+ error: string;
17
+ }];
18
+ 'sync.completed': [
19
+ {
20
+ instanceId: string;
21
+ slug: string;
22
+ added: number;
23
+ pendingReview: string[];
24
+ newGroups: string[];
25
+ rulesDisabled?: number;
26
+ }
27
+ ];
28
+ 'sync.failed': [{
29
+ instanceId: string;
30
+ slug: string;
31
+ error: string;
32
+ }];
33
+ 'auth.lockout': [{
34
+ username: string;
35
+ ip?: string;
36
+ surface?: 'admin' | 'mcp';
37
+ }];
38
+ }
39
+ export type CoreEventName = keyof CoreEventMap;
40
+ export declare const CORE_EVENT_NAMES: CoreEventName[];
41
+ export declare class CoreEvents extends EventEmitter<CoreEventMap> {
42
+ constructor();
43
+ }
package/dist/events.js ADDED
@@ -0,0 +1,16 @@
1
+ import { EventEmitter } from 'node:events';
2
+ export const CORE_EVENT_NAMES = [
3
+ 'instance.status',
4
+ 'plugin.crashed',
5
+ 'sync.completed',
6
+ 'sync.failed',
7
+ 'auth.lockout',
8
+ ];
9
+ export class CoreEvents extends EventEmitter {
10
+ constructor() {
11
+ super();
12
+ // Several subscribers (notifier channels, SSE clients) is normal; don't warn at 10.
13
+ this.setMaxListeners(0);
14
+ }
15
+ }
16
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAyB3C,MAAM,CAAC,MAAM,gBAAgB,GAAoB;IAC/C,iBAAiB;IACjB,gBAAgB;IAChB,gBAAgB;IAChB,aAAa;IACb,cAAc;CACf,CAAC;AAEF,MAAM,OAAO,UAAW,SAAQ,YAA0B;IACxD;QACE,KAAK,EAAE,CAAC;QACR,oFAAoF;QACpF,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;CACF"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Access levels (design §5.2 step 2). Every operation has an effective level: its own override if
3
+ * an admin set one, otherwise its group's level. The level decides whether a call is hidden, runs
4
+ * straight away, needs a human approval, or is auto-approved:
5
+ *
6
+ * none → nothing callable
7
+ * read → reads run; writes are hidden
8
+ * ask → reads run; writes need approval (pre-approval rules may cover them)
9
+ * write → reads run; acknowledged writes run without asking
10
+ *
11
+ * Locked operations never follow their group into `ask`/`write`: each needs its own `ask` override,
12
+ * and `write` is not allowed for them. A principal whose access ceiling is `read` (consent page,
13
+ * bearer token) never reaches a write, whatever the levels say.
14
+ */
15
+ export declare const ACCESS_LEVELS: readonly ["none", "read", "ask", "write"];
16
+ export type AccessLevel = (typeof ACCESS_LEVELS)[number];
17
+ export declare const ACCESS_CEILINGS: readonly ["read", "write"];
18
+ export type AccessCeiling = (typeof ACCESS_CEILINGS)[number];
19
+ export declare const isAccessLevel: (v: unknown) => v is AccessLevel;
20
+ export declare const minLevel: (a: AccessLevel, b: AccessLevel) => AccessLevel;
21
+ export type AccessReason = 'group_missing' | 'level_none' | 'read_only' | 'token_read_only' | 'locked_not_opted_in';
22
+ /** `run`: read, no approval · `approve`: needs a human (or a pre-approval rule) · `auto`: write, auto-approved. */
23
+ export type AccessMode = 'run' | 'approve' | 'auto';
24
+ export interface AccessOperation {
25
+ classification: 'read' | 'write';
26
+ locked: boolean;
27
+ levelOverride: AccessLevel | null;
28
+ writeAcknowledged: boolean;
29
+ }
30
+ export interface AccessGroup {
31
+ level: AccessLevel;
32
+ }
33
+ export interface AccessPrincipal {
34
+ ceiling: AccessCeiling;
35
+ }
36
+ export type AccessDecision = {
37
+ reachable: true;
38
+ mode: AccessMode;
39
+ level: AccessLevel;
40
+ /** A write at level `write` that nobody acknowledged yet: it asks until an admin does. */
41
+ pendingReview?: true;
42
+ } | {
43
+ reachable: false;
44
+ reason: AccessReason;
45
+ };
46
+ export declare const FULL_ACCESS: AccessPrincipal;
47
+ export declare function effectiveAccess(op: AccessOperation, group: AccessGroup | undefined, principal?: AccessPrincipal): AccessDecision;
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Access levels (design §5.2 step 2). Every operation has an effective level: its own override if
3
+ * an admin set one, otherwise its group's level. The level decides whether a call is hidden, runs
4
+ * straight away, needs a human approval, or is auto-approved:
5
+ *
6
+ * none → nothing callable
7
+ * read → reads run; writes are hidden
8
+ * ask → reads run; writes need approval (pre-approval rules may cover them)
9
+ * write → reads run; acknowledged writes run without asking
10
+ *
11
+ * Locked operations never follow their group into `ask`/`write`: each needs its own `ask` override,
12
+ * and `write` is not allowed for them. A principal whose access ceiling is `read` (consent page,
13
+ * bearer token) never reaches a write, whatever the levels say.
14
+ */
15
+ export const ACCESS_LEVELS = ['none', 'read', 'ask', 'write'];
16
+ export const ACCESS_CEILINGS = ['read', 'write'];
17
+ const RANK = { none: 0, read: 1, ask: 2, write: 3 };
18
+ export const isAccessLevel = (v) => ACCESS_LEVELS.includes(v);
19
+ export const minLevel = (a, b) => (RANK[a] <= RANK[b] ? a : b);
20
+ export const FULL_ACCESS = { ceiling: 'write' };
21
+ export function effectiveAccess(op, group, principal = FULL_ACCESS) {
22
+ // Fail closed on a missing or unrecognized group row, and on an unrecognized override.
23
+ if (!group || !isAccessLevel(group.level))
24
+ return { reachable: false, reason: 'group_missing' };
25
+ const level = op.levelOverride === null ? group.level : isAccessLevel(op.levelOverride) ? op.levelOverride : 'none';
26
+ if (level === 'none')
27
+ return { reachable: false, reason: 'level_none' };
28
+ // Locked operations are always writes, whatever classification the row carries.
29
+ const isWrite = op.locked || op.classification === 'write';
30
+ if (!isWrite)
31
+ return { reachable: true, mode: 'run', level };
32
+ if (principal.ceiling !== 'write')
33
+ return { reachable: false, reason: 'token_read_only' };
34
+ if (op.locked) {
35
+ // Only an explicit per-operation `ask` opens a locked op, and it never auto-approves.
36
+ if (op.levelOverride === null || RANK[level] < RANK.ask)
37
+ return { reachable: false, reason: 'locked_not_opted_in' };
38
+ return { reachable: true, mode: 'approve', level: 'ask' };
39
+ }
40
+ if (level === 'read')
41
+ return { reachable: false, reason: 'read_only' };
42
+ if (level === 'ask')
43
+ return { reachable: true, mode: 'approve', level };
44
+ if (!op.writeAcknowledged)
45
+ return { reachable: true, mode: 'approve', level, pendingReview: true };
46
+ return { reachable: true, mode: 'auto', level };
47
+ }
48
+ //# sourceMappingURL=access.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access.js","sourceRoot":"","sources":["../../src/gate/access.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAU,CAAC;AAGvE,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,MAAM,EAAE,OAAO,CAAU,CAAC;AAG1D,MAAM,IAAI,GAAgC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;AAEjF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAU,EAAoB,EAAE,CAAE,aAAoC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAEjH,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAc,EAAE,CAAc,EAAe,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAgCtG,MAAM,CAAC,MAAM,WAAW,GAAoB,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AAEjE,MAAM,UAAU,eAAe,CAC7B,EAAmB,EACnB,KAA8B,EAC9B,YAA6B,WAAW;IAExC,uFAAuF;IACvF,IAAI,CAAC,KAAK,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;IAChG,MAAM,KAAK,GACT,EAAE,CAAC,aAAa,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC;IAExG,IAAI,KAAK,KAAK,MAAM;QAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;IACxE,gFAAgF;IAChF,MAAM,OAAO,GAAG,EAAE,CAAC,MAAM,IAAI,EAAE,CAAC,cAAc,KAAK,OAAO,CAAC;IAC3D,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IAE7D,IAAI,SAAS,CAAC,OAAO,KAAK,OAAO;QAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC1F,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC;QACd,sFAAsF;QACtF,IAAI,EAAE,CAAC,aAAa,KAAK,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG;YAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,qBAAqB,EAAE,CAAC;QACpH,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IAC5D,CAAC;IACD,IAAI,KAAK,KAAK,MAAM;QAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IACvE,IAAI,KAAK,KAAK,KAAK;QAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IACxE,IAAI,CAAC,EAAE,CAAC,iBAAiB;QAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;IACnG,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAClD,CAAC"}