@crossworks/client-types 0.232.133 → 0.232.140

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crossworks/client-types",
3
- "version": "0.232.133",
3
+ "version": "0.232.140",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -0,0 +1,229 @@
1
+ /**
2
+ * @mantle/client-types · agent-graph
3
+ *
4
+ * Skills, tools, tool groups and AI workers — the pieces an agent is
5
+ * assembled from.
6
+ *
7
+ * Split out of the 2548-line index.ts on 2026-09-02 (audit, tier 3) with the
8
+ * contents unchanged. index.ts re-exports every one of these, so the package's
9
+ * public surface is byte-identical — only the file a symbol lives in moved.
10
+ */
11
+
12
+ // ── Skills ────────────────────────────────────────────────────────────────────
13
+
14
+ /** A skill as returned by `GET /api/skills`. */
15
+ export interface SkillDTO {
16
+ id: string;
17
+ slug: string;
18
+ name: string;
19
+ description: string;
20
+ instructions: string;
21
+ /** Template state heartbeats inherit on create. */
22
+ defaultState: Record<string, unknown>;
23
+ enabled: boolean;
24
+ createdAt: string;
25
+ updatedAt: string;
26
+ }
27
+
28
+ /** A heartbeat that references a skill — drives the "used by N heartbeats" badge. */
29
+ export interface HeartbeatRef {
30
+ slug: string;
31
+ name: string;
32
+ status: string;
33
+ }
34
+
35
+ /** `GET /api/skills/backrefs` — heartbeat refs keyed by skill slug. */
36
+ export type SkillBackrefs = Record<string, HeartbeatRef[]>;
37
+
38
+ // ── Tools ─────────────────────────────────────────────────────────────────────
39
+
40
+ /**
41
+ * Tool handler descriptor — the canonical wire shape. Mirrors @mantle/db's
42
+ * `ToolHandler` union; kept standalone here so this package stays zero-dep (no
43
+ * postgres type graph). Drift is caught where it matters: `@mantle/tools` aliases
44
+ * `ToolSummary = ToolDTO`, so if db's union ever diverges from this one, that
45
+ * package fails to compile.
46
+ */
47
+ export interface RecipeStep {
48
+ tool: string;
49
+ input?: Record<string, unknown>;
50
+ as?: string;
51
+ }
52
+
53
+ export type ToolHandler =
54
+ | { kind: 'builtin'; ref: string }
55
+ | {
56
+ kind: 'http';
57
+ url: string;
58
+ method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
59
+ headers?: Record<string, string>;
60
+ query?: Record<string, string>;
61
+ body?: string | null;
62
+ headersRef?: string | null;
63
+ authRef?: string | null;
64
+ timeoutMs?: number;
65
+ /** Provenance on rows materialised by an OpenAPI connector's sync. */
66
+ openapi?: { group: string; op: string; vanishedAt?: string; editedAt?: string };
67
+ }
68
+ | { kind: 'shell'; cmd: string }
69
+ | { kind: 'mcp'; group: string; toolName: string; vanishedAt?: string }
70
+ | { kind: 'recipe'; steps: RecipeStep[]; output?: unknown };
71
+
72
+ /** A tool as returned by `GET /api/tools`. */
73
+ export interface ToolDTO {
74
+ id: string;
75
+ slug: string;
76
+ name: string;
77
+ description: string;
78
+ inputSchema: Record<string, unknown>;
79
+ handler: ToolHandler;
80
+ requiresConfirm: boolean;
81
+ enabled: boolean;
82
+ createdAt: string;
83
+ updatedAt: string;
84
+ }
85
+
86
+ /** `GET/PUT /api/tools/settings` — the two owner-level tool policy toggles. */
87
+ export interface ToolSettings {
88
+ /** Tools an agent authors (Toolsmith) start confirm-gated until cleared. */
89
+ requireApproval: boolean;
90
+ /** Unattended heartbeats park email/web calls for approval. */
91
+ egressGate: boolean;
92
+ }
93
+
94
+ // ── Tool groups ───────────────────────────────────────────────────────────────
95
+
96
+ /**
97
+ * The service binding on a group that IS an API integration: where its calls go,
98
+ * which vault entry authenticates them, where that credential is placed, and
99
+ * pointers to the stored API docs + usage skill. Mirrors the `ToolGroupIntegration`
100
+ * type in @mantle/db. `secretRef` is a `service/label` pointer and auth-template
101
+ * values are `{{secret:…}}` refs — a plaintext key never crosses this wire.
102
+ */
103
+ export interface ToolGroupIntegrationDTO {
104
+ service: string;
105
+ baseUrl?: string;
106
+ secretRef?: string;
107
+ authTemplate?: {
108
+ headers?: Record<string, string>;
109
+ query?: Record<string, string>;
110
+ };
111
+ docsNodeId?: string;
112
+ docsSourceUrl?: string;
113
+ docsUpdatedAt?: string;
114
+ /** Slug of the usage skill that travels with this group's grant. */
115
+ skillSlug?: string;
116
+ /** Set when the group is an MCP CONNECTOR — a mirror of an external MCP
117
+ * server's tools. `secretRef` is a `service/label` vault pointer; the
118
+ * sync-bookkeeping fields are written by the connector sync. */
119
+ mcp?: {
120
+ url: string;
121
+ secretRef?: string;
122
+ authHeader?: string;
123
+ authScheme?: string;
124
+ /** OAuth bookkeeping when the server uses the MCP auth flow. Tokens and
125
+ * the client registration are vault-sealed and never cross this wire. */
126
+ oauth?: {
127
+ enabled: true;
128
+ status: 'pending' | 'connected' | 'needs_reconnect';
129
+ clientId?: string;
130
+ pending?: { state: string; redirectUri: string; startedAt: string };
131
+ redirectUri?: string;
132
+ tokenExpiresAt?: string;
133
+ connectedAt?: string;
134
+ lastError?: string;
135
+ };
136
+ lastSyncAt?: string;
137
+ toolCount?: number;
138
+ serverInfo?: { name?: string; version?: string };
139
+ };
140
+ /** Set when the group is an OPENAPI CONNECTOR — its operations are compiled
141
+ * into ordinary http tools by the connector sync. Auth stays on the
142
+ * surrounding integration fields (`baseUrl`/`secretRef`/`authTemplate`),
143
+ * never in this block; the sync-bookkeeping fields are written by the sync. */
144
+ openapi?: {
145
+ specUrl: string;
146
+ specHash?: string;
147
+ selection?: { tags?: string[]; operations?: string[] };
148
+ apiTitle?: string;
149
+ apiVersion?: string;
150
+ lastSyncAt?: string;
151
+ toolCount?: number;
152
+ };
153
+ }
154
+
155
+ /** A tool group — a named bundle of tool slugs granted to agents wholesale. */
156
+ export interface ToolGroupDTO {
157
+ id: string;
158
+ slug: string;
159
+ name: string;
160
+ description: string;
161
+ toolSlugs: string[];
162
+ /** Set when the group is an API integration; null for capability-only bundles. */
163
+ integration: ToolGroupIntegrationDTO | null;
164
+ enabled: boolean;
165
+ createdAt: string;
166
+ updatedAt: string;
167
+ }
168
+
169
+ /** `GET /api/tool-groups` — each group plus which agent slugs grant it. */
170
+ export interface ToolGroupWithRefs extends ToolGroupDTO {
171
+ grantedTo: string[];
172
+ }
173
+
174
+ // ── AI workers ────────────────────────────────────────────────────────────────
175
+
176
+ /** Worker kinds (mirrors the @mantle/db `ai_worker_kind` enum). Drift is caught
177
+ * by `toAiWorkerDTO` in lib/ai-workers, whose mapping won't compile if the db
178
+ * enum gains/renames a value. */
179
+ export type AiWorkerKind =
180
+ | 'reflector'
181
+ | 'extractor'
182
+ | 'summarizer'
183
+ | 'tts'
184
+ | 'stt'
185
+ | 'vision'
186
+ | 'document'
187
+ | 'image_gen'
188
+ | 'embedding'
189
+ | 'search'
190
+ | 'search_advanced'
191
+ | 'narrator'
192
+ | 'suggester';
193
+
194
+ /** An AI worker as returned by `GET /api/ai-workers`. `params` is jsonb (shape
195
+ * varies by kind) — kept loose here; the form narrows per kind. */
196
+ export interface AiWorkerDTO {
197
+ id: string;
198
+ slug: string;
199
+ name: string;
200
+ kind: AiWorkerKind;
201
+ provider: string;
202
+ model: string;
203
+ apiKeyId: string | null;
204
+ systemPrompt: string | null;
205
+ params: Record<string, unknown>;
206
+ enabled: boolean;
207
+ priority: number;
208
+ isDefault: boolean;
209
+ backupProvider: string | null;
210
+ backupModel: string | null;
211
+ backupApiKeyId: string | null;
212
+ backupEnabled: boolean;
213
+ baseUrl: string | null;
214
+ viaTailnet: boolean;
215
+ backupBaseUrl: string | null;
216
+ backupViaTailnet: boolean;
217
+ usageCount: number;
218
+ lastUsedAt: string | null;
219
+ createdAt: string;
220
+ updatedAt: string;
221
+ }
222
+
223
+ /** `GET /api/ai-workers/config` — static-ish bits the worker form needs. */
224
+ export interface AiWorkerConfig {
225
+ /** Providers with a native-PDF document adapter (vs. rasterize-at-ingest). */
226
+ nativeDocProviders: string[];
227
+ /** Online tailnet peer MagicDNS names (route base-URL datalist). */
228
+ tailnetPeers: string[];
229
+ }
@@ -0,0 +1,190 @@
1
+ /**
2
+ * @mantle/client-types · agents
3
+ *
4
+ * Agents themselves: role, avatar, memory/params jsonb, persona notes and
5
+ * the experience readout.
6
+ *
7
+ * Split out of the 2548-line index.ts on 2026-09-02 (audit, tier 3) with the
8
+ * contents unchanged. index.ts re-exports every one of these, so the package's
9
+ * public surface is byte-identical — only the file a symbol lives in moved.
10
+ */
11
+
12
+ // ── Agents ────────────────────────────────────────────────────────────────────
13
+
14
+ /** Conversational + worker roles an agent row can carry. Mirrors the
15
+ * `agent_role` enum (`packages/db/src/schema/agents.ts`); the `/settings/agents`
16
+ * page only lists the conversational ones. */
17
+ export type AgentRole =
18
+ | 'assistant'
19
+ | 'responder'
20
+ | 'extractor'
21
+ | 'summarizer'
22
+ | 'reflector'
23
+ | 'custom'
24
+ // Runner-queue worker template (docs/runs.md) — never conversational.
25
+ | 'worker';
26
+
27
+ /** Per-agent generated avatar (style + seed → DiceBear). null = initials. */
28
+ export interface AgentAvatarDTO {
29
+ style: string;
30
+ seed: string;
31
+ /** Avatar-builder component choices layered over the seed: component name →
32
+ * pinned variant, or null to hide an optional component. Stale entries
33
+ * (from another style) are ignored at render time.
34
+ *
35
+ * READ: absent = seed only. WRITE protocol (agents create/patch): an
36
+ * ABSENT parts key means "keep what's stored" — so a parts-unaware client
37
+ * can never wipe pins — `{}` is the explicit clear, and a non-empty map
38
+ * replaces. Every client that writes avatars must send `{}` to clear. */
39
+ parts?: Record<string, string | null>;
40
+ }
41
+
42
+ /** Memory/budget tuning (jsonb). All fields optional — empty = runtime defaults.
43
+ * Replicated standalone (NOT re-exported from @mantle/db) to keep this package
44
+ * zero-dep; the server aliases its `AgentMemoryConfig` against this so drift is
45
+ * a compile error. */
46
+ export interface AgentMemoryConfigDTO {
47
+ history_limit?: number;
48
+ history_window_hours?: number | null;
49
+ digest_limit?: number;
50
+ fact_limit?: number;
51
+ content_hit_limit?: number;
52
+ chunk_limit?: number;
53
+ inject_journal?: boolean;
54
+ inject_working_notes?: boolean;
55
+ summarize_threshold?: number;
56
+ summarize_batch?: number;
57
+ extract_types?: string[];
58
+ extract_facts?: boolean;
59
+ extract_cost_cap_micro_usd?: number | null;
60
+ delegate_to?: string[];
61
+ max_iterations?: number;
62
+ result_handling?: {
63
+ inline_max_kb?: number;
64
+ embed_min_kb?: number;
65
+ spill_max_kb?: number;
66
+ };
67
+ }
68
+
69
+ /** Sampling + voice-reply params (jsonb). */
70
+ export interface AgentParamsDTO {
71
+ temperature?: number;
72
+ max_tokens?: number;
73
+ top_p?: number;
74
+ max_retries?: number;
75
+ voice?: {
76
+ enabled?: boolean;
77
+ name?: 'alloy' | 'echo' | 'fable' | 'nova' | 'onyx' | 'shimmer';
78
+ model?: 'tts-1' | 'tts-1-hd';
79
+ speed?: number;
80
+ };
81
+ /** Propose a follow-up question after each completed turn (the suggester
82
+ * worker's chip above the chat composer). Absent/false = off. */
83
+ suggest_follow_up?: boolean;
84
+ }
85
+
86
+ /** One persona note (jsonb element). Soft-retired, never deleted — the read
87
+ * path filters `retiredAt`. `at`/`retiredAt` are ISO strings. */
88
+ export interface PersonaNoteDTO {
89
+ id?: string;
90
+ kind: 'style' | 'relationship' | 'correction';
91
+ content: string;
92
+ at: string;
93
+ source?: { type: 'turn' | 'digest'; id: string };
94
+ retiredAt?: string;
95
+ retiredReason?: 'superseded' | 'removed';
96
+ supersededBy?: string;
97
+ }
98
+
99
+ /** Raw counters behind an agent's experience level — always shipped next to
100
+ * the level so the UI can show WHY it is level N. All are lifetime counts for
101
+ * THIS brain (experience is per-brain, display-only — never a trust gate). */
102
+ export interface AgentExperienceComponentsDTO {
103
+ /** Completed conversation turns this agent answered on the assistant
104
+ * stream (web, Telegram, mobile). Team/forum turns live in a different
105
+ * store and are not counted (yet). */
106
+ turns: number;
107
+ /** Tool calls that succeeded across those turns. */
108
+ toolSuccesses: number;
109
+ /** Delegated runs this agent completed for other agents. */
110
+ delegations: number;
111
+ /** Heartbeat fires this agent completed. */
112
+ heartbeats: number;
113
+ }
114
+
115
+ /** An agent's experience readout — a soft-capped level derived from real
116
+ * accumulated usage (see `agent-experience.ts` server-side for the weights
117
+ * and curve). Computed at read time; nothing is stored. */
118
+ export interface AgentExperienceDTO {
119
+ level: number;
120
+ /** Total XP earned. */
121
+ xp: number;
122
+ /** Cumulative XP at which the current level began. */
123
+ levelXp: number;
124
+ /** Cumulative XP needed to reach the next level. */
125
+ nextLevelXp: number;
126
+ components: AgentExperienceComponentsDTO;
127
+ }
128
+
129
+ /** An agent as returned by `GET /api/agents` (and `…/[id]`). Dates are ISO
130
+ * strings. The server aliases its `AgentSummary` to this so the wire shape and
131
+ * the consuming client can't drift. */
132
+ export interface AgentDTO {
133
+ id: string;
134
+ slug: string;
135
+ name: string;
136
+ description: string | null;
137
+ role: AgentRole;
138
+ provider: string;
139
+ model: string;
140
+ apiKeyId: string | null;
141
+ backupProvider: string | null;
142
+ backupModel: string | null;
143
+ backupApiKeyId: string | null;
144
+ backupEnabled: boolean;
145
+ baseUrl: string | null;
146
+ viaTailnet: boolean;
147
+ backupBaseUrl: string | null;
148
+ backupViaTailnet: boolean;
149
+ ttsWorkerId: string | null;
150
+ systemPrompt: string;
151
+ skillSlugs: string[];
152
+ toolGroupSlugs: string[];
153
+ memoryConfig: AgentMemoryConfigDTO;
154
+ params: AgentParamsDTO;
155
+ avatar: AgentAvatarDTO | null;
156
+ personaNotes: PersonaNoteDTO[];
157
+ /** The co-admin login this agent is the personal assistant for (migration
158
+ * 0143), or null for a shared agent. Set, it becomes that login's default
159
+ * chat target — the mechanism that keeps two people typing at once out of
160
+ * one interleaved thread. Not a privacy boundary: every login still sees
161
+ * and can open every agent. */
162
+ assignedUserId: string | null;
163
+ /** ISO timestamp of the current assignment; null when unassigned. */
164
+ assignedAt: string | null;
165
+ priority: number;
166
+ enabled: boolean;
167
+ /** True when this agent ships from the system manifest (a def-synced
168
+ * specialist). Since 2026-07-29 only its params/memoryConfig tuning
169
+ * re-syncs on upgrade — prompt, model, provider and key are operator-owned
170
+ * and survive. Drives the "system" badge on the agents screens. */
171
+ manifestManaged: boolean;
172
+ lastUsedAt: string | null;
173
+ usageCount: number;
174
+ /** Experience readout (level + raw counters). Optional: filled on the list
175
+ * reads the agent screens use (`GET /api/agents`, the assistant thread
176
+ * bundle); absent on single-row CRUD echoes where computing it would cost
177
+ * extra queries for nothing. */
178
+ experience?: AgentExperienceDTO;
179
+ createdAt: string;
180
+ updatedAt: string;
181
+ }
182
+
183
+ /** A lightweight agent option (slug + name + role) for picker dropdowns —
184
+ * `GET /api/agents/options`. Unlike `GET /api/agents` (conversational roles
185
+ * only), this lists EVERY agent, so heartbeats can bind worker-role agents. */
186
+ export interface AgentOptionDTO {
187
+ slug: string;
188
+ name: string;
189
+ role: AgentRole;
190
+ }
@@ -0,0 +1,114 @@
1
+ /**
2
+ * @mantle/client-types · comms
3
+ *
4
+ * Calendar feeds, Microsoft drives and the email reading pane.
5
+ *
6
+ * Split out of the 2548-line index.ts on 2026-09-02 (audit, tier 3) with the
7
+ * contents unchanged. index.ts re-exports every one of these, so the package's
8
+ * public surface is byte-identical — only the file a symbol lives in moved.
9
+ */
10
+
11
+ // ── Calendar ────────────────────────────────────────────────────────────────────
12
+
13
+ /** A subscribed calendar feed as returned by `GET /api/calendar` — the wire
14
+ * projection of @mantle/db's `CalendarAccount` row. The sealed `feedUrlEnc`
15
+ * credential, `ownerId`, and `syncState` are server-only and intentionally
16
+ * omitted; dates are ISO strings. The route maps its rows to this so the wire
17
+ * shape and the consuming client can't drift. */
18
+ export interface CalendarAccountDTO {
19
+ id: string;
20
+ /** 'ics' (future: 'google' | 'microsoft'). */
21
+ provider: string;
22
+ displayName: string;
23
+ /** Optional UI accent (hex) so multiple calendars are distinguishable. */
24
+ color: string | null;
25
+ enabled: boolean;
26
+ lastEventCount: number | null;
27
+ lastSyncAt: string | null;
28
+ lastSyncError: string | null;
29
+ }
30
+
31
+ // ── Microsoft (SharePoint / OneDrive) ───────────────────────────────────────────
32
+
33
+ /** A discovered drive as returned by `GET/POST /api/microsoft/accounts/[id]/drives`
34
+ * — the wire projection of @mantle/db's `MsDrive` row. The Graph `deltaLink`
35
+ * cursor and `accountId` are server-only and omitted; `lastSyncAt` is an ISO
36
+ * string. The route maps its rows to this so the shapes can't drift. */
37
+ export interface MsDriveDTO {
38
+ id: string;
39
+ /** Graph drive id. */
40
+ driveId: string;
41
+ /** `personal` (OneDrive) | `documentLibrary` (SharePoint) | other. */
42
+ driveType: string;
43
+ name: string;
44
+ /** SharePoint site display name; null for OneDrive. */
45
+ siteName: string | null;
46
+ webUrl: string | null;
47
+ enabled: boolean;
48
+ lastSyncAt: string | null;
49
+ lastError: string | null;
50
+ /** How many scope selections the drive has; 0 = syncing everything. */
51
+ scopeCount: number;
52
+ }
53
+
54
+ /** One scope selection on a drive, as stored/returned by
55
+ * `GET/PUT /api/microsoft/drives/[id]/scopes`. Folder scopes include the
56
+ * whole subtree (path prefix); file scopes match that one item. */
57
+ export interface MsDriveScopeDTO {
58
+ itemId: string;
59
+ /** After-`root:` path, always starting with `/` (e.g. `/Reports/2026`). */
60
+ path: string;
61
+ isFolder: boolean;
62
+ name: string | null;
63
+ }
64
+
65
+ /** One row of a drive-folder listing from
66
+ * `GET /api/microsoft/drives/[id]/browse` — the scope picker's navigation
67
+ * unit. Selection state is client-derived by matching against the scope set. */
68
+ export interface MsDriveChildDTO {
69
+ itemId: string;
70
+ name: string;
71
+ isFolder: boolean;
72
+ childCount: number | null;
73
+ size: number | null;
74
+ path: string | null;
75
+ webUrl: string | null;
76
+ }
77
+
78
+ // ── Email (inbox reading pane) ──────────────────────────────────────────────────
79
+
80
+ /** One message as returned by `GET /api/email/messages/[id]` — the wire
81
+ * projection of @mantle/db's `Email` row, trimmed to what the reading pane
82
+ * renders. Server-only/sensitive columns are dropped: the raw `bodyHtml` (it's
83
+ * sanitized server-side into `MessageDetailDTO.bodyHtmlSafe` and must never
84
+ * cross the wire untrusted), plus account/node/provider ids, labels, snippet,
85
+ * etc. `internalDate` is an ISO string. */
86
+ export interface EmailDTO {
87
+ id: string;
88
+ subject: string | null;
89
+ fromAddr: string;
90
+ fromName: string | null;
91
+ toAddrs: string[];
92
+ ccAddrs: string[];
93
+ internalDate: string;
94
+ folder: string | null;
95
+ isRead: boolean;
96
+ isStarred: boolean;
97
+ bodyText: string | null;
98
+ }
99
+
100
+ /** One attachment row returned with a message. */
101
+ export interface EmailAttachmentDTO {
102
+ id: string;
103
+ filename: string;
104
+ mimeType: string | null;
105
+ sizeBytes: number | null;
106
+ }
107
+
108
+ /** `GET /api/email/messages/[id]` — a message, its attachments, and the
109
+ * server-sanitized HTML body (the raw `bodyHtml` never crosses the wire). */
110
+ export interface MessageDetailDTO {
111
+ email: EmailDTO;
112
+ attachments: EmailAttachmentDTO[];
113
+ bodyHtmlSafe: string | null;
114
+ }
@@ -0,0 +1,60 @@
1
+ /**
2
+ * @mantle/client-types · heartbeats
3
+ *
4
+ * Heartbeats — the brain on its own clock.
5
+ *
6
+ * Split out of the 2548-line index.ts on 2026-09-02 (audit, tier 3) with the
7
+ * contents unchanged. index.ts re-exports every one of these, so the package's
8
+ * public surface is byte-identical — only the file a symbol lives in moved.
9
+ */
10
+
11
+ // ── Heartbeats ─────────────────────────────────────────────────────────────────
12
+
13
+ /** A heartbeat's schedule (jsonb). `cron` is read-only in v1 (the form locks it);
14
+ * create/update only accept once/interval/manual. `at` is an ISO string. */
15
+ export type HeartbeatScheduleSpecDTO =
16
+ | { kind: 'once'; at: string }
17
+ | { kind: 'interval'; every_minutes: number; jitter_minutes?: number }
18
+ | { kind: 'cron'; expr: string }
19
+ | { kind: 'manual' };
20
+
21
+ /** Where a heartbeat's reply is delivered (jsonb). */
22
+ export type HeartbeatSurfaceDTO = { kind: 'telegram'; chat_id: string } | { kind: 'web' };
23
+
24
+ /** Optional quiet-hours window (jsonb). null tz = use the profile timezone. */
25
+ export interface HeartbeatQuietHoursDTO {
26
+ from: string;
27
+ to: string;
28
+ tz?: string | null;
29
+ }
30
+
31
+ /** A heartbeat as returned by `GET /api/heartbeats(/[id])`. Dates are ISO
32
+ * strings. The server aliases its `HeartbeatSummary` to this so the wire shape
33
+ * and the consuming client can't drift. */
34
+ /** Alias kept for the heartbeats settings screens (formerly @server/lib/heartbeats). */
35
+ export type HeartbeatSummary = HeartbeatDTO;
36
+
37
+ export interface HeartbeatDTO {
38
+ id: string;
39
+ slug: string;
40
+ name: string;
41
+ description: string | null;
42
+ agentSlug: string;
43
+ skillSlug: string;
44
+ scheduleKind: 'once' | 'interval' | 'cron' | 'manual';
45
+ schedule: HeartbeatScheduleSpecDTO;
46
+ surface: HeartbeatSurfaceDTO;
47
+ nextFireAt: string | null;
48
+ lastFiredAt: string | null;
49
+ fireCount: number;
50
+ maxFires: number | null;
51
+ minIdleMinutes: number | null;
52
+ quietHours: HeartbeatQuietHoursDTO | null;
53
+ earliestAt: string | null;
54
+ cooldownMinutes: number | null;
55
+ state: Record<string, unknown>;
56
+ status: 'active' | 'paused' | 'completed' | 'cancelled';
57
+ completionReason: string | null;
58
+ createdAt: string;
59
+ updatedAt: string;
60
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @mantle/client-types · recall
3
+ *
4
+ * Recall — the owner's memory maps.
5
+ *
6
+ * Split out of the 2548-line index.ts on 2026-09-02 (audit, tier 3) with the
7
+ * contents unchanged. index.ts re-exports every one of these, so the package's
8
+ * public surface is byte-identical — only the file a symbol lives in moved.
9
+ */
10
+
11
+ // ── Recall (memory maps) ─────────────────────────────────────────────────────
12
+
13
+ export type {
14
+ RecallLintIssueDTO,
15
+ RecallLintSeverity,
16
+ RecallMapDetailDTO,
17
+ RecallMapSummaryDTO,
18
+ RecallNodeDTO,
19
+ RecallOptionDTO,
20
+ RecallPageStateDTO,
21
+ } from '../types/recall';