@aitne/shared 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 (114) hide show
  1. package/LICENSE +21 -0
  2. package/dist/advisor-models.d.ts +34 -0
  3. package/dist/advisor-models.d.ts.map +1 -0
  4. package/dist/advisor-models.js +39 -0
  5. package/dist/advisor-models.js.map +1 -0
  6. package/dist/agent-identity.d.ts +11 -0
  7. package/dist/agent-identity.d.ts.map +1 -0
  8. package/dist/agent-identity.js +29 -0
  9. package/dist/agent-identity.js.map +1 -0
  10. package/dist/alerts.d.ts +44 -0
  11. package/dist/alerts.d.ts.map +1 -0
  12. package/dist/alerts.js +12 -0
  13. package/dist/alerts.js.map +1 -0
  14. package/dist/backend-api-key-config.d.ts +337 -0
  15. package/dist/backend-api-key-config.d.ts.map +1 -0
  16. package/dist/backend-api-key-config.js +682 -0
  17. package/dist/backend-api-key-config.js.map +1 -0
  18. package/dist/backend.d.ts +93 -0
  19. package/dist/backend.d.ts.map +1 -0
  20. package/dist/backend.js +22 -0
  21. package/dist/backend.js.map +1 -0
  22. package/dist/branding.d.ts +96 -0
  23. package/dist/branding.d.ts.map +1 -0
  24. package/dist/branding.js +102 -0
  25. package/dist/branding.js.map +1 -0
  26. package/dist/chat-session-scope.d.ts +14 -0
  27. package/dist/chat-session-scope.d.ts.map +1 -0
  28. package/dist/chat-session-scope.js +18 -0
  29. package/dist/chat-session-scope.js.map +1 -0
  30. package/dist/date-utils.d.ts +80 -0
  31. package/dist/date-utils.d.ts.map +1 -0
  32. package/dist/date-utils.js +187 -0
  33. package/dist/date-utils.js.map +1 -0
  34. package/dist/docs-frontmatter.d.ts +51 -0
  35. package/dist/docs-frontmatter.d.ts.map +1 -0
  36. package/dist/docs-frontmatter.js +184 -0
  37. package/dist/docs-frontmatter.js.map +1 -0
  38. package/dist/docs-schema.d.ts +79 -0
  39. package/dist/docs-schema.d.ts.map +1 -0
  40. package/dist/docs-schema.js +135 -0
  41. package/dist/docs-schema.js.map +1 -0
  42. package/dist/editable-config-keys.d.ts +14 -0
  43. package/dist/editable-config-keys.d.ts.map +1 -0
  44. package/dist/editable-config-keys.js +157 -0
  45. package/dist/editable-config-keys.js.map +1 -0
  46. package/dist/exec-with-stdin.d.ts +14 -0
  47. package/dist/exec-with-stdin.d.ts.map +1 -0
  48. package/dist/exec-with-stdin.js +35 -0
  49. package/dist/exec-with-stdin.js.map +1 -0
  50. package/dist/index.d.ts +37 -0
  51. package/dist/index.d.ts.map +1 -0
  52. package/dist/index.js +49 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/integrations-snapshot.d.ts +183 -0
  55. package/dist/integrations-snapshot.d.ts.map +1 -0
  56. package/dist/integrations-snapshot.js +757 -0
  57. package/dist/integrations-snapshot.js.map +1 -0
  58. package/dist/integrations.d.ts +675 -0
  59. package/dist/integrations.d.ts.map +1 -0
  60. package/dist/integrations.js +1656 -0
  61. package/dist/integrations.js.map +1 -0
  62. package/dist/keychain-helper-client.d.ts +31 -0
  63. package/dist/keychain-helper-client.d.ts.map +1 -0
  64. package/dist/keychain-helper-client.js +105 -0
  65. package/dist/keychain-helper-client.js.map +1 -0
  66. package/dist/log-entry.d.ts +14 -0
  67. package/dist/log-entry.d.ts.map +1 -0
  68. package/dist/log-entry.js +2 -0
  69. package/dist/log-entry.js.map +1 -0
  70. package/dist/management-domains.d.ts +369 -0
  71. package/dist/management-domains.d.ts.map +1 -0
  72. package/dist/management-domains.js +499 -0
  73. package/dist/management-domains.js.map +1 -0
  74. package/dist/process-key.d.ts +67 -0
  75. package/dist/process-key.d.ts.map +1 -0
  76. package/dist/process-key.js +366 -0
  77. package/dist/process-key.js.map +1 -0
  78. package/dist/schemas.d.ts +267 -0
  79. package/dist/schemas.d.ts.map +1 -0
  80. package/dist/schemas.js +271 -0
  81. package/dist/schemas.js.map +1 -0
  82. package/dist/secret-client-factory.d.ts +16 -0
  83. package/dist/secret-client-factory.d.ts.map +1 -0
  84. package/dist/secret-client-factory.js +111 -0
  85. package/dist/secret-client-factory.js.map +1 -0
  86. package/dist/secret-client-file.d.ts +51 -0
  87. package/dist/secret-client-file.d.ts.map +1 -0
  88. package/dist/secret-client-file.js +160 -0
  89. package/dist/secret-client-file.js.map +1 -0
  90. package/dist/secret-client-linux.d.ts +26 -0
  91. package/dist/secret-client-linux.d.ts.map +1 -0
  92. package/dist/secret-client-linux.js +63 -0
  93. package/dist/secret-client-linux.js.map +1 -0
  94. package/dist/secret-client-windows.d.ts +37 -0
  95. package/dist/secret-client-windows.d.ts.map +1 -0
  96. package/dist/secret-client-windows.js +82 -0
  97. package/dist/secret-client-windows.js.map +1 -0
  98. package/dist/secret-redaction.d.ts +3 -0
  99. package/dist/secret-redaction.d.ts.map +1 -0
  100. package/dist/secret-redaction.js +31 -0
  101. package/dist/secret-redaction.js.map +1 -0
  102. package/dist/skill-curation/decision-language.d.ts +6 -0
  103. package/dist/skill-curation/decision-language.d.ts.map +1 -0
  104. package/dist/skill-curation/decision-language.js +38 -0
  105. package/dist/skill-curation/decision-language.js.map +1 -0
  106. package/dist/skill-curation/schemas.d.ts +461 -0
  107. package/dist/skill-curation/schemas.d.ts.map +1 -0
  108. package/dist/skill-curation/schemas.js +211 -0
  109. package/dist/skill-curation/schemas.js.map +1 -0
  110. package/dist/types.d.ts +204 -0
  111. package/dist/types.d.ts.map +1 -0
  112. package/dist/types.js +54 -0
  113. package/dist/types.js.map +1 -0
  114. package/package.json +50 -0
