@agntcms/next 0.2.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.
@@ -0,0 +1,330 @@
1
+ import { C as ContentStorageAdapter, A as AssetStorageAdapter } from './assets-Cyt9upqW.cjs';
2
+ import { l as Runtime, R as RateLimit } from './rateLimit-CiROGTLE.cjs';
3
+ import { A as AnyFormDefinition, o as SubmissionStorageAdapter } from './form-BqY0H1V5.cjs';
4
+ import './global-CV23g5Bn.cjs';
5
+
6
+ type TaskId = string;
7
+ interface Task {
8
+ readonly id: TaskId;
9
+ readonly type: string;
10
+ readonly payload: unknown;
11
+ }
12
+ type TaskResult = unknown;
13
+ type TaskState = 'pending' | 'in_progress' | 'completed' | 'failed';
14
+ type TaskEvent = {
15
+ readonly kind: 'progress';
16
+ readonly message: string;
17
+ } | {
18
+ readonly kind: 'completed';
19
+ readonly result: TaskResult;
20
+ } | {
21
+ readonly kind: 'failed';
22
+ readonly error: string;
23
+ };
24
+ interface TaskSnapshot {
25
+ readonly id: TaskId;
26
+ readonly type: string;
27
+ readonly state: TaskState;
28
+ readonly result?: TaskResult;
29
+ readonly error?: string;
30
+ }
31
+ type TaskEventListener = (event: TaskEvent) => void;
32
+ type Unsubscribe = () => void;
33
+ interface TaskStore {
34
+ readonly create: (task: Task) => Promise<TaskResult>;
35
+ readonly get: (id: TaskId) => TaskSnapshot | undefined;
36
+ readonly progress: (id: TaskId, message: string) => void;
37
+ readonly complete: (id: TaskId, result: TaskResult) => void;
38
+ readonly fail: (id: TaskId, error: string) => void;
39
+ readonly subscribe: (id: TaskId, listener: TaskEventListener) => Unsubscribe;
40
+ }
41
+
42
+ declare const createTaskStore: () => TaskStore;
43
+
44
+ type AgentBridgeStatus = 'stopped' | 'starting' | 'running' | 'failed';
45
+ /**
46
+ * Typed error subclass thrown when `pushTask` is called against a bridge
47
+ * that is not in the 'running' state, or when `start()` fails the health
48
+ * check. The handler layer discriminates on this class to choose a 503
49
+ * vs 500 HTTP status.
50
+ */
51
+ declare class AgentUnreachableError extends Error {
52
+ readonly name = "AgentUnreachableError";
53
+ readonly status: AgentBridgeStatus;
54
+ constructor(message: string, status: AgentBridgeStatus);
55
+ }
56
+ interface AgentBridge {
57
+ /**
58
+ * Health-checks the channel server. Idempotent: calling it twice on a
59
+ * started bridge returns the same promise (so concurrent callers
60
+ * converge on a single check). Calling it after `stop()` re-starts.
61
+ */
62
+ readonly start: () => Promise<void>;
63
+ /**
64
+ * Registers `task` with the injected task store, then fires an HTTP
65
+ * POST to the channel server. The returned promise IS the store's
66
+ * promise: it resolves when the channel server POSTs back a
67
+ * `task_callback` with event 'completed'.
68
+ *
69
+ * Rejects with `AgentUnreachableError` if the bridge is not 'running'.
70
+ */
71
+ readonly pushTask: (task: Task) => Promise<TaskResult>;
72
+ /**
73
+ * Fails all inflight tasks. Idempotent. Safe to call before `start`,
74
+ * during `start`, after `start` succeeds, and after failure. Never
75
+ * throws.
76
+ */
77
+ readonly stop: () => Promise<void>;
78
+ /**
79
+ * Synchronous status getter. Handlers call this to emit 503-style
80
+ * errors without having to await a round-trip to the bridge.
81
+ */
82
+ readonly status: () => AgentBridgeStatus;
83
+ }
84
+ interface CreateAgentBridgeOptions {
85
+ readonly taskStore: TaskStore;
86
+ /** Port the channel server listens on. Defaults to 4819. */
87
+ readonly channelPort?: number;
88
+ /** Host the channel server listens on. Defaults to '127.0.0.1'. */
89
+ readonly channelHost?: string;
90
+ /** Callback URL the channel server will POST results to. Defaults to 'http://localhost:3000/api/agntcms/mcp'. */
91
+ readonly callbackUrl?: string;
92
+ /**
93
+ * How long to wait, after the HTTP POST to the channel server has
94
+ * returned 200, for the agent to acknowledge via `report_task_progress`
95
+ * or `report_task_done` before failing the task with
96
+ * `TASK_ACK_TIMEOUT_MESSAGE`. Default 15000 ms.
97
+ *
98
+ * Set to 0 to disable the watchdog (useful for tests that drive the
99
+ * store manually).
100
+ *
101
+ * Once any progress or terminal event has been seen, the watchdog is
102
+ * considered satisfied and is not re-armed. The agent owns the
103
+ * long-tail timing after that point.
104
+ */
105
+ readonly taskAckTimeoutMs?: number;
106
+ /** Test seam: override fetch for HTTP calls. */
107
+ readonly fetch?: typeof globalThis.fetch;
108
+ /**
109
+ * Test seams for the watchdog timer. When `taskAckTimeoutMs > 0`, the
110
+ * bridge calls `setTimeoutFn(callback, ms)` and `clearTimeoutFn(handle)`
111
+ * to drive the watchdog. Defaults to the global `setTimeout` /
112
+ * `clearTimeout`.
113
+ */
114
+ readonly setTimeoutFn?: (cb: () => void, ms: number) => unknown;
115
+ readonly clearTimeoutFn?: (handle: unknown) => void;
116
+ }
117
+ /**
118
+ * Primary factory. See file header for design notes.
119
+ */
120
+ declare const createAgentBridge: (options: CreateAgentBridgeOptions) => AgentBridge;
121
+
122
+ interface McpHandlerDeps {
123
+ readonly bridge: AgentBridge;
124
+ readonly taskStore: TaskStore;
125
+ }
126
+ interface McpHandler {
127
+ readonly POST: (req: Request) => Promise<Response>;
128
+ }
129
+ declare const createMcpHandler: (deps: McpHandlerDeps) => McpHandler;
130
+
131
+ interface EventsHandlerDeps {
132
+ readonly taskStore: TaskStore;
133
+ }
134
+ interface EventsHandler {
135
+ readonly GET: (req: Request) => Response;
136
+ }
137
+ declare const createEventsHandler: (deps: EventsHandlerDeps) => EventsHandler;
138
+
139
+ interface PreviewToken {
140
+ readonly token: string;
141
+ readonly slug: string;
142
+ readonly createdAt: number;
143
+ }
144
+ interface PreviewTokenStoreOptions {
145
+ /** Time-to-live in milliseconds. Defaults to 600_000 (10 minutes). */
146
+ readonly ttlMs?: number;
147
+ }
148
+ interface PreviewTokenStore {
149
+ /** Issue a new single-use preview token for the given slug. */
150
+ readonly issue: (slug: string) => PreviewToken;
151
+ /**
152
+ * Consume a token. Returns the associated slug if the token exists and
153
+ * has not expired; returns `null` otherwise. A consumed token is deleted
154
+ * and cannot be reused.
155
+ */
156
+ readonly consume: (token: string) => string | null;
157
+ }
158
+
159
+ declare const createPreviewTokenStore: (options?: PreviewTokenStoreOptions) => PreviewTokenStore;
160
+
161
+ interface PreviewHandlerDeps {
162
+ /** Cookie name used for preview mode flag. Default: '__agntcms_preview' */
163
+ readonly cookieName?: string;
164
+ /** Optional token store for single-use preview links. */
165
+ readonly tokenStore?: PreviewTokenStore;
166
+ }
167
+ interface PreviewHandler {
168
+ /** POST /api/agntcms/preview/enter -- enable preview mode */
169
+ readonly enter: (req: Request) => Response;
170
+ /** POST /api/agntcms/preview/exit -- disable preview mode */
171
+ readonly exit: (req: Request) => Response;
172
+ /** GET /api/agntcms/preview/enter?token=... -- token exchange + redirect */
173
+ readonly enterWithToken: (req: Request) => Response;
174
+ /** POST /api/agntcms/preview/token -- issue a single-use preview token */
175
+ readonly issueToken: (req: Request) => Promise<Response>;
176
+ }
177
+ declare function createPreviewHandler(deps?: PreviewHandlerDeps): PreviewHandler;
178
+
179
+ interface DraftHandlerDeps {
180
+ readonly contentAdapter: ContentStorageAdapter;
181
+ readonly runtime: Runtime;
182
+ }
183
+ interface DraftHandler {
184
+ /** POST /api/agntcms/draft/save -- save a draft page */
185
+ readonly save: (req: Request) => Promise<Response>;
186
+ /** GET /api/agntcms/draft/list -- list all drafts */
187
+ readonly list: (req: Request) => Promise<Response>;
188
+ /** POST /api/agntcms/draft/publish -- publish a draft */
189
+ readonly publish: (req: Request) => Promise<Response>;
190
+ /** POST /api/agntcms/draft/reorder -- reorder sections within a draft */
191
+ readonly reorder: (req: Request) => Promise<Response>;
192
+ /** POST /api/agntcms/draft/discard -- delete a draft (published version must exist) */
193
+ readonly discard: (req: Request) => Promise<Response>;
194
+ }
195
+ declare function createDraftHandler(deps: DraftHandlerDeps): DraftHandler;
196
+
197
+ interface AssetsHandlerDeps {
198
+ readonly assetAdapter: AssetStorageAdapter;
199
+ }
200
+ interface AssetsHandler {
201
+ /** GET /api/agntcms/assets -- list every asset (newest first) */
202
+ readonly list: (req: Request) => Promise<Response>;
203
+ /** POST /api/agntcms/assets -- upload bytes */
204
+ readonly upload: (req: Request) => Promise<Response>;
205
+ }
206
+ declare function createAssetsHandler(deps: AssetsHandlerDeps): AssetsHandler;
207
+
208
+ interface PageHandlerDeps {
209
+ readonly contentAdapter: ContentStorageAdapter;
210
+ /**
211
+ * Runtime instance. Required: `rollback` saves a draft then republishes
212
+ * it via `runtime.publishDraft`, and the `tag/limit/sort` mode of `list`
213
+ * routes through `runtime.listPages`. Both code paths are part of the
214
+ * public surface, so the type forbids constructing the handler without
215
+ * it. Template route files (frozen zone) all wire it in.
216
+ */
217
+ readonly runtime: Runtime;
218
+ }
219
+ interface PageHandler {
220
+ readonly list: (req: Request) => Promise<Response>;
221
+ readonly read: (req: Request) => Promise<Response>;
222
+ readonly deletePage: (req: Request) => Promise<Response>;
223
+ readonly unpublish: (req: Request) => Promise<Response>;
224
+ readonly listHistory: (req: Request) => Promise<Response>;
225
+ readonly rollback: (req: Request) => Promise<Response>;
226
+ readonly rename: (req: Request) => Promise<Response>;
227
+ /** POST /api/agntcms/page/duplicate -- clone a page under a new slug as a draft */
228
+ readonly duplicate: (req: Request) => Promise<Response>;
229
+ }
230
+ declare function createPageHandler(deps: PageHandlerDeps): PageHandler;
231
+
232
+ interface GlobalHandlerDeps {
233
+ readonly contentAdapter: ContentStorageAdapter;
234
+ /** When provided, `save` rejects types not in this set with 400 `unknown_type`. */
235
+ readonly allowedTypes?: ReadonlySet<string>;
236
+ /** Pre-resolved section defaults. When provided, the save handler fills
237
+ * missing fields in global data with these defaults so that a freshly
238
+ * created global (with `data: {}`) starts with valid placeholder values
239
+ * instead of crashing the section component at render time. */
240
+ readonly sectionDefaults?: ReadonlyMap<string, Readonly<Record<string, unknown>>>;
241
+ }
242
+ interface GlobalHandler {
243
+ /** GET /api/agntcms/global/list */
244
+ readonly list: (req: Request) => Promise<Response>;
245
+ /** GET /api/agntcms/global/read?name=xxx */
246
+ readonly read: (req: Request) => Promise<Response>;
247
+ /** POST /api/agntcms/global/save */
248
+ readonly save: (req: Request) => Promise<Response>;
249
+ /** POST /api/agntcms/global/delete */
250
+ readonly delete: (req: Request) => Promise<Response>;
251
+ /**
252
+ * GET /api/agntcms/global/history?name=xxx[&ts=...]
253
+ *
254
+ * Without `ts`: returns the list of history entries for the global.
255
+ * With `ts`: returns the full body of the matching single snapshot.
256
+ * Mirrors the page handler's `listHistory`/?ts= behaviour exactly.
257
+ */
258
+ readonly listHistory: (req: Request) => Promise<Response>;
259
+ /** POST /api/agntcms/global/rollback — body: { name, timestamp } */
260
+ readonly rollback: (req: Request) => Promise<Response>;
261
+ }
262
+ declare function createGlobalHandler(deps: GlobalHandlerDeps): GlobalHandler;
263
+
264
+ /**
265
+ * Template definition shape matching `PageTemplate` from config.
266
+ * Redeclared here as a structural type so the handler does not import
267
+ * from config/ (invariant 1).
268
+ */
269
+ interface TemplateDef {
270
+ readonly name: string;
271
+ readonly description?: string;
272
+ readonly sectionTypes: readonly string[];
273
+ }
274
+ interface TemplateHandlerDeps {
275
+ /**
276
+ * Pre-resolved map: section type name -> default data for that section.
277
+ * Built by the wiring layer from the registered `AnySectionDefinition[]`.
278
+ */
279
+ readonly sectionDefaults: ReadonlyMap<string, Readonly<Record<string, unknown>>>;
280
+ /** The template definitions from config. */
281
+ readonly templates: readonly TemplateDef[];
282
+ }
283
+ interface TemplateHandler {
284
+ /** GET /api/agntcms/template/list */
285
+ readonly list: (req: Request) => Promise<Response>;
286
+ }
287
+ declare function createTemplateHandler(deps: TemplateHandlerDeps): TemplateHandler;
288
+
289
+ interface SubmitHandlerDeps {
290
+ readonly runtime: Runtime;
291
+ readonly rateLimit: RateLimit;
292
+ }
293
+ declare function createSubmitFormHandler(deps: SubmitHandlerDeps): (req: Request) => Promise<Response>;
294
+
295
+ /**
296
+ * Adapter info surfaced to the AdminModal. Two shapes:
297
+ * - `{ kind: 'fs' }` — local FS submissions; readable.
298
+ * - `{ kind: 'webhook', host }` — webhook adapter; not locally readable.
299
+ */
300
+ type FormsListAdapterInfo = {
301
+ readonly kind: 'fs';
302
+ } | {
303
+ readonly kind: 'webhook';
304
+ readonly host: string;
305
+ };
306
+ interface FormsListHandlerDeps {
307
+ /** Registered form definitions (from `defineConfig({ forms: [...] })`). */
308
+ readonly forms: ReadonlyArray<AnyFormDefinition>;
309
+ /**
310
+ * Optional adapter descriptor. When omitted, the handler reports
311
+ * `{ kind: 'fs' }` — the v1 default adapter (ARCHITECTURE.md §6.5).
312
+ * Frozen routes that wire a webhook adapter pass `{ kind: 'webhook',
313
+ * host: '<host>' }` here; the host is computed once at handler-construction
314
+ * time from the configured webhook URL.
315
+ */
316
+ readonly adapter?: FormsListAdapterInfo;
317
+ }
318
+ /** Forms list handler. */
319
+ declare function createFormsListHandler(deps: FormsListHandlerDeps): (_req: Request) => Promise<Response>;
320
+
321
+ interface FormsReadHandlerDeps {
322
+ readonly submissionAdapter: SubmissionStorageAdapter;
323
+ /** Registered form names — used to 404 unknown forms before hitting the adapter. */
324
+ readonly knownForms: ReadonlySet<string>;
325
+ }
326
+ declare function createFormsReadHandler(deps: FormsReadHandlerDeps): (req: Request) => Promise<Response>;
327
+
328
+ declare function createFormsDeleteHandler(): (_req: Request) => Promise<Response>;
329
+
330
+ export { type AgentBridge, type AgentBridgeStatus, AgentUnreachableError, type AssetsHandler, type AssetsHandlerDeps, type CreateAgentBridgeOptions, type DraftHandler, type DraftHandlerDeps, type EventsHandler, type EventsHandlerDeps, type FormsListAdapterInfo, type FormsListHandlerDeps, type FormsReadHandlerDeps, type GlobalHandler, type GlobalHandlerDeps, type McpHandler, type McpHandlerDeps, type PageHandler, type PageHandlerDeps, type PreviewHandler, type PreviewHandlerDeps, type PreviewToken, type PreviewTokenStore, type PreviewTokenStoreOptions, type SubmitHandlerDeps, type Task, type TaskEvent, type TaskId, type TaskSnapshot, type TaskState, type TaskStore, type TemplateHandler, type TemplateHandlerDeps, createAgentBridge, createAssetsHandler, createDraftHandler, createEventsHandler, createFormsDeleteHandler, createFormsListHandler, createFormsReadHandler, createGlobalHandler, createMcpHandler, createPageHandler, createPreviewHandler, createPreviewTokenStore, createSubmitFormHandler, createTaskStore, createTemplateHandler };
@@ -0,0 +1,330 @@
1
+ import { C as ContentStorageAdapter, A as AssetStorageAdapter } from './assets-P8OCigDG.js';
2
+ import { l as Runtime, R as RateLimit } from './rateLimit-CXptRM_K.js';
3
+ import { A as AnyFormDefinition, o as SubmissionStorageAdapter } from './form-BqY0H1V5.js';
4
+ import './global-CV23g5Bn.js';
5
+
6
+ type TaskId = string;
7
+ interface Task {
8
+ readonly id: TaskId;
9
+ readonly type: string;
10
+ readonly payload: unknown;
11
+ }
12
+ type TaskResult = unknown;
13
+ type TaskState = 'pending' | 'in_progress' | 'completed' | 'failed';
14
+ type TaskEvent = {
15
+ readonly kind: 'progress';
16
+ readonly message: string;
17
+ } | {
18
+ readonly kind: 'completed';
19
+ readonly result: TaskResult;
20
+ } | {
21
+ readonly kind: 'failed';
22
+ readonly error: string;
23
+ };
24
+ interface TaskSnapshot {
25
+ readonly id: TaskId;
26
+ readonly type: string;
27
+ readonly state: TaskState;
28
+ readonly result?: TaskResult;
29
+ readonly error?: string;
30
+ }
31
+ type TaskEventListener = (event: TaskEvent) => void;
32
+ type Unsubscribe = () => void;
33
+ interface TaskStore {
34
+ readonly create: (task: Task) => Promise<TaskResult>;
35
+ readonly get: (id: TaskId) => TaskSnapshot | undefined;
36
+ readonly progress: (id: TaskId, message: string) => void;
37
+ readonly complete: (id: TaskId, result: TaskResult) => void;
38
+ readonly fail: (id: TaskId, error: string) => void;
39
+ readonly subscribe: (id: TaskId, listener: TaskEventListener) => Unsubscribe;
40
+ }
41
+
42
+ declare const createTaskStore: () => TaskStore;
43
+
44
+ type AgentBridgeStatus = 'stopped' | 'starting' | 'running' | 'failed';
45
+ /**
46
+ * Typed error subclass thrown when `pushTask` is called against a bridge
47
+ * that is not in the 'running' state, or when `start()` fails the health
48
+ * check. The handler layer discriminates on this class to choose a 503
49
+ * vs 500 HTTP status.
50
+ */
51
+ declare class AgentUnreachableError extends Error {
52
+ readonly name = "AgentUnreachableError";
53
+ readonly status: AgentBridgeStatus;
54
+ constructor(message: string, status: AgentBridgeStatus);
55
+ }
56
+ interface AgentBridge {
57
+ /**
58
+ * Health-checks the channel server. Idempotent: calling it twice on a
59
+ * started bridge returns the same promise (so concurrent callers
60
+ * converge on a single check). Calling it after `stop()` re-starts.
61
+ */
62
+ readonly start: () => Promise<void>;
63
+ /**
64
+ * Registers `task` with the injected task store, then fires an HTTP
65
+ * POST to the channel server. The returned promise IS the store's
66
+ * promise: it resolves when the channel server POSTs back a
67
+ * `task_callback` with event 'completed'.
68
+ *
69
+ * Rejects with `AgentUnreachableError` if the bridge is not 'running'.
70
+ */
71
+ readonly pushTask: (task: Task) => Promise<TaskResult>;
72
+ /**
73
+ * Fails all inflight tasks. Idempotent. Safe to call before `start`,
74
+ * during `start`, after `start` succeeds, and after failure. Never
75
+ * throws.
76
+ */
77
+ readonly stop: () => Promise<void>;
78
+ /**
79
+ * Synchronous status getter. Handlers call this to emit 503-style
80
+ * errors without having to await a round-trip to the bridge.
81
+ */
82
+ readonly status: () => AgentBridgeStatus;
83
+ }
84
+ interface CreateAgentBridgeOptions {
85
+ readonly taskStore: TaskStore;
86
+ /** Port the channel server listens on. Defaults to 4819. */
87
+ readonly channelPort?: number;
88
+ /** Host the channel server listens on. Defaults to '127.0.0.1'. */
89
+ readonly channelHost?: string;
90
+ /** Callback URL the channel server will POST results to. Defaults to 'http://localhost:3000/api/agntcms/mcp'. */
91
+ readonly callbackUrl?: string;
92
+ /**
93
+ * How long to wait, after the HTTP POST to the channel server has
94
+ * returned 200, for the agent to acknowledge via `report_task_progress`
95
+ * or `report_task_done` before failing the task with
96
+ * `TASK_ACK_TIMEOUT_MESSAGE`. Default 15000 ms.
97
+ *
98
+ * Set to 0 to disable the watchdog (useful for tests that drive the
99
+ * store manually).
100
+ *
101
+ * Once any progress or terminal event has been seen, the watchdog is
102
+ * considered satisfied and is not re-armed. The agent owns the
103
+ * long-tail timing after that point.
104
+ */
105
+ readonly taskAckTimeoutMs?: number;
106
+ /** Test seam: override fetch for HTTP calls. */
107
+ readonly fetch?: typeof globalThis.fetch;
108
+ /**
109
+ * Test seams for the watchdog timer. When `taskAckTimeoutMs > 0`, the
110
+ * bridge calls `setTimeoutFn(callback, ms)` and `clearTimeoutFn(handle)`
111
+ * to drive the watchdog. Defaults to the global `setTimeout` /
112
+ * `clearTimeout`.
113
+ */
114
+ readonly setTimeoutFn?: (cb: () => void, ms: number) => unknown;
115
+ readonly clearTimeoutFn?: (handle: unknown) => void;
116
+ }
117
+ /**
118
+ * Primary factory. See file header for design notes.
119
+ */
120
+ declare const createAgentBridge: (options: CreateAgentBridgeOptions) => AgentBridge;
121
+
122
+ interface McpHandlerDeps {
123
+ readonly bridge: AgentBridge;
124
+ readonly taskStore: TaskStore;
125
+ }
126
+ interface McpHandler {
127
+ readonly POST: (req: Request) => Promise<Response>;
128
+ }
129
+ declare const createMcpHandler: (deps: McpHandlerDeps) => McpHandler;
130
+
131
+ interface EventsHandlerDeps {
132
+ readonly taskStore: TaskStore;
133
+ }
134
+ interface EventsHandler {
135
+ readonly GET: (req: Request) => Response;
136
+ }
137
+ declare const createEventsHandler: (deps: EventsHandlerDeps) => EventsHandler;
138
+
139
+ interface PreviewToken {
140
+ readonly token: string;
141
+ readonly slug: string;
142
+ readonly createdAt: number;
143
+ }
144
+ interface PreviewTokenStoreOptions {
145
+ /** Time-to-live in milliseconds. Defaults to 600_000 (10 minutes). */
146
+ readonly ttlMs?: number;
147
+ }
148
+ interface PreviewTokenStore {
149
+ /** Issue a new single-use preview token for the given slug. */
150
+ readonly issue: (slug: string) => PreviewToken;
151
+ /**
152
+ * Consume a token. Returns the associated slug if the token exists and
153
+ * has not expired; returns `null` otherwise. A consumed token is deleted
154
+ * and cannot be reused.
155
+ */
156
+ readonly consume: (token: string) => string | null;
157
+ }
158
+
159
+ declare const createPreviewTokenStore: (options?: PreviewTokenStoreOptions) => PreviewTokenStore;
160
+
161
+ interface PreviewHandlerDeps {
162
+ /** Cookie name used for preview mode flag. Default: '__agntcms_preview' */
163
+ readonly cookieName?: string;
164
+ /** Optional token store for single-use preview links. */
165
+ readonly tokenStore?: PreviewTokenStore;
166
+ }
167
+ interface PreviewHandler {
168
+ /** POST /api/agntcms/preview/enter -- enable preview mode */
169
+ readonly enter: (req: Request) => Response;
170
+ /** POST /api/agntcms/preview/exit -- disable preview mode */
171
+ readonly exit: (req: Request) => Response;
172
+ /** GET /api/agntcms/preview/enter?token=... -- token exchange + redirect */
173
+ readonly enterWithToken: (req: Request) => Response;
174
+ /** POST /api/agntcms/preview/token -- issue a single-use preview token */
175
+ readonly issueToken: (req: Request) => Promise<Response>;
176
+ }
177
+ declare function createPreviewHandler(deps?: PreviewHandlerDeps): PreviewHandler;
178
+
179
+ interface DraftHandlerDeps {
180
+ readonly contentAdapter: ContentStorageAdapter;
181
+ readonly runtime: Runtime;
182
+ }
183
+ interface DraftHandler {
184
+ /** POST /api/agntcms/draft/save -- save a draft page */
185
+ readonly save: (req: Request) => Promise<Response>;
186
+ /** GET /api/agntcms/draft/list -- list all drafts */
187
+ readonly list: (req: Request) => Promise<Response>;
188
+ /** POST /api/agntcms/draft/publish -- publish a draft */
189
+ readonly publish: (req: Request) => Promise<Response>;
190
+ /** POST /api/agntcms/draft/reorder -- reorder sections within a draft */
191
+ readonly reorder: (req: Request) => Promise<Response>;
192
+ /** POST /api/agntcms/draft/discard -- delete a draft (published version must exist) */
193
+ readonly discard: (req: Request) => Promise<Response>;
194
+ }
195
+ declare function createDraftHandler(deps: DraftHandlerDeps): DraftHandler;
196
+
197
+ interface AssetsHandlerDeps {
198
+ readonly assetAdapter: AssetStorageAdapter;
199
+ }
200
+ interface AssetsHandler {
201
+ /** GET /api/agntcms/assets -- list every asset (newest first) */
202
+ readonly list: (req: Request) => Promise<Response>;
203
+ /** POST /api/agntcms/assets -- upload bytes */
204
+ readonly upload: (req: Request) => Promise<Response>;
205
+ }
206
+ declare function createAssetsHandler(deps: AssetsHandlerDeps): AssetsHandler;
207
+
208
+ interface PageHandlerDeps {
209
+ readonly contentAdapter: ContentStorageAdapter;
210
+ /**
211
+ * Runtime instance. Required: `rollback` saves a draft then republishes
212
+ * it via `runtime.publishDraft`, and the `tag/limit/sort` mode of `list`
213
+ * routes through `runtime.listPages`. Both code paths are part of the
214
+ * public surface, so the type forbids constructing the handler without
215
+ * it. Template route files (frozen zone) all wire it in.
216
+ */
217
+ readonly runtime: Runtime;
218
+ }
219
+ interface PageHandler {
220
+ readonly list: (req: Request) => Promise<Response>;
221
+ readonly read: (req: Request) => Promise<Response>;
222
+ readonly deletePage: (req: Request) => Promise<Response>;
223
+ readonly unpublish: (req: Request) => Promise<Response>;
224
+ readonly listHistory: (req: Request) => Promise<Response>;
225
+ readonly rollback: (req: Request) => Promise<Response>;
226
+ readonly rename: (req: Request) => Promise<Response>;
227
+ /** POST /api/agntcms/page/duplicate -- clone a page under a new slug as a draft */
228
+ readonly duplicate: (req: Request) => Promise<Response>;
229
+ }
230
+ declare function createPageHandler(deps: PageHandlerDeps): PageHandler;
231
+
232
+ interface GlobalHandlerDeps {
233
+ readonly contentAdapter: ContentStorageAdapter;
234
+ /** When provided, `save` rejects types not in this set with 400 `unknown_type`. */
235
+ readonly allowedTypes?: ReadonlySet<string>;
236
+ /** Pre-resolved section defaults. When provided, the save handler fills
237
+ * missing fields in global data with these defaults so that a freshly
238
+ * created global (with `data: {}`) starts with valid placeholder values
239
+ * instead of crashing the section component at render time. */
240
+ readonly sectionDefaults?: ReadonlyMap<string, Readonly<Record<string, unknown>>>;
241
+ }
242
+ interface GlobalHandler {
243
+ /** GET /api/agntcms/global/list */
244
+ readonly list: (req: Request) => Promise<Response>;
245
+ /** GET /api/agntcms/global/read?name=xxx */
246
+ readonly read: (req: Request) => Promise<Response>;
247
+ /** POST /api/agntcms/global/save */
248
+ readonly save: (req: Request) => Promise<Response>;
249
+ /** POST /api/agntcms/global/delete */
250
+ readonly delete: (req: Request) => Promise<Response>;
251
+ /**
252
+ * GET /api/agntcms/global/history?name=xxx[&ts=...]
253
+ *
254
+ * Without `ts`: returns the list of history entries for the global.
255
+ * With `ts`: returns the full body of the matching single snapshot.
256
+ * Mirrors the page handler's `listHistory`/?ts= behaviour exactly.
257
+ */
258
+ readonly listHistory: (req: Request) => Promise<Response>;
259
+ /** POST /api/agntcms/global/rollback — body: { name, timestamp } */
260
+ readonly rollback: (req: Request) => Promise<Response>;
261
+ }
262
+ declare function createGlobalHandler(deps: GlobalHandlerDeps): GlobalHandler;
263
+
264
+ /**
265
+ * Template definition shape matching `PageTemplate` from config.
266
+ * Redeclared here as a structural type so the handler does not import
267
+ * from config/ (invariant 1).
268
+ */
269
+ interface TemplateDef {
270
+ readonly name: string;
271
+ readonly description?: string;
272
+ readonly sectionTypes: readonly string[];
273
+ }
274
+ interface TemplateHandlerDeps {
275
+ /**
276
+ * Pre-resolved map: section type name -> default data for that section.
277
+ * Built by the wiring layer from the registered `AnySectionDefinition[]`.
278
+ */
279
+ readonly sectionDefaults: ReadonlyMap<string, Readonly<Record<string, unknown>>>;
280
+ /** The template definitions from config. */
281
+ readonly templates: readonly TemplateDef[];
282
+ }
283
+ interface TemplateHandler {
284
+ /** GET /api/agntcms/template/list */
285
+ readonly list: (req: Request) => Promise<Response>;
286
+ }
287
+ declare function createTemplateHandler(deps: TemplateHandlerDeps): TemplateHandler;
288
+
289
+ interface SubmitHandlerDeps {
290
+ readonly runtime: Runtime;
291
+ readonly rateLimit: RateLimit;
292
+ }
293
+ declare function createSubmitFormHandler(deps: SubmitHandlerDeps): (req: Request) => Promise<Response>;
294
+
295
+ /**
296
+ * Adapter info surfaced to the AdminModal. Two shapes:
297
+ * - `{ kind: 'fs' }` — local FS submissions; readable.
298
+ * - `{ kind: 'webhook', host }` — webhook adapter; not locally readable.
299
+ */
300
+ type FormsListAdapterInfo = {
301
+ readonly kind: 'fs';
302
+ } | {
303
+ readonly kind: 'webhook';
304
+ readonly host: string;
305
+ };
306
+ interface FormsListHandlerDeps {
307
+ /** Registered form definitions (from `defineConfig({ forms: [...] })`). */
308
+ readonly forms: ReadonlyArray<AnyFormDefinition>;
309
+ /**
310
+ * Optional adapter descriptor. When omitted, the handler reports
311
+ * `{ kind: 'fs' }` — the v1 default adapter (ARCHITECTURE.md §6.5).
312
+ * Frozen routes that wire a webhook adapter pass `{ kind: 'webhook',
313
+ * host: '<host>' }` here; the host is computed once at handler-construction
314
+ * time from the configured webhook URL.
315
+ */
316
+ readonly adapter?: FormsListAdapterInfo;
317
+ }
318
+ /** Forms list handler. */
319
+ declare function createFormsListHandler(deps: FormsListHandlerDeps): (_req: Request) => Promise<Response>;
320
+
321
+ interface FormsReadHandlerDeps {
322
+ readonly submissionAdapter: SubmissionStorageAdapter;
323
+ /** Registered form names — used to 404 unknown forms before hitting the adapter. */
324
+ readonly knownForms: ReadonlySet<string>;
325
+ }
326
+ declare function createFormsReadHandler(deps: FormsReadHandlerDeps): (req: Request) => Promise<Response>;
327
+
328
+ declare function createFormsDeleteHandler(): (_req: Request) => Promise<Response>;
329
+
330
+ export { type AgentBridge, type AgentBridgeStatus, AgentUnreachableError, type AssetsHandler, type AssetsHandlerDeps, type CreateAgentBridgeOptions, type DraftHandler, type DraftHandlerDeps, type EventsHandler, type EventsHandlerDeps, type FormsListAdapterInfo, type FormsListHandlerDeps, type FormsReadHandlerDeps, type GlobalHandler, type GlobalHandlerDeps, type McpHandler, type McpHandlerDeps, type PageHandler, type PageHandlerDeps, type PreviewHandler, type PreviewHandlerDeps, type PreviewToken, type PreviewTokenStore, type PreviewTokenStoreOptions, type SubmitHandlerDeps, type Task, type TaskEvent, type TaskId, type TaskSnapshot, type TaskState, type TaskStore, type TemplateHandler, type TemplateHandlerDeps, createAgentBridge, createAssetsHandler, createDraftHandler, createEventsHandler, createFormsDeleteHandler, createFormsListHandler, createFormsReadHandler, createGlobalHandler, createMcpHandler, createPageHandler, createPreviewHandler, createPreviewTokenStore, createSubmitFormHandler, createTaskStore, createTemplateHandler };