@@ -0,0 +1,499 @@
1
+ import { z } from "zod";
2
+ import { recurrenceRuleSchema } from "./schemas.js";
3
+ /**
4
+ * Management Registry — shared types and validators.
5
+ *
6
+ * This module is the single source of truth for the four-layer management
7
+ * model defined in `docs/design/21-management-registry-and-entities.md`:
8
+ *
9
+ * - L1 — `rules/management.md` SoT bindings (Section A) and Managed
10
+ * Tasks (Section B).
11
+ * - L2 — Entity files at `context/<domain>/<type-plural>/<slug>.md`.
12
+ * - L3 — `context/_activity/<source>.md` (auto-generated).
13
+ * - L4 — `agent_actions` / `md_file_snapshots` (existing audit tables).
14
+ *
15
+ * Pure-logic only — no I/O, no DB access, no fs. Imported by the daemon
16
+ * (`api/routes/managed-tasks.ts`, `core/management-registry.ts`,
17
+ * `core/entity-mirror.ts`), the dashboard (Settings → Management page,
18
+ * entity browser), and skill prompts.
19
+ *
20
+ * 100% coverage is required (see `vitest.config.ts`'s curated set).
21
+ */
22
+ // ── Domains (§9.4) ────────────────────────────────────────────────────────
23
+ /**
24
+ * The fixed v1 domain enum (§8.8). Drives:
25
+ * - L2 directory layout (`context/<domain>/<type-plural>/<slug>.md`),
26
+ * - SoT-binding rows (Section A of management.md),
27
+ * - Managed-task `Output path` validation (§9.1 render rules),
28
+ * - dashboard navigation tabs.
29
+ *
30
+ * Custom user-defined domains are deferred to v4 (OQ-1). Adding a new
31
+ * value here is an additive change; removing one is a breaking change.
32
+ */
33
+ export const DOMAINS = [
34
+ "work",
35
+ "travel",
36
+ "finance",
37
+ "personal",
38
+ "health",
39
+ "learning",
40
+ ];
41
+ const DOMAIN_SET = new Set(DOMAINS);
42
+ export function isDomain(value) {
43
+ return typeof value === "string" && DOMAIN_SET.has(value);
44
+ }
45
+ // ── Entity types (§9.3) ───────────────────────────────────────────────────
46
+ /**
47
+ * The fixed v1 entity-type enum. Each `type` corresponds to exactly one
48
+ * directory name (the plural form). Adding a new type requires:
49
+ * 1. an entry here,
50
+ * 2. a `TYPE_PLURALS` entry,
51
+ * 3. an EntitySchema enum bump,
52
+ * 4. a dashboard tab if user-visible.
53
+ *
54
+ * Singular form is the canonical identifier (matches frontmatter `type`);
55
+ * the plural form is derived from `TYPE_PLURALS`.
56
+ */
57
+ export const ENTITY_TYPES = [
58
+ "meeting",
59
+ "trip",
60
+ "receipt",
61
+ "project",
62
+ "book",
63
+ "note",
64
+ ];
65
+ const ENTITY_TYPE_SET = new Set(ENTITY_TYPES);
66
+ export function isEntityType(value) {
67
+ return typeof value === "string" && ENTITY_TYPE_SET.has(value);
68
+ }
69
+ /**
70
+ * Singular → plural map. The plural form is the directory segment in
71
+ * L2 paths (`context/<domain>/<type-plural>/<slug>.md`). Static — no
72
+ * inflection library is used (§9.3).
73
+ */
74
+ export const TYPE_PLURALS = {
75
+ meeting: "meetings",
76
+ trip: "trips",
77
+ receipt: "receipts",
78
+ project: "projects",
79
+ book: "books",
80
+ note: "notes",
81
+ };
82
+ const PLURAL_TO_TYPE = new Map(ENTITY_TYPES.map((t) => [TYPE_PLURALS[t], t]));
83
+ export function typeToPlural(type) {
84
+ return TYPE_PLURALS[type];
85
+ }
86
+ export function pluralToType(plural) {
87
+ return PLURAL_TO_TYPE.get(plural) ?? null;
88
+ }
89
+ // ── Caps & limits (§13.2) ─────────────────────────────────────────────────
90
+ /** Max length of the user-typed `App` label rendered in management.md. */
91
+ export const APP_MAX_LENGTH = 64;
92
+ /** Max length of the `Intent` description on a managed task. */
93
+ export const INTENT_MAX_LENGTH = 200;
94
+ /** Max length of `last_result` (free text). */
95
+ export const LAST_RESULT_MAX_LENGTH = 120;
96
+ /** Default cap on active managed tasks (NFR-8); configurable. */
97
+ export const MANAGEMENT_MAX_ACTIVE_TASKS_DEFAULT = 100;
98
+ /** Soft warning threshold surfaced on the dashboard (§NFR-1a). */
99
+ export const MANAGEMENT_ACTIVE_TASKS_SOFT_WARNING = 30;
100
+ /** Default minimum cadence interval, in minutes (§13.2). */
101
+ export const MANAGEMENT_MIN_CADENCE_MINUTES_DEFAULT = 5;
102
+ /** Default consecutive-failure count before notifying the owner (§10.4). */
103
+ export const MANAGEMENT_FAILURE_NOTIFY_THRESHOLD_DEFAULT = 3;
104
+ // ── String validators (§13.3) ─────────────────────────────────────────────
105
+ const APP_FORBIDDEN_CHARS = /[\n\r|]/;
106
+ /**
107
+ * Trim, NFC-normalize, and validate a user-typed `App` label. Rejects
108
+ * empty input, newlines, and pipe characters (would break the rendered
109
+ * Markdown table). Returns `null` on rejection so callers can format
110
+ * the error in their context. The Zod schemas use `validateLabel`
111
+ * directly to surface a specific failure reason in the issue message.
112
+ */
113
+ export function validateAppLabel(value) {
114
+ const r = validateLabel(value, APP_MAX_LENGTH);
115
+ return r.ok ? r.value : null;
116
+ }
117
+ /**
118
+ * Lowercase + collapse-whitespace form used as the dedup key in
119
+ * `managed_tasks.app_normalized` (§9.2). Two visually-different inputs
120
+ * that map to the same normalized form are considered the same app
121
+ * for dedup purposes (§12 failure modes).
122
+ *
123
+ * Caller is expected to have run `validateAppLabel` first; this function
124
+ * is purely lexical and does not enforce length / forbidden-char caps.
125
+ */
126
+ export function normalizeAppLabel(value) {
127
+ return value.normalize("NFC").trim().toLowerCase().replace(/\s+/g, " ");
128
+ }
129
+ /**
130
+ * Trim, NFC-normalize, and validate a user-typed `Intent` description.
131
+ * Same rules as `validateAppLabel` but with `INTENT_MAX_LENGTH` cap.
132
+ */
133
+ export function validateIntent(value) {
134
+ const detailed = validateLabel(value, INTENT_MAX_LENGTH);
135
+ return detailed.ok ? detailed.value : null;
136
+ }
137
+ /** Internal — shared validator for app/intent/category labels. */
138
+ function validateLabel(value, max) {
139
+ const cleaned = value.normalize("NFC").trim();
140
+ if (!cleaned)
141
+ return { ok: false, reason: { kind: "empty" } };
142
+ if (cleaned.length > max)
143
+ return { ok: false, reason: { kind: "too-long", max } };
144
+ if (APP_FORBIDDEN_CHARS.test(cleaned))
145
+ return { ok: false, reason: { kind: "forbidden-char" } };
146
+ return { ok: true, value: cleaned };
147
+ }
148
+ function labelErrorMessage(field, reason) {
149
+ switch (reason.kind) {
150
+ case "empty":
151
+ return `${field} must not be empty after trimming`;
152
+ case "too-long":
153
+ return `${field} must be ≤ ${reason.max} chars`;
154
+ case "forbidden-char":
155
+ return `${field} must not contain newline or pipe characters`;
156
+ }
157
+ }
158
+ /**
159
+ * Build a Zod schema fragment that accepts a raw string, applies
160
+ * `validateLabel(field, max)`, and emits a specific issue on failure.
161
+ * Used by every public input schema that takes a user-typed label so the
162
+ * trim/NFC/forbidden-char invariants are enforced at the API boundary
163
+ * (§13.3) — not just in the standalone helpers.
164
+ */
165
+ function trimmedLabel(field, max) {
166
+ return z.string().transform((val, ctx) => {
167
+ const r = validateLabel(val, max);
168
+ if (!r.ok) {
169
+ ctx.addIssue({
170
+ code: z.ZodIssueCode.custom,
171
+ message: labelErrorMessage(field, r.reason),
172
+ });
173
+ return z.NEVER;
174
+ }
175
+ return r.value;
176
+ });
177
+ }
178
+ // ── Slug validator (§9.3) ─────────────────────────────────────────────────
179
+ const SLUG_RE = /^[a-z0-9][a-z0-9-]*$/;
180
+ const SLUG_MAX_LENGTH = 100;
181
+ /**
182
+ * Lowercase kebab-case slug. Must start with `[a-z0-9]`, may contain
183
+ * `-`. Used as the file-name segment of an entity path. Length-capped
184
+ * to keep filesystem paths well under typical `PATH_MAX` limits.
185
+ */
186
+ export function isValidSlug(value) {
187
+ return (typeof value === "string" &&
188
+ value.length > 0 &&
189
+ value.length <= SLUG_MAX_LENGTH &&
190
+ SLUG_RE.test(value));
191
+ }
192
+ const PATH_TRAVERSAL_RE = /(^|\/)\.\.(\/|$)/;
193
+ /**
194
+ * Validate an `Output path` value rendered in management.md's B-section
195
+ * (§9.1 render rules). The path:
196
+ *
197
+ * - is relative (no leading `/`),
198
+ * - has exactly two segments: `<domain>/<type-plural>/`,
199
+ * - ends with a trailing `/`,
200
+ * - contains no `..` traversal,
201
+ * - has a `<domain>` in `DOMAINS` and `<type-plural>` in `TYPE_PLURALS`.
202
+ *
203
+ * The leading `context/` is implicit (every L2 path lives there). The
204
+ * SQL `CHECK (output_path IS NULL OR output_path LIKE '%/')` constraint
205
+ * (§9.2) is the DB-side enforcement; this function is the renderer/
206
+ * parser-side enforcement.
207
+ */
208
+ export function isValidOutputPath(value) {
209
+ if (typeof value !== "string" || value.length === 0)
210
+ return false;
211
+ if (value.startsWith("/"))
212
+ return false;
213
+ if (PATH_TRAVERSAL_RE.test(value))
214
+ return false;
215
+ if (!value.endsWith("/"))
216
+ return false;
217
+ // Strip trailing slash and split — must have exactly two segments.
218
+ const segments = value.slice(0, -1).split("/");
219
+ if (segments.length !== 2)
220
+ return false;
221
+ const [domain, typePlural] = segments;
222
+ if (!domain || !typePlural)
223
+ return false;
224
+ if (!isDomain(domain))
225
+ return false;
226
+ if (pluralToType(typePlural) === null)
227
+ return false;
228
+ return true;
229
+ }
230
+ /**
231
+ * Parse an entity-file path of the form
232
+ * `<domain>/<type-plural>/<slug>.md` into its components. Returns
233
+ * `null` when the path is malformed or any segment fails its enum
234
+ * check. The leading `context/` MUST already be stripped — this is
235
+ * the relative form used in `entities.path`.
236
+ */
237
+ export function parseEntityPath(path) {
238
+ if (typeof path !== "string" || path.length === 0)
239
+ return null;
240
+ if (path.startsWith("/"))
241
+ return null;
242
+ if (PATH_TRAVERSAL_RE.test(path))
243
+ return null;
244
+ if (!path.endsWith(".md"))
245
+ return null;
246
+ const segments = path.split("/");
247
+ if (segments.length !== 3)
248
+ return null;
249
+ const [domain, typePlural, fileName] = segments;
250
+ if (!domain || !typePlural || !fileName)
251
+ return null;
252
+ if (!isDomain(domain))
253
+ return null;
254
+ const type = pluralToType(typePlural);
255
+ if (type === null)
256
+ return null;
257
+ const slug = fileName.slice(0, -3); // strip ".md"
258
+ if (!isValidSlug(slug))
259
+ return null;
260
+ return { domain, type, typePlural, slug, path };
261
+ }
262
+ /**
263
+ * Build the canonical entity-file path from components. Inverse of
264
+ * `parseEntityPath`. Returns `null` when any input fails its enum/slug
265
+ * validator — the caller should never assume the components are
266
+ * already validated.
267
+ */
268
+ export function buildEntityPath(domain, type, slug) {
269
+ if (!isDomain(domain))
270
+ return null;
271
+ if (!isEntityType(type))
272
+ return null;
273
+ if (!isValidSlug(slug))
274
+ return null;
275
+ return `${domain}/${typeToPlural(type)}/${slug}.md`;
276
+ }
277
+ // ── Managed-task ID (§9.2, §13.3) ─────────────────────────────────────────
278
+ const MT_ID_RE = /^mt_[1-9]\d*$/;
279
+ /**
280
+ * Validate a managed-task identifier. Format: `mt_<n>` where n is a
281
+ * positive decimal with no leading zeros. Allocated by
282
+ * `managed_task_seq` (§9.2); IDs are never reused so historical
283
+ * `agent_actions` references stay unambiguous.
284
+ */
285
+ export function isValidManagedTaskId(value) {
286
+ return typeof value === "string" && MT_ID_RE.test(value);
287
+ }
288
+ /** Format a numeric sequence value as a managed-task id. */
289
+ export function formatManagedTaskId(seq) {
290
+ if (!Number.isInteger(seq) || seq < 1) {
291
+ throw new RangeError(`managed-task sequence must be a positive integer, got ${seq}`);
292
+ }
293
+ return `mt_${seq}`;
294
+ }
295
+ // ── Zod schemas (§9.3, §9.5, §9.2) ────────────────────────────────────────
296
+ /**
297
+ * Per-source frontmatter sub-record on an entity file. Each contributing
298
+ * app gets one entry under `frontmatter.sources.<key>`. The map key is
299
+ * the user-typed app label — the same string that appears in
300
+ * management.md's `App` column. This is the cross-link between L1 and
301
+ * L2 (§8.2 ADR — entity-per-file, not app-per-file).
302
+ *
303
+ * `passthrough` permits app-specific fields beyond the four named ones
304
+ * without forcing a schema bump per integration.
305
+ */
306
+ export const entitySourceEntrySchema = z
307
+ .object({
308
+ /** App-internal id (free-form, e.g. Google Doc id). */
309
+ id: z.string().optional(),
310
+ /** Canonical URL into the source app for human follow-through. */
311
+ url: z.string().url().optional(),
312
+ /**
313
+ * Stable upstream identifier — the strongest signal for the §7.6
314
+ * lookup contract's tier-1 dedup match.
315
+ */
316
+ external_id: z.string().optional(),
317
+ })
318
+ .passthrough();
319
+ /**
320
+ * EntitySchema — frontmatter schema for L2 entity files (§9.3).
321
+ *
322
+ * Validated on every PATCH to `/api/context/<domain>/<type-plural>/
323
+ * <slug>.md` and by the entity-mirror watcher before a row is upserted
324
+ * into the `entities` SQLite table.
325
+ */
326
+ export const entitySchema = z.object({
327
+ type: z.enum(ENTITY_TYPES),
328
+ domain: z.enum(DOMAINS),
329
+ slug: z.string().refine(isValidSlug, "invalid slug"),
330
+ title: z.string().min(1).max(200),
331
+ status: z.enum(["upcoming", "active", "done", "archived"]).optional(),
332
+ /**
333
+ * Map of app-label → per-app metadata. Keys are user-typed strings;
334
+ * Zod `record` enforces non-empty string keys at parse time.
335
+ */
336
+ sources: z.record(z.string().min(1), entitySourceEntrySchema).default({}),
337
+ /** Wikilinks / paths to related entities. */
338
+ related: z.array(z.string()).default([]),
339
+ /** Free-form classification labels. */
340
+ tags: z.array(z.string()).default([]),
341
+ /** ISO-8601 datetime — when the entity file was first created. */
342
+ created: z.string().datetime(),
343
+ /** ISO-8601 datetime — most recent successful sync from any source. */
344
+ last_synced_at: z.string().datetime().optional(),
345
+ });
346
+ /**
347
+ * SotBindingSchema — one row of management.md's Section A (§9.5).
348
+ *
349
+ * Persisted in `settings(key='sot_bindings', value_json=...)` as a JSON
350
+ * array; mirrors the §A render in management.md.
351
+ *
352
+ * **`category` vs `Domain` (resolves design-doc §9.1/§9.5 ambiguity).**
353
+ * §9.1's example A-section renders rows like `tasks → notion`,
354
+ * `meetings → google_calendar+zoom`, `notes → obsidian` — values that
355
+ * are **not** in the §9.4 `DOMAINS` enum (which lists life-areas:
356
+ * `work`, `travel`, `finance`, `personal`, `health`, `learning`).
357
+ *
358
+ * SoT bindings are coarse data-categories independent of life-area —
359
+ * the v2 template's "Category" column made this explicit, and OQ-3
360
+ * defers per-life-area SoT bindings to v4. So `category` is a
361
+ * free-form, validated string here, **not** a `Domain`. Rendering uses
362
+ * a "Category" column header.
363
+ */
364
+ export const sotBindingSchema = z.object({
365
+ /**
366
+ * Free-form data-category label (e.g. `tasks`, `meetings`, `notes`,
367
+ * `projects`). Validated with the same trim/NFC/forbidden-char rules
368
+ * as `App`.
369
+ */
370
+ category: trimmedLabel("category", APP_MAX_LENGTH),
371
+ /** Free-form, user-typed canonical app label (e.g. "notion"). */
372
+ sotApp: trimmedLabel("sotApp", APP_MAX_LENGTH),
373
+ /**
374
+ * Optional path to a local mirror MD file (e.g. `context/work/tasks-
375
+ * index.md`). `null` when the SoT is external-only and no local
376
+ * mirror is maintained.
377
+ */
378
+ mirrorPath: z.string().min(1).max(255).nullable(),
379
+ /** Free-text policy note (≤200 chars). `null` when no policy applies. */
380
+ policy: z.string().max(200).nullable(),
381
+ /** Who is permitted to write the canonical store / its mirror. */
382
+ writer: z.enum(["agent", "shared", "user"]),
383
+ });
384
+ export const sotBindingsSchema = z.array(sotBindingSchema);
385
+ /**
386
+ * ManagedTaskSchema — DB-row shape for `managed_tasks` (§9.2).
387
+ *
388
+ * Matches the table column order; consumed by API GET responses and
389
+ * by the management.md renderer. Strings here represent the **stored**
390
+ * (already-cleaned) form — per-input cleaning lives on
391
+ * `managedTaskCreateSchema` / `managedTaskPatchSchema` so a row read
392
+ * from the DB does not get re-trimmed every load.
393
+ */
394
+ export const managedTaskSchema = z.object({
395
+ id: z.string().refine(isValidManagedTaskId, "must match /^mt_[1-9]\\d*$/"),
396
+ intent: z.string().min(1).max(INTENT_MAX_LENGTH),
397
+ app: z.string().min(1).max(APP_MAX_LENGTH),
398
+ app_normalized: z.string().min(1).max(APP_MAX_LENGTH),
399
+ cadence: z.string().min(1).max(200),
400
+ /**
401
+ * `output_path` is nullable only between row creation and the first
402
+ * successful run (FR-16). Validated against `isValidOutputPath` when
403
+ * non-null.
404
+ */
405
+ output_path: z
406
+ .string()
407
+ .nullable()
408
+ .refine((v) => v === null || isValidOutputPath(v), "output_path must be `<domain>/<type-plural>/` (see §9.1)"),
409
+ schedule_id: z.number().int().positive(),
410
+ /** ISO-8601 UTC; `null` until the first successful fire. */
411
+ last_run_at: z.string().datetime().nullable(),
412
+ last_result: z.string().max(LAST_RESULT_MAX_LENGTH).nullable(),
413
+ consecutive_failures: z.number().int().nonnegative(),
414
+ created_at: z.string(),
415
+ updated_at: z.string(),
416
+ });
417
+ /**
418
+ * Request body for `POST /api/managed-tasks` (§10.1 step 5).
419
+ *
420
+ * The structured `recurrenceRule` (frequency + time + tz + days) is
421
+ * threaded directly into the underlying `recurring_schedules` row
422
+ * (`db/recurring-schedules.ts` consumes this exact shape). The server
423
+ * allocates `mt_id` and `schedule_id` itself. `app` and `intent` are
424
+ * trimmed/NFC-normalized at this boundary so the downstream rendering
425
+ * and dedup paths see a clean value (§13.3).
426
+ *
427
+ * Note: the design doc (§10.1, §10.4) frames the cadence as `cron`+`tz`
428
+ * for prose readability, but the daemon's recurrence engine has never
429
+ * accepted raw cron — `RecurrenceRule` is the canonical shape. The
430
+ * registration skill resolves the user's natural-language phrasing
431
+ * (`"daily 10:00 (Asia/Tokyo)"`) into both:
432
+ * - `cadence` (free text rendered in management.md), and
433
+ * - `recurrenceRule` (the executable form).
434
+ */
435
+ export const managedTaskCreateSchema = z.object({
436
+ intent: trimmedLabel("intent", INTENT_MAX_LENGTH),
437
+ app: trimmedLabel("app", APP_MAX_LENGTH),
438
+ /**
439
+ * Human-readable cadence (e.g. "daily 10:00 (Asia/Tokyo)"). Length
440
+ * cap is intentionally generous; the structured `recurrenceRule` is
441
+ * the executable form, this string is the rendered form.
442
+ */
443
+ cadence: z.string().min(1).max(200),
444
+ /** Structured recurrence — the same shape `recurring_schedules` uses. */
445
+ recurrenceRule: recurrenceRuleSchema,
446
+ /** Optional initial output path; first run populates it when omitted. */
447
+ output_path: z
448
+ .string()
449
+ .refine((v) => isValidOutputPath(v), "output_path must be `<domain>/<type-plural>/` (see §9.1)")
450
+ .optional(),
451
+ });
452
+ /**
453
+ * Request body for `PATCH /api/managed-tasks/:id` (§10.2).
454
+ *
455
+ * Any subset of mutable columns. The `id`, `app`, `app_normalized`,
456
+ * `schedule_id`, and timestamps are NOT mutable through this surface.
457
+ * `last_run_at` / `last_result` / `consecutive_failures` are written
458
+ * by the scheduled-managed-task skill, not by user-facing PATCHes.
459
+ *
460
+ * `app` is intentionally immutable — renaming an app would silently
461
+ * orphan all entity-file `frontmatter.sources.<key>` references. The
462
+ * separate `POST /api/managed-tasks/:id/rename-app` endpoint (§12)
463
+ * handles that atomically.
464
+ */
465
+ export const managedTaskPatchSchema = z
466
+ .object({
467
+ intent: trimmedLabel("intent", INTENT_MAX_LENGTH).optional(),
468
+ cadence: z.string().min(1).max(200).optional(),
469
+ /**
470
+ * Structured recurrence (matches the create-schema shape). The
471
+ * route layer threads this through `updateRecurringSchedule` which
472
+ * regenerates the next `agent_schedule` row.
473
+ */
474
+ recurrenceRule: recurrenceRuleSchema.optional(),
475
+ output_path: z
476
+ .string()
477
+ .refine((v) => isValidOutputPath(v), "output_path must be `<domain>/<type-plural>/` (see §9.1)")
478
+ .nullable()
479
+ .optional(),
480
+ })
481
+ .refine((data) => Object.keys(data).length > 0, "PATCH body must specify at least one field");
482
+ /**
483
+ * Internal-update schema — used by the scheduled-managed-task skill
484
+ * via `PATCH /api/managed-tasks/:id/run-result` (§10.4 step 5).
485
+ * Separate from the user-facing PATCH because the surfaces and
486
+ * risk-tier classifications differ.
487
+ */
488
+ export const managedTaskRunResultSchema = z.object({
489
+ /** ISO-8601 UTC. Validated strictly so a malformed write fails loudly. */
490
+ last_run_at: z.string().datetime(),
491
+ last_result: z.string().max(LAST_RESULT_MAX_LENGTH),
492
+ /**
493
+ * Replace-semantics. The server sets the value verbatim; the skill
494
+ * is responsible for bumping/resetting based on success or failure
495
+ * (§10.4).
496
+ */
497
+ consecutive_failures: z.number().int().nonnegative(),
498
+ });
499
+ //# sourceMappingURL=management-domains.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"management-domains.js","sourceRoot":"","sources":["../src/management-domains.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ import type { Event } from "./types.js";
2
+ export declare const CONFIGURABLE_PROCESS_KEYS: readonly ["routine.morning_routine", "routine.evening_review", "routine.weekly_review", "routine.monthly_review", "routine.hourly_check", "message.dm", "message.mention", "dashboard.chat", "dashboard.docs_qa", "agent.task", "agent.dm_task", "calendar.change", "gmail_classify", "github.pull_request.review_requested", "github.assigned", "github.security_alert", "github.workflow_run.failed", "git.push.detected", "git.local_ahead.stale", "git.push.force_pushed", "git.branch.created", "git.tag.created", "git.merge_to_default", "git.project.init", "git.project.update", "git.project.refresh_architecture", "git.project.retemplate", "routine.skill_curation", "observation.summarize", "routine.hourly_check.triage"];
3
+ declare const ALL_PROCESS_KEYS: readonly ["routine.morning_routine", "routine.evening_review", "routine.weekly_review", "routine.monthly_review", "routine.hourly_check", "message.dm", "message.mention", "dashboard.chat", "dashboard.docs_qa", "agent.task", "agent.dm_task", "calendar.change", "gmail_classify", "github.pull_request.review_requested", "github.assigned", "github.security_alert", "github.workflow_run.failed", "git.push.detected", "git.local_ahead.stale", "git.push.force_pushed", "git.branch.created", "git.tag.created", "git.merge_to_default", "git.project.init", "git.project.update", "git.project.refresh_architecture", "git.project.retemplate", "routine.skill_curation", "observation.summarize", "routine.hourly_check.triage", "git.lifecycle.poll", "routine.morning_routine_initial", "routine.roadmap_refresh", "routine.today_refresh", "routine.user_profile_sweep", "schedule.approaching", "integration_drift_sync", "setup", "knowledge.import", "delegated_task", "delegated_task_heavy"];
4
+ type ConfigurableProcessKey = (typeof CONFIGURABLE_PROCESS_KEYS)[number];
5
+ type KnownProcessKey = (typeof ALL_PROCESS_KEYS)[number];
6
+ /**
7
+ * Process keys identify dispatch surfaces (DM, routine, observer event,
8
+ * scheduled task, custom routine, etc.). The union is widened to `string`
9
+ * because custom-routine keys (`routine.custom.<slug>`) are user-supplied
10
+ * at runtime — we cannot enumerate them at compile time. Trade-off: a
11
+ * literal typo like `"messasge.dm"` typechecks. Use `isProcessKey()` at
12
+ * boundaries that care (DB write, dispatcher routing) to assert the
13
+ * value belongs to the known set.
14
+ */
15
+ export type ProcessKey = KnownProcessKey | string;
16
+ /**
17
+ * See {@link BackendModelTier} in `backend.ts` for the tier semantics. The
18
+ * two are kept aligned by the test in `process-key.test.ts`.
19
+ */
20
+ export type ProcessModelTier = "lite" | "medium" | "high";
21
+ export declare function isProcessKey(value: string): value is KnownProcessKey;
22
+ export declare function isConfigurableProcessKey(value: string): value is ConfigurableProcessKey;
23
+ export declare function isCustomRoutineKey(value: string): boolean;
24
+ export declare function customRoutineKey(slug: string): string;
25
+ export declare function customRoutineSlugFromKey(key: string): string | null;
26
+ export declare function isAutonomousProcessKey(processKey: ProcessKey): boolean;
27
+ /**
28
+ * Hard tier locks that supersede operator pins, requestedTier hints, and
29
+ * `process_backend_config` rows. Use sparingly: a lock here means we are
30
+ * stating that the named process must run at the listed tier even if the
31
+ * operator explicitly pinned it to something else in `/settings/models`.
32
+ *
33
+ * `dashboard.docs_qa` is locked to `medium` because the QA panel is a
34
+ * doc-lookup surface, not a free-form chat — high tier would silently
35
+ * drain the Opus quota on every "what does X do?" question. See
36
+ * DOCS_QA_DESIGN.md §10.1.
37
+ */
38
+ export declare const TIER_LOCKED_PROCESS_KEYS: Readonly<Partial<Record<ProcessKey, ProcessModelTier>>>;
39
+ export declare function getDefaultTierForProcessKey(processKey: ProcessKey): ProcessModelTier;
40
+ /**
41
+ * DELEGATED-TASK-MODE-DESIGN.md §17 — hard caps on the `/exec` and `/run`
42
+ * task-mode endpoints. These bound a prompt-injected caller's blast radius
43
+ * regardless of the per-request fields they pass. `config.ts` holds the
44
+ * *defaults* (`delegatedTaskDefaultMaxToolCalls` etc.); the constants below
45
+ * are not user-tunable — they live here alongside the ProcessKey
46
+ * definitions because they describe the contract of the `delegated_task` /
47
+ * `delegated_task_heavy` execution shape itself, not the operator's
48
+ * preferences.
49
+ */
50
+ export declare const DELEGATED_TASK_HARD_CAPS: {
51
+ /** Upper bound on `maxToolCalls` request field. */
52
+ readonly maxToolCalls: 15;
53
+ /** Upper bound on `maxBudgetUsd` request field. */
54
+ readonly maxBudgetUsd: 0.5;
55
+ /** Upper bound on `timeoutMs` request field. */
56
+ readonly maxTimeoutMs: 300000;
57
+ /**
58
+ * Upper bound on the inlined `outputSchema` payload, measured as
59
+ * `Buffer.byteLength(JSON.stringify(schema), "utf-8")`. The schema
60
+ * lands in the subprocess system prompt and is paid as input tokens
61
+ * on every model turn; 4 KB ≈ 1000 tokens — empirical cap (§6.4).
62
+ */
63
+ readonly maxSchemaBytes: 4096;
64
+ };
65
+ export declare function resolveProcessKey(event: Event): ProcessKey;
66
+ export {};
67
+ //# sourceMappingURL=process-key.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-key.d.ts","sourceRoot":"","sources":["../src/process-key.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAgB,MAAM,YAAY,CAAC;AAGtD,eAAO,MAAM,yBAAyB,2sBAmE5B,CAAC;AAkCX,QAAA,MAAM,gBAAgB,+8BAGZ,CAAC;AAEX,KAAK,sBAAsB,GAAG,CAAC,OAAO,yBAAyB,CAAC,CAAC,MAAM,CAAC,CAAC;AACzE,KAAK,eAAe,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AACzD;;;;;;;;GAQG;AACH,MAAM,MAAM,UAAU,GAAG,eAAe,GAAG,MAAM,CAAC;AAClD;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;AA4H1D,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,eAAe,CAEpE;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,sBAAsB,CAEvF;AAWD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAKzD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGnE;AAqBD,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAEtE;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,wBAAwB,EAAE,QAAQ,CAC7C,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC,CAG9C,CAAC;AAEF,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,UAAU,GAAG,gBAAgB,CAWpF;AAMD;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB;IACnC,mDAAmD;;IAEnD,mDAAmD;;IAEnD,gDAAgD;;IAEhD;;;;;OAKG;;CAEK,CAAC;AAEX,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,KAAK,GAAG,UAAU,CA0C1D"}