forge-openclaw-plugin 0.2.3 → 0.2.7

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 (117) hide show
  1. package/README.md +114 -6
  2. package/dist/assets/board-CzgvdLO8.js +6 -0
  3. package/dist/assets/board-CzgvdLO8.js.map +1 -0
  4. package/dist/assets/favicon-BCHm9dUV.ico +0 -0
  5. package/dist/assets/index-8d_oM8fL.js +27 -0
  6. package/dist/assets/index-8d_oM8fL.js.map +1 -0
  7. package/dist/assets/index-D4A_bq8m.css +1 -0
  8. package/dist/assets/motion-STUd1O46.js +10 -0
  9. package/dist/assets/motion-STUd1O46.js.map +1 -0
  10. package/dist/assets/plus-jakarta-sans-latin-ext-wght-normal-DmpS2jIq.woff2 +0 -0
  11. package/dist/assets/plus-jakarta-sans-latin-wght-normal-eXO_dkmS.woff2 +0 -0
  12. package/dist/assets/plus-jakarta-sans-vietnamese-wght-normal-qRpaaN48.woff2 +0 -0
  13. package/dist/assets/sora-latin-ext-wght-normal-CawQDOvP.woff2 +0 -0
  14. package/dist/assets/sora-latin-wght-normal-DdqRvwsR.woff2 +0 -0
  15. package/dist/assets/space-grotesk-latin-500-normal-CNSSEhBt.woff +0 -0
  16. package/dist/assets/space-grotesk-latin-500-normal-lFbtlQH6.woff2 +0 -0
  17. package/dist/assets/space-grotesk-latin-700-normal-CwsQ-cCU.woff +0 -0
  18. package/dist/assets/space-grotesk-latin-700-normal-RjhwGPKo.woff2 +0 -0
  19. package/dist/assets/space-grotesk-latin-ext-500-normal-3dgZTiw9.woff +0 -0
  20. package/dist/assets/space-grotesk-latin-ext-500-normal-DUe3BAxM.woff2 +0 -0
  21. package/dist/assets/space-grotesk-latin-ext-700-normal-BQnZhY3m.woff2 +0 -0
  22. package/dist/assets/space-grotesk-latin-ext-700-normal-HVCqSBdx.woff +0 -0
  23. package/dist/assets/space-grotesk-vietnamese-500-normal-BTqKIpxg.woff +0 -0
  24. package/dist/assets/space-grotesk-vietnamese-500-normal-BmEvtly_.woff2 +0 -0
  25. package/dist/assets/space-grotesk-vietnamese-700-normal-DMty7AZE.woff2 +0 -0
  26. package/dist/assets/space-grotesk-vietnamese-700-normal-Duxec5Rn.woff +0 -0
  27. package/dist/assets/table-CtNlETLc.js +23 -0
  28. package/dist/assets/table-CtNlETLc.js.map +1 -0
  29. package/dist/assets/ui-ThzkR_oW.js +46 -0
  30. package/dist/assets/ui-ThzkR_oW.js.map +1 -0
  31. package/dist/assets/vendor-CRS-psbw.css +1 -0
  32. package/dist/assets/vendor-DyHAI6nk.js +423 -0
  33. package/dist/assets/vendor-DyHAI6nk.js.map +1 -0
  34. package/dist/assets/viz-BJuBCz_G.js +34 -0
  35. package/dist/assets/viz-BJuBCz_G.js.map +1 -0
  36. package/dist/favicon.ico +0 -0
  37. package/dist/favicon.png +0 -0
  38. package/dist/index.html +29 -0
  39. package/dist/openclaw/api-client.d.ts +8 -0
  40. package/dist/openclaw/api-client.js +31 -4
  41. package/dist/openclaw/local-runtime.d.ts +3 -0
  42. package/dist/openclaw/local-runtime.js +135 -0
  43. package/dist/openclaw/parity.d.ts +4 -4
  44. package/dist/openclaw/parity.js +23 -33
  45. package/dist/openclaw/plugin-entry-shared.d.ts +5 -3
  46. package/dist/openclaw/plugin-entry-shared.js +52 -10
  47. package/dist/openclaw/routes.d.ts +12 -3
  48. package/dist/openclaw/routes.js +156 -924
  49. package/dist/openclaw/tools.js +242 -1100
  50. package/dist/server/app.js +2450 -0
  51. package/dist/server/db.js +313 -0
  52. package/dist/server/e2e-server.js +20 -0
  53. package/dist/server/errors.js +15 -0
  54. package/dist/server/index.js +16 -0
  55. package/dist/server/managers/base.js +17 -0
  56. package/dist/server/managers/contracts.js +47 -0
  57. package/dist/server/managers/platform/api-gateway-manager.js +11 -0
  58. package/dist/server/managers/platform/audit-manager.js +15 -0
  59. package/dist/server/managers/platform/authentication-manager.js +56 -0
  60. package/dist/server/managers/platform/authorization-manager.js +56 -0
  61. package/dist/server/managers/platform/background-job-manager.js +10 -0
  62. package/dist/server/managers/platform/configuration-manager.js +33 -0
  63. package/dist/server/managers/platform/database-manager.js +14 -0
  64. package/dist/server/managers/platform/event-bus-manager.js +7 -0
  65. package/dist/server/managers/platform/external-service-manager.js +11 -0
  66. package/dist/server/managers/platform/health-manager.js +7 -0
  67. package/dist/server/managers/platform/migration-manager.js +8 -0
  68. package/dist/server/managers/platform/search-index-manager.js +4 -0
  69. package/dist/server/managers/platform/secrets-manager.js +19 -0
  70. package/dist/server/managers/platform/session-manager.js +121 -0
  71. package/dist/server/managers/platform/storage-manager.js +16 -0
  72. package/dist/server/managers/platform/token-manager.js +37 -0
  73. package/dist/server/managers/platform/transaction-manager.js +8 -0
  74. package/dist/server/managers/platform/trusted-network.js +39 -0
  75. package/dist/server/managers/runtime.js +56 -0
  76. package/dist/server/managers/type-guards.js +4 -0
  77. package/dist/server/openapi.js +3512 -0
  78. package/dist/server/psyche-types.js +395 -0
  79. package/dist/server/repositories/activity-events.js +157 -0
  80. package/dist/server/repositories/collaboration.js +497 -0
  81. package/dist/server/repositories/comments.js +176 -0
  82. package/dist/server/repositories/deleted-entities.js +192 -0
  83. package/dist/server/repositories/domains.js +30 -0
  84. package/dist/server/repositories/event-log.js +64 -0
  85. package/dist/server/repositories/goals.js +159 -0
  86. package/dist/server/repositories/projects.js +214 -0
  87. package/dist/server/repositories/psyche.js +1356 -0
  88. package/dist/server/repositories/rewards.js +675 -0
  89. package/dist/server/repositories/settings.js +399 -0
  90. package/dist/server/repositories/tags.js +160 -0
  91. package/dist/server/repositories/task-runs.js +488 -0
  92. package/dist/server/repositories/tasks.js +413 -0
  93. package/dist/server/services/context.js +214 -0
  94. package/dist/server/services/dashboard.js +170 -0
  95. package/dist/server/services/entity-crud.js +576 -0
  96. package/dist/server/services/gamification.js +215 -0
  97. package/dist/server/services/insights.js +91 -0
  98. package/dist/server/services/projects.js +75 -0
  99. package/dist/server/services/psyche.js +63 -0
  100. package/dist/server/services/relations.js +28 -0
  101. package/dist/server/services/reviews.js +88 -0
  102. package/dist/server/services/run-recovery.js +13 -0
  103. package/dist/server/services/tagging.js +49 -0
  104. package/dist/server/services/task-run-watchdog.js +92 -0
  105. package/dist/server/services/work-time.js +176 -0
  106. package/dist/server/types.js +999 -0
  107. package/dist/server/web.js +91 -0
  108. package/openclaw.plugin.json +22 -10
  109. package/package.json +17 -4
  110. package/server/migrations/001_core.sql +333 -0
  111. package/server/migrations/002_psyche.sql +241 -0
  112. package/server/migrations/003_timer_execution.sql +18 -0
  113. package/server/migrations/004_psyche_linked_entities.sql +5 -0
  114. package/server/migrations/005_adaptive_schemas.sql +157 -0
  115. package/server/migrations/006_psyche_auth_setting.sql +4 -0
  116. package/server/migrations/007_deleted_entities.sql +16 -0
  117. package/skills/forge-openclaw/SKILL.md +189 -275
@@ -0,0 +1,1356 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { getDatabase, runInTransaction } from "../db.js";
3
+ import { recordActivityEvent } from "./activity-events.js";
4
+ import { filterDeletedEntities, filterDeletedIds, isEntityDeleted } from "./deleted-entities.js";
5
+ import { recordEventLog } from "./event-log.js";
6
+ import { recordPsycheClarityReward, recordPsycheReflectionReward } from "./rewards.js";
7
+ import { behaviorPatternSchema, behaviorSchema, beliefEntrySchema, createBehaviorPatternSchema, createBehaviorSchema, createBeliefEntrySchema, createEmotionDefinitionSchema, createEventTypeSchema, createModeGuideSessionSchema, createModeProfileSchema, createPsycheValueSchema, createTriggerReportSchema, domainSchema, emotionDefinitionSchema, eventTypeSchema, modeFamilySchema, modeGuideResultSchema, modeGuideSessionSchema, modeProfileSchema, modeTimelineEntrySchema, psycheValueSchema, schemaCatalogEntrySchema, triggerReportSchema, updateBehaviorPatternSchema, updateBehaviorSchema, updateBeliefEntrySchema, updateEmotionDefinitionSchema, updateEventTypeSchema, updateModeGuideSessionSchema, updateModeProfileSchema, updatePsycheValueSchema, updateTriggerReportSchema } from "../psyche-types.js";
8
+ const PSYCHE_DOMAIN_ID = "domain_psyche";
9
+ function parseJson(value) {
10
+ return JSON.parse(value);
11
+ }
12
+ function buildId(prefix) {
13
+ return `${prefix}_${randomUUID().replaceAll("-", "").slice(0, 10)}`;
14
+ }
15
+ function enrichTriggerItems(items, prefix) {
16
+ return items.map((item) => ({
17
+ ...item,
18
+ id: item.id ?? buildId(prefix)
19
+ }));
20
+ }
21
+ function mapDomain(row) {
22
+ return domainSchema.parse({
23
+ id: row.id,
24
+ slug: row.slug,
25
+ title: row.title,
26
+ description: row.description,
27
+ themeColor: row.theme_color,
28
+ sensitive: row.sensitive === 1,
29
+ createdAt: row.created_at,
30
+ updatedAt: row.updated_at
31
+ });
32
+ }
33
+ function mapSchemaCatalogEntry(row) {
34
+ return schemaCatalogEntrySchema.parse({
35
+ id: row.id,
36
+ slug: row.slug,
37
+ title: row.title,
38
+ family: row.family,
39
+ schemaType: row.schema_type,
40
+ description: row.description,
41
+ createdAt: row.created_at,
42
+ updatedAt: row.updated_at
43
+ });
44
+ }
45
+ function mapEventType(row) {
46
+ return eventTypeSchema.parse({
47
+ id: row.id,
48
+ domainId: row.domain_id,
49
+ label: row.label,
50
+ description: row.description,
51
+ system: row.system === 1,
52
+ createdAt: row.created_at,
53
+ updatedAt: row.updated_at
54
+ });
55
+ }
56
+ function mapEmotionDefinition(row) {
57
+ return emotionDefinitionSchema.parse({
58
+ id: row.id,
59
+ domainId: row.domain_id,
60
+ label: row.label,
61
+ description: row.description,
62
+ category: row.category,
63
+ system: row.system === 1,
64
+ createdAt: row.created_at,
65
+ updatedAt: row.updated_at
66
+ });
67
+ }
68
+ function mapPsycheValue(row) {
69
+ return psycheValueSchema.parse({
70
+ id: row.id,
71
+ domainId: row.domain_id,
72
+ title: row.title,
73
+ description: row.description,
74
+ valuedDirection: row.valued_direction,
75
+ whyItMatters: row.why_it_matters,
76
+ linkedGoalIds: filterDeletedIds("goal", parseJson(row.linked_goal_ids_json)),
77
+ linkedProjectIds: filterDeletedIds("project", parseJson(row.linked_project_ids_json)),
78
+ linkedTaskIds: filterDeletedIds("task", parseJson(row.linked_task_ids_json)),
79
+ committedActions: parseJson(row.committed_actions_json),
80
+ createdAt: row.created_at,
81
+ updatedAt: row.updated_at
82
+ });
83
+ }
84
+ function mapBehaviorPattern(row) {
85
+ return behaviorPatternSchema.parse({
86
+ id: row.id,
87
+ domainId: row.domain_id,
88
+ title: row.title,
89
+ description: row.description,
90
+ targetBehavior: row.target_behavior,
91
+ cueContexts: parseJson(row.cue_contexts_json),
92
+ shortTermPayoff: row.short_term_payoff,
93
+ longTermCost: row.long_term_cost,
94
+ preferredResponse: row.preferred_response,
95
+ linkedValueIds: filterDeletedIds("psyche_value", parseJson(row.linked_value_ids_json)),
96
+ linkedSchemaLabels: parseJson(row.linked_schema_labels_json),
97
+ linkedModeLabels: parseJson(row.linked_mode_labels_json),
98
+ linkedModeIds: filterDeletedIds("mode_profile", parseJson(row.linked_mode_ids_json)),
99
+ linkedBeliefIds: filterDeletedIds("belief_entry", parseJson(row.linked_belief_ids_json)),
100
+ createdAt: row.created_at,
101
+ updatedAt: row.updated_at
102
+ });
103
+ }
104
+ function mapBehavior(row) {
105
+ return behaviorSchema.parse({
106
+ id: row.id,
107
+ domainId: row.domain_id,
108
+ kind: row.kind,
109
+ title: row.title,
110
+ description: row.description,
111
+ commonCues: parseJson(row.common_cues_json),
112
+ urgeStory: row.urge_story,
113
+ shortTermPayoff: row.short_term_payoff,
114
+ longTermCost: row.long_term_cost,
115
+ replacementMove: row.replacement_move,
116
+ repairPlan: row.repair_plan,
117
+ linkedPatternIds: filterDeletedIds("behavior_pattern", parseJson(row.linked_pattern_ids_json)),
118
+ linkedValueIds: filterDeletedIds("psyche_value", parseJson(row.linked_value_ids_json)),
119
+ linkedSchemaIds: parseJson(row.linked_schema_ids_json),
120
+ linkedModeIds: filterDeletedIds("mode_profile", parseJson(row.linked_mode_ids_json)),
121
+ createdAt: row.created_at,
122
+ updatedAt: row.updated_at
123
+ });
124
+ }
125
+ function mapBeliefEntry(row) {
126
+ return beliefEntrySchema.parse({
127
+ id: row.id,
128
+ domainId: row.domain_id,
129
+ schemaId: row.schema_id,
130
+ statement: row.statement,
131
+ beliefType: row.belief_type,
132
+ originNote: row.origin_note,
133
+ confidence: row.confidence,
134
+ evidenceFor: parseJson(row.evidence_for_json),
135
+ evidenceAgainst: parseJson(row.evidence_against_json),
136
+ flexibleAlternative: row.flexible_alternative,
137
+ linkedValueIds: filterDeletedIds("psyche_value", parseJson(row.linked_value_ids_json)),
138
+ linkedBehaviorIds: filterDeletedIds("behavior", parseJson(row.linked_behavior_ids_json)),
139
+ linkedModeIds: filterDeletedIds("mode_profile", parseJson(row.linked_mode_ids_json)),
140
+ linkedReportIds: filterDeletedIds("trigger_report", parseJson(row.linked_report_ids_json)),
141
+ createdAt: row.created_at,
142
+ updatedAt: row.updated_at
143
+ });
144
+ }
145
+ function mapModeProfile(row) {
146
+ return modeProfileSchema.parse({
147
+ id: row.id,
148
+ domainId: row.domain_id,
149
+ family: row.family,
150
+ archetype: row.archetype,
151
+ title: row.title,
152
+ persona: row.persona,
153
+ imagery: row.imagery,
154
+ symbolicForm: row.symbolic_form,
155
+ facialExpression: row.facial_expression,
156
+ fear: row.fear,
157
+ burden: row.burden,
158
+ protectiveJob: row.protective_job,
159
+ originContext: row.origin_context,
160
+ firstAppearanceAt: row.first_appearance_at,
161
+ linkedPatternIds: filterDeletedIds("behavior_pattern", parseJson(row.linked_pattern_ids_json)),
162
+ linkedBehaviorIds: filterDeletedIds("behavior", parseJson(row.linked_behavior_ids_json)),
163
+ linkedValueIds: filterDeletedIds("psyche_value", parseJson(row.linked_value_ids_json)),
164
+ createdAt: row.created_at,
165
+ updatedAt: row.updated_at
166
+ });
167
+ }
168
+ function mapModeGuideSession(row) {
169
+ return modeGuideSessionSchema.parse({
170
+ id: row.id,
171
+ summary: row.summary,
172
+ answers: parseJson(row.answers_json),
173
+ results: parseJson(row.results_json),
174
+ createdAt: row.created_at,
175
+ updatedAt: row.updated_at
176
+ });
177
+ }
178
+ function mapTriggerReport(row) {
179
+ const emotions = parseJson(row.emotions_json).map((emotion) => emotion.emotionDefinitionId && isEntityDeleted("emotion_definition", emotion.emotionDefinitionId)
180
+ ? { ...emotion, emotionDefinitionId: null }
181
+ : emotion);
182
+ const thoughts = parseJson(row.thoughts_json).map((thought) => thought.beliefId && isEntityDeleted("belief_entry", thought.beliefId)
183
+ ? { ...thought, beliefId: null }
184
+ : thought);
185
+ const behaviors = parseJson(row.behaviors_json).map((behavior) => behavior.behaviorId && isEntityDeleted("behavior", behavior.behaviorId)
186
+ ? { ...behavior, behaviorId: null }
187
+ : behavior);
188
+ const modeTimeline = parseJson(row.mode_timeline_json).map((entry) => entry.modeId && isEntityDeleted("mode_profile", entry.modeId)
189
+ ? { ...entry, modeId: null }
190
+ : entry);
191
+ return triggerReportSchema.parse({
192
+ id: row.id,
193
+ domainId: row.domain_id,
194
+ title: row.title,
195
+ status: row.status,
196
+ eventTypeId: row.event_type_id && isEntityDeleted("event_type", row.event_type_id) ? null : row.event_type_id,
197
+ customEventType: row.custom_event_type,
198
+ eventSituation: row.event_situation,
199
+ occurredAt: row.occurred_at,
200
+ emotions,
201
+ thoughts,
202
+ behaviors,
203
+ consequences: parseJson(row.consequences_json),
204
+ linkedPatternIds: filterDeletedIds("behavior_pattern", parseJson(row.linked_pattern_ids_json)),
205
+ linkedValueIds: filterDeletedIds("psyche_value", parseJson(row.linked_value_ids_json)),
206
+ linkedGoalIds: filterDeletedIds("goal", parseJson(row.linked_goal_ids_json)),
207
+ linkedProjectIds: filterDeletedIds("project", parseJson(row.linked_project_ids_json)),
208
+ linkedTaskIds: filterDeletedIds("task", parseJson(row.linked_task_ids_json)),
209
+ linkedBehaviorIds: filterDeletedIds("behavior", parseJson(row.linked_behavior_ids_json)),
210
+ linkedBeliefIds: filterDeletedIds("belief_entry", parseJson(row.linked_belief_ids_json)),
211
+ linkedModeIds: filterDeletedIds("mode_profile", parseJson(row.linked_mode_ids_json)),
212
+ modeOverlays: parseJson(row.mode_overlays_json),
213
+ schemaLinks: parseJson(row.schema_links_json),
214
+ modeTimeline,
215
+ nextMoves: parseJson(row.next_moves_json),
216
+ createdAt: row.created_at,
217
+ updatedAt: row.updated_at
218
+ });
219
+ }
220
+ function scoreModeGuideSession(input) {
221
+ const answers = new Map(input.answers.map((answer) => [answer.questionKey, answer.value]));
222
+ const results = [];
223
+ const coping = answers.get("coping_response");
224
+ if (coping && coping !== "none") {
225
+ results.push(modeGuideResultSchema.parse({
226
+ family: "coping",
227
+ archetype: coping,
228
+ label: coping === "fight"
229
+ ? "Fighter"
230
+ : coping === "flight"
231
+ ? "Escaper"
232
+ : coping === "freeze"
233
+ ? "Freezer"
234
+ : coping === "detach"
235
+ ? "Detached protector"
236
+ : coping === "comply"
237
+ ? "Compliant surrender"
238
+ : "Overcompensator",
239
+ confidence: 0.78,
240
+ reasoning: `The coping response leaned most strongly toward ${coping}.`
241
+ }));
242
+ }
243
+ const child = answers.get("child_state");
244
+ if (child && child !== "none") {
245
+ results.push(modeGuideResultSchema.parse({
246
+ family: "child",
247
+ archetype: child,
248
+ label: child === "vulnerable"
249
+ ? "Vulnerable child"
250
+ : child === "angry"
251
+ ? "Angry child"
252
+ : child === "impulsive"
253
+ ? "Impulsive child"
254
+ : child === "lonely"
255
+ ? "Lonely child"
256
+ : "Ashamed child",
257
+ confidence: 0.72,
258
+ reasoning: `The child-state answers cluster around ${child} activation.`
259
+ }));
260
+ }
261
+ const critic = answers.get("critic_style");
262
+ if (critic && critic !== "none") {
263
+ results.push(modeGuideResultSchema.parse({
264
+ family: "critic_parent",
265
+ archetype: critic,
266
+ label: critic === "demanding" ? "Demanding critic" : "Punitive critic",
267
+ confidence: 0.76,
268
+ reasoning: `The inner critical tone reads as ${critic}.`
269
+ }));
270
+ }
271
+ const healthy = answers.get("healthy_contact");
272
+ if (healthy && healthy !== "none") {
273
+ results.push(modeGuideResultSchema.parse({
274
+ family: healthy === "happy_child" ? "happy_child" : "healthy_adult",
275
+ archetype: healthy,
276
+ label: healthy === "happy_child" ? "Happy child" : "Healthy adult",
277
+ confidence: 0.69,
278
+ reasoning: `There is still some contact with ${healthy === "happy_child" ? "playful aliveness" : "steady adult leadership"}.`
279
+ }));
280
+ }
281
+ if (results.length === 0) {
282
+ results.push(modeGuideResultSchema.parse({
283
+ family: "healthy_adult",
284
+ archetype: "undifferentiated",
285
+ label: "Mixed state",
286
+ confidence: 0.41,
287
+ reasoning: "The questionnaire suggests a mixed or unclear state; name the mode manually after reflection."
288
+ }));
289
+ }
290
+ return results;
291
+ }
292
+ function mapCreateUpdateContext(input) {
293
+ recordActivityEvent({
294
+ entityType: input.entityType,
295
+ entityId: input.entityId,
296
+ eventType: input.eventKind,
297
+ title: input.title,
298
+ description: input.title,
299
+ actor: input.actor ?? null,
300
+ source: input.source,
301
+ metadata: input.metadata ?? {}
302
+ });
303
+ recordEventLog({
304
+ eventKind: input.eventKind,
305
+ entityType: input.entityType,
306
+ entityId: input.entityId,
307
+ actor: input.actor ?? null,
308
+ source: input.source,
309
+ metadata: input.metadata ?? {}
310
+ });
311
+ }
312
+ function getRow(sql, id) {
313
+ return getDatabase().prepare(sql).get(id);
314
+ }
315
+ function deleteEntityComments(entityType, entityId) {
316
+ getDatabase()
317
+ .prepare(`DELETE FROM entity_comments
318
+ WHERE entity_type = ?
319
+ AND entity_id = ?`)
320
+ .run(entityType, entityId);
321
+ }
322
+ function rewriteJsonColumn(table, column, transform) {
323
+ const rows = getDatabase()
324
+ .prepare(`SELECT id, ${column} AS payload FROM ${table}`)
325
+ .all();
326
+ const update = getDatabase().prepare(`UPDATE ${table} SET ${column} = ?, updated_at = ? WHERE id = ?`);
327
+ for (const row of rows) {
328
+ const current = parseJson(row.payload);
329
+ const next = transform(current);
330
+ const currentJson = JSON.stringify(current);
331
+ const nextJson = JSON.stringify(next);
332
+ if (nextJson !== currentJson) {
333
+ update.run(nextJson, new Date().toISOString(), row.id);
334
+ }
335
+ }
336
+ }
337
+ function removeIdFromStringArrayColumn(table, column, targetId) {
338
+ rewriteJsonColumn(table, column, (values) => values.filter((value) => value !== targetId));
339
+ }
340
+ function nullifyTriggerThoughtBeliefReferences(beliefId) {
341
+ rewriteJsonColumn("trigger_reports", "thoughts_json", (thoughts) => thoughts.map((thought) => (thought.beliefId === beliefId ? { ...thought, beliefId: null } : thought)));
342
+ }
343
+ function nullifyTriggerBehaviorReferences(behaviorId) {
344
+ rewriteJsonColumn("trigger_reports", "behaviors_json", (behaviors) => behaviors.map((behavior) => (behavior.behaviorId === behaviorId ? { ...behavior, behaviorId: null } : behavior)));
345
+ }
346
+ function nullifyTriggerEmotionReferences(emotionId) {
347
+ rewriteJsonColumn("trigger_reports", "emotions_json", (emotions) => emotions.map((emotion) => emotion.emotionDefinitionId === emotionId ? { ...emotion, emotionDefinitionId: null } : emotion));
348
+ }
349
+ function nullifyTriggerTimelineModeReferences(modeId) {
350
+ rewriteJsonColumn("trigger_reports", "mode_timeline_json", (entries) => entries.map((entry) => (entry.modeId === modeId ? { ...entry, modeId: null } : entry)));
351
+ }
352
+ export function pruneLinkedEntityReferences(entityType, entityId) {
353
+ const columnByEntityType = {
354
+ goal: "linked_goal_ids_json",
355
+ project: "linked_project_ids_json",
356
+ task: "linked_task_ids_json"
357
+ };
358
+ const column = columnByEntityType[entityType];
359
+ removeIdFromStringArrayColumn("psyche_values", column, entityId);
360
+ removeIdFromStringArrayColumn("trigger_reports", column, entityId);
361
+ }
362
+ export function getPsycheDomain() {
363
+ const row = getDatabase()
364
+ .prepare(`SELECT id, slug, title, description, theme_color, sensitive, created_at, updated_at
365
+ FROM domains
366
+ WHERE id = ?`)
367
+ .get(PSYCHE_DOMAIN_ID);
368
+ return row ? mapDomain(row) : undefined;
369
+ }
370
+ export function listSchemaCatalog() {
371
+ const rows = getDatabase()
372
+ .prepare(`SELECT id, slug, title, family, schema_type, description, created_at, updated_at
373
+ FROM schema_catalog
374
+ ORDER BY CASE schema_type WHEN 'maladaptive' THEN 0 ELSE 1 END, family, title`)
375
+ .all();
376
+ return rows.map(mapSchemaCatalogEntry);
377
+ }
378
+ export function listEventTypes() {
379
+ const rows = getDatabase()
380
+ .prepare(`SELECT id, domain_id, label, description, system, created_at, updated_at
381
+ FROM event_types
382
+ WHERE domain_id = ?
383
+ ORDER BY system DESC, label`)
384
+ .all(PSYCHE_DOMAIN_ID);
385
+ return filterDeletedEntities("event_type", rows.map(mapEventType));
386
+ }
387
+ export function getEventTypeById(eventTypeId) {
388
+ if (isEntityDeleted("event_type", eventTypeId)) {
389
+ return undefined;
390
+ }
391
+ const row = getRow(`SELECT id, domain_id, label, description, system, created_at, updated_at
392
+ FROM event_types
393
+ WHERE id = ?`, eventTypeId);
394
+ return row ? mapEventType(row) : undefined;
395
+ }
396
+ export function createEventType(input, context) {
397
+ const parsed = createEventTypeSchema.parse(input);
398
+ const now = new Date().toISOString();
399
+ const eventType = eventTypeSchema.parse({
400
+ id: buildId("evt"),
401
+ domainId: PSYCHE_DOMAIN_ID,
402
+ label: parsed.label,
403
+ description: parsed.description,
404
+ system: false,
405
+ createdAt: now,
406
+ updatedAt: now
407
+ });
408
+ getDatabase()
409
+ .prepare(`INSERT INTO event_types (id, domain_id, label, description, system, created_at, updated_at)
410
+ VALUES (?, ?, ?, ?, 0, ?, ?)`)
411
+ .run(eventType.id, eventType.domainId, eventType.label, eventType.description, eventType.createdAt, eventType.updatedAt);
412
+ mapCreateUpdateContext({
413
+ entityType: "event_type",
414
+ entityId: eventType.id,
415
+ title: "Event type added",
416
+ eventKind: "event_type.created",
417
+ source: context.source,
418
+ actor: context.actor ?? null,
419
+ metadata: { domainId: eventType.domainId }
420
+ });
421
+ return eventType;
422
+ }
423
+ export function updateEventType(eventTypeId, patch, context) {
424
+ const existing = getEventTypeById(eventTypeId);
425
+ if (!existing) {
426
+ return undefined;
427
+ }
428
+ const parsed = updateEventTypeSchema.parse(patch);
429
+ const updated = eventTypeSchema.parse({
430
+ ...existing,
431
+ ...parsed,
432
+ updatedAt: new Date().toISOString()
433
+ });
434
+ getDatabase()
435
+ .prepare(`UPDATE event_types
436
+ SET label = ?, description = ?, updated_at = ?
437
+ WHERE id = ?`)
438
+ .run(updated.label, updated.description, updated.updatedAt, eventTypeId);
439
+ mapCreateUpdateContext({
440
+ entityType: "event_type",
441
+ entityId: eventTypeId,
442
+ title: "Event type updated",
443
+ eventKind: "event_type.updated",
444
+ source: context.source,
445
+ actor: context.actor ?? null,
446
+ metadata: { domainId: updated.domainId }
447
+ });
448
+ return updated;
449
+ }
450
+ export function deleteEventType(eventTypeId, context) {
451
+ const existing = getEventTypeById(eventTypeId);
452
+ if (!existing) {
453
+ return undefined;
454
+ }
455
+ return runInTransaction(() => {
456
+ deleteEntityComments("event_type", eventTypeId);
457
+ getDatabase()
458
+ .prepare(`DELETE FROM event_types WHERE id = ?`)
459
+ .run(eventTypeId);
460
+ mapCreateUpdateContext({
461
+ entityType: "event_type",
462
+ entityId: eventTypeId,
463
+ title: "Event type deleted",
464
+ eventKind: "event_type.deleted",
465
+ source: context.source,
466
+ actor: context.actor ?? null,
467
+ metadata: { domainId: existing.domainId }
468
+ });
469
+ return existing;
470
+ });
471
+ }
472
+ export function listEmotionDefinitions() {
473
+ const rows = getDatabase()
474
+ .prepare(`SELECT id, domain_id, label, description, category, system, created_at, updated_at
475
+ FROM emotion_definitions
476
+ WHERE domain_id = ?
477
+ ORDER BY system DESC, label`)
478
+ .all(PSYCHE_DOMAIN_ID);
479
+ return filterDeletedEntities("emotion_definition", rows.map(mapEmotionDefinition));
480
+ }
481
+ export function getEmotionDefinitionById(emotionId) {
482
+ if (isEntityDeleted("emotion_definition", emotionId)) {
483
+ return undefined;
484
+ }
485
+ const row = getRow(`SELECT id, domain_id, label, description, category, system, created_at, updated_at
486
+ FROM emotion_definitions
487
+ WHERE id = ?`, emotionId);
488
+ return row ? mapEmotionDefinition(row) : undefined;
489
+ }
490
+ export function createEmotionDefinition(input, context) {
491
+ const parsed = createEmotionDefinitionSchema.parse(input);
492
+ const now = new Date().toISOString();
493
+ const emotion = emotionDefinitionSchema.parse({
494
+ id: buildId("emo"),
495
+ domainId: PSYCHE_DOMAIN_ID,
496
+ label: parsed.label,
497
+ description: parsed.description,
498
+ category: parsed.category,
499
+ system: false,
500
+ createdAt: now,
501
+ updatedAt: now
502
+ });
503
+ getDatabase()
504
+ .prepare(`INSERT INTO emotion_definitions (id, domain_id, label, description, category, system, created_at, updated_at)
505
+ VALUES (?, ?, ?, ?, ?, 0, ?, ?)`)
506
+ .run(emotion.id, emotion.domainId, emotion.label, emotion.description, emotion.category, emotion.createdAt, emotion.updatedAt);
507
+ mapCreateUpdateContext({
508
+ entityType: "emotion_definition",
509
+ entityId: emotion.id,
510
+ title: "Emotion definition added",
511
+ eventKind: "emotion_definition.created",
512
+ source: context.source,
513
+ actor: context.actor ?? null,
514
+ metadata: { domainId: emotion.domainId }
515
+ });
516
+ return emotion;
517
+ }
518
+ export function updateEmotionDefinition(emotionId, patch, context) {
519
+ const existing = getEmotionDefinitionById(emotionId);
520
+ if (!existing) {
521
+ return undefined;
522
+ }
523
+ const parsed = updateEmotionDefinitionSchema.parse(patch);
524
+ const updated = emotionDefinitionSchema.parse({
525
+ ...existing,
526
+ ...parsed,
527
+ updatedAt: new Date().toISOString()
528
+ });
529
+ getDatabase()
530
+ .prepare(`UPDATE emotion_definitions
531
+ SET label = ?, description = ?, category = ?, updated_at = ?
532
+ WHERE id = ?`)
533
+ .run(updated.label, updated.description, updated.category, updated.updatedAt, emotionId);
534
+ mapCreateUpdateContext({
535
+ entityType: "emotion_definition",
536
+ entityId: emotionId,
537
+ title: "Emotion definition updated",
538
+ eventKind: "emotion_definition.updated",
539
+ source: context.source,
540
+ actor: context.actor ?? null,
541
+ metadata: { domainId: updated.domainId }
542
+ });
543
+ return updated;
544
+ }
545
+ export function deleteEmotionDefinition(emotionId, context) {
546
+ const existing = getEmotionDefinitionById(emotionId);
547
+ if (!existing) {
548
+ return undefined;
549
+ }
550
+ return runInTransaction(() => {
551
+ nullifyTriggerEmotionReferences(emotionId);
552
+ deleteEntityComments("emotion_definition", emotionId);
553
+ getDatabase()
554
+ .prepare(`DELETE FROM emotion_definitions WHERE id = ?`)
555
+ .run(emotionId);
556
+ mapCreateUpdateContext({
557
+ entityType: "emotion_definition",
558
+ entityId: emotionId,
559
+ title: "Emotion definition deleted",
560
+ eventKind: "emotion_definition.deleted",
561
+ source: context.source,
562
+ actor: context.actor ?? null,
563
+ metadata: { domainId: existing.domainId }
564
+ });
565
+ return existing;
566
+ });
567
+ }
568
+ export function listPsycheValues() {
569
+ const rows = getDatabase()
570
+ .prepare(`SELECT
571
+ id, domain_id, title, description, valued_direction, why_it_matters,
572
+ linked_goal_ids_json, linked_project_ids_json, linked_task_ids_json, committed_actions_json, created_at, updated_at
573
+ FROM psyche_values
574
+ WHERE domain_id = ?
575
+ ORDER BY updated_at DESC`)
576
+ .all(PSYCHE_DOMAIN_ID);
577
+ return filterDeletedEntities("psyche_value", rows.map(mapPsycheValue));
578
+ }
579
+ export function getPsycheValueById(valueId) {
580
+ if (isEntityDeleted("psyche_value", valueId)) {
581
+ return undefined;
582
+ }
583
+ const row = getRow(`SELECT
584
+ id, domain_id, title, description, valued_direction, why_it_matters,
585
+ linked_goal_ids_json, linked_project_ids_json, linked_task_ids_json, committed_actions_json, created_at, updated_at
586
+ FROM psyche_values
587
+ WHERE id = ?`, valueId);
588
+ return row ? mapPsycheValue(row) : undefined;
589
+ }
590
+ export function createPsycheValue(input, context) {
591
+ const parsed = createPsycheValueSchema.parse(input);
592
+ const now = new Date().toISOString();
593
+ const value = psycheValueSchema.parse({
594
+ id: buildId("psy"),
595
+ domainId: PSYCHE_DOMAIN_ID,
596
+ title: parsed.title,
597
+ description: parsed.description,
598
+ valuedDirection: parsed.valuedDirection,
599
+ whyItMatters: parsed.whyItMatters,
600
+ linkedGoalIds: parsed.linkedGoalIds,
601
+ linkedProjectIds: parsed.linkedProjectIds,
602
+ linkedTaskIds: parsed.linkedTaskIds,
603
+ committedActions: parsed.committedActions,
604
+ createdAt: now,
605
+ updatedAt: now
606
+ });
607
+ getDatabase()
608
+ .prepare(`INSERT INTO psyche_values (
609
+ id, domain_id, title, description, valued_direction, why_it_matters, linked_goal_ids_json, linked_project_ids_json,
610
+ linked_task_ids_json, committed_actions_json, created_at, updated_at
611
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
612
+ .run(value.id, value.domainId, value.title, value.description, value.valuedDirection, value.whyItMatters, JSON.stringify(value.linkedGoalIds), JSON.stringify(value.linkedProjectIds), JSON.stringify(value.linkedTaskIds), JSON.stringify(value.committedActions), value.createdAt, value.updatedAt);
613
+ mapCreateUpdateContext({
614
+ entityType: "psyche_value",
615
+ entityId: value.id,
616
+ title: "Psyche value added",
617
+ eventKind: "psyche_value.created",
618
+ source: context.source,
619
+ actor: context.actor ?? null,
620
+ metadata: { domainId: value.domainId }
621
+ });
622
+ recordPsycheClarityReward("psyche_value", value.id, value.title, "psyche_value_defined", context);
623
+ return value;
624
+ }
625
+ export function updatePsycheValue(valueId, patch, context) {
626
+ const existing = getPsycheValueById(valueId);
627
+ if (!existing) {
628
+ return undefined;
629
+ }
630
+ const parsed = updatePsycheValueSchema.parse(patch);
631
+ const updated = psycheValueSchema.parse({
632
+ ...existing,
633
+ ...parsed,
634
+ committedActions: parsed.committedActions ?? existing.committedActions,
635
+ updatedAt: new Date().toISOString()
636
+ });
637
+ getDatabase()
638
+ .prepare(`UPDATE psyche_values
639
+ SET title = ?, description = ?, valued_direction = ?, why_it_matters = ?, linked_goal_ids_json = ?,
640
+ linked_project_ids_json = ?, linked_task_ids_json = ?, committed_actions_json = ?, updated_at = ?
641
+ WHERE id = ?`)
642
+ .run(updated.title, updated.description, updated.valuedDirection, updated.whyItMatters, JSON.stringify(updated.linkedGoalIds), JSON.stringify(updated.linkedProjectIds), JSON.stringify(updated.linkedTaskIds), JSON.stringify(updated.committedActions), updated.updatedAt, valueId);
643
+ mapCreateUpdateContext({
644
+ entityType: "psyche_value",
645
+ entityId: valueId,
646
+ title: "Psyche value updated",
647
+ eventKind: "psyche_value.updated",
648
+ source: context.source,
649
+ actor: context.actor ?? null,
650
+ metadata: { domainId: updated.domainId }
651
+ });
652
+ return updated;
653
+ }
654
+ export function deletePsycheValue(valueId, context) {
655
+ const existing = getPsycheValueById(valueId);
656
+ if (!existing) {
657
+ return undefined;
658
+ }
659
+ return runInTransaction(() => {
660
+ removeIdFromStringArrayColumn("behavior_patterns", "linked_value_ids_json", valueId);
661
+ removeIdFromStringArrayColumn("psyche_behaviors", "linked_value_ids_json", valueId);
662
+ removeIdFromStringArrayColumn("belief_entries", "linked_value_ids_json", valueId);
663
+ removeIdFromStringArrayColumn("mode_profiles", "linked_value_ids_json", valueId);
664
+ removeIdFromStringArrayColumn("trigger_reports", "linked_value_ids_json", valueId);
665
+ deleteEntityComments("psyche_value", valueId);
666
+ getDatabase()
667
+ .prepare(`DELETE FROM psyche_values WHERE id = ?`)
668
+ .run(valueId);
669
+ mapCreateUpdateContext({
670
+ entityType: "psyche_value",
671
+ entityId: valueId,
672
+ title: "Psyche value deleted",
673
+ eventKind: "psyche_value.deleted",
674
+ source: context.source,
675
+ actor: context.actor ?? null,
676
+ metadata: { domainId: existing.domainId }
677
+ });
678
+ return existing;
679
+ });
680
+ }
681
+ export function listBehaviorPatterns() {
682
+ const rows = getDatabase()
683
+ .prepare(`SELECT
684
+ id, domain_id, title, description, target_behavior, cue_contexts_json, short_term_payoff, long_term_cost,
685
+ preferred_response, linked_value_ids_json, linked_schema_labels_json, linked_mode_labels_json, linked_mode_ids_json,
686
+ linked_belief_ids_json, created_at, updated_at
687
+ FROM behavior_patterns
688
+ WHERE domain_id = ?
689
+ ORDER BY updated_at DESC`)
690
+ .all(PSYCHE_DOMAIN_ID);
691
+ return filterDeletedEntities("behavior_pattern", rows.map(mapBehaviorPattern));
692
+ }
693
+ export function getBehaviorPatternById(patternId) {
694
+ if (isEntityDeleted("behavior_pattern", patternId)) {
695
+ return undefined;
696
+ }
697
+ const row = getRow(`SELECT
698
+ id, domain_id, title, description, target_behavior, cue_contexts_json, short_term_payoff, long_term_cost,
699
+ preferred_response, linked_value_ids_json, linked_schema_labels_json, linked_mode_labels_json, linked_mode_ids_json,
700
+ linked_belief_ids_json, created_at, updated_at
701
+ FROM behavior_patterns
702
+ WHERE id = ?`, patternId);
703
+ return row ? mapBehaviorPattern(row) : undefined;
704
+ }
705
+ export function createBehaviorPattern(input, context) {
706
+ const parsed = createBehaviorPatternSchema.parse(input);
707
+ const now = new Date().toISOString();
708
+ const pattern = behaviorPatternSchema.parse({
709
+ id: buildId("pat"),
710
+ domainId: PSYCHE_DOMAIN_ID,
711
+ title: parsed.title,
712
+ description: parsed.description,
713
+ targetBehavior: parsed.targetBehavior,
714
+ cueContexts: parsed.cueContexts,
715
+ shortTermPayoff: parsed.shortTermPayoff,
716
+ longTermCost: parsed.longTermCost,
717
+ preferredResponse: parsed.preferredResponse,
718
+ linkedValueIds: parsed.linkedValueIds,
719
+ linkedSchemaLabels: parsed.linkedSchemaLabels,
720
+ linkedModeLabels: parsed.linkedModeLabels,
721
+ linkedModeIds: parsed.linkedModeIds,
722
+ linkedBeliefIds: parsed.linkedBeliefIds,
723
+ createdAt: now,
724
+ updatedAt: now
725
+ });
726
+ getDatabase()
727
+ .prepare(`INSERT INTO behavior_patterns (
728
+ id, domain_id, title, description, target_behavior, cue_contexts_json, short_term_payoff, long_term_cost,
729
+ preferred_response, linked_value_ids_json, linked_schema_labels_json, linked_mode_labels_json, linked_mode_ids_json,
730
+ linked_belief_ids_json, created_at, updated_at
731
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
732
+ .run(pattern.id, pattern.domainId, pattern.title, pattern.description, pattern.targetBehavior, JSON.stringify(pattern.cueContexts), pattern.shortTermPayoff, pattern.longTermCost, pattern.preferredResponse, JSON.stringify(pattern.linkedValueIds), JSON.stringify(pattern.linkedSchemaLabels), JSON.stringify(pattern.linkedModeLabels), JSON.stringify(pattern.linkedModeIds), JSON.stringify(pattern.linkedBeliefIds), pattern.createdAt, pattern.updatedAt);
733
+ mapCreateUpdateContext({
734
+ entityType: "behavior_pattern",
735
+ entityId: pattern.id,
736
+ title: "Behavior pattern added",
737
+ eventKind: "behavior_pattern.created",
738
+ source: context.source,
739
+ actor: context.actor ?? null,
740
+ metadata: { domainId: pattern.domainId }
741
+ });
742
+ recordPsycheClarityReward("behavior_pattern", pattern.id, pattern.title, "psyche_pattern_defined", context);
743
+ return pattern;
744
+ }
745
+ export function updateBehaviorPattern(patternId, patch, context) {
746
+ const existing = getBehaviorPatternById(patternId);
747
+ if (!existing) {
748
+ return undefined;
749
+ }
750
+ const parsed = updateBehaviorPatternSchema.parse(patch);
751
+ const updated = behaviorPatternSchema.parse({
752
+ ...existing,
753
+ ...parsed,
754
+ updatedAt: new Date().toISOString()
755
+ });
756
+ getDatabase()
757
+ .prepare(`UPDATE behavior_patterns
758
+ SET title = ?, description = ?, target_behavior = ?, cue_contexts_json = ?, short_term_payoff = ?, long_term_cost = ?,
759
+ preferred_response = ?, linked_value_ids_json = ?, linked_schema_labels_json = ?, linked_mode_labels_json = ?,
760
+ linked_mode_ids_json = ?, linked_belief_ids_json = ?, updated_at = ?
761
+ WHERE id = ?`)
762
+ .run(updated.title, updated.description, updated.targetBehavior, JSON.stringify(updated.cueContexts), updated.shortTermPayoff, updated.longTermCost, updated.preferredResponse, JSON.stringify(updated.linkedValueIds), JSON.stringify(updated.linkedSchemaLabels), JSON.stringify(updated.linkedModeLabels), JSON.stringify(updated.linkedModeIds), JSON.stringify(updated.linkedBeliefIds), updated.updatedAt, patternId);
763
+ mapCreateUpdateContext({
764
+ entityType: "behavior_pattern",
765
+ entityId: patternId,
766
+ title: "Behavior pattern updated",
767
+ eventKind: "behavior_pattern.updated",
768
+ source: context.source,
769
+ actor: context.actor ?? null,
770
+ metadata: { domainId: updated.domainId }
771
+ });
772
+ return updated;
773
+ }
774
+ export function deleteBehaviorPattern(patternId, context) {
775
+ const existing = getBehaviorPatternById(patternId);
776
+ if (!existing) {
777
+ return undefined;
778
+ }
779
+ return runInTransaction(() => {
780
+ removeIdFromStringArrayColumn("psyche_behaviors", "linked_pattern_ids_json", patternId);
781
+ removeIdFromStringArrayColumn("mode_profiles", "linked_pattern_ids_json", patternId);
782
+ removeIdFromStringArrayColumn("trigger_reports", "linked_pattern_ids_json", patternId);
783
+ deleteEntityComments("behavior_pattern", patternId);
784
+ getDatabase()
785
+ .prepare(`DELETE FROM behavior_patterns WHERE id = ?`)
786
+ .run(patternId);
787
+ mapCreateUpdateContext({
788
+ entityType: "behavior_pattern",
789
+ entityId: patternId,
790
+ title: "Behavior pattern deleted",
791
+ eventKind: "behavior_pattern.deleted",
792
+ source: context.source,
793
+ actor: context.actor ?? null,
794
+ metadata: { domainId: existing.domainId }
795
+ });
796
+ return existing;
797
+ });
798
+ }
799
+ export function listBehaviors() {
800
+ const rows = getDatabase()
801
+ .prepare(`SELECT
802
+ id, domain_id, kind, title, description, common_cues_json, urge_story, short_term_payoff, long_term_cost,
803
+ replacement_move, repair_plan, linked_pattern_ids_json, linked_value_ids_json, linked_schema_ids_json,
804
+ linked_mode_ids_json, created_at, updated_at
805
+ FROM psyche_behaviors
806
+ WHERE domain_id = ?
807
+ ORDER BY kind, updated_at DESC`)
808
+ .all(PSYCHE_DOMAIN_ID);
809
+ return filterDeletedEntities("behavior", rows.map(mapBehavior));
810
+ }
811
+ export function getBehaviorById(behaviorId) {
812
+ if (isEntityDeleted("behavior", behaviorId)) {
813
+ return undefined;
814
+ }
815
+ const row = getRow(`SELECT
816
+ id, domain_id, kind, title, description, common_cues_json, urge_story, short_term_payoff, long_term_cost,
817
+ replacement_move, repair_plan, linked_pattern_ids_json, linked_value_ids_json, linked_schema_ids_json,
818
+ linked_mode_ids_json, created_at, updated_at
819
+ FROM psyche_behaviors
820
+ WHERE id = ?`, behaviorId);
821
+ return row ? mapBehavior(row) : undefined;
822
+ }
823
+ export function createBehavior(input, context) {
824
+ const parsed = createBehaviorSchema.parse(input);
825
+ const now = new Date().toISOString();
826
+ const behavior = behaviorSchema.parse({
827
+ id: buildId("bhv"),
828
+ domainId: PSYCHE_DOMAIN_ID,
829
+ ...parsed,
830
+ createdAt: now,
831
+ updatedAt: now
832
+ });
833
+ getDatabase()
834
+ .prepare(`INSERT INTO psyche_behaviors (
835
+ id, domain_id, kind, title, description, common_cues_json, urge_story, short_term_payoff, long_term_cost,
836
+ replacement_move, repair_plan, linked_pattern_ids_json, linked_value_ids_json, linked_schema_ids_json, linked_mode_ids_json,
837
+ created_at, updated_at
838
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
839
+ .run(behavior.id, behavior.domainId, behavior.kind, behavior.title, behavior.description, JSON.stringify(behavior.commonCues), behavior.urgeStory, behavior.shortTermPayoff, behavior.longTermCost, behavior.replacementMove, behavior.repairPlan, JSON.stringify(behavior.linkedPatternIds), JSON.stringify(behavior.linkedValueIds), JSON.stringify(behavior.linkedSchemaIds), JSON.stringify(behavior.linkedModeIds), behavior.createdAt, behavior.updatedAt);
840
+ mapCreateUpdateContext({
841
+ entityType: "behavior",
842
+ entityId: behavior.id,
843
+ title: "Behavior added",
844
+ eventKind: "behavior.created",
845
+ source: context.source,
846
+ actor: context.actor ?? null,
847
+ metadata: { kind: behavior.kind, domainId: behavior.domainId }
848
+ });
849
+ recordPsycheClarityReward("behavior", behavior.id, behavior.title, "psyche_behavior_defined", context);
850
+ return behavior;
851
+ }
852
+ export function updateBehavior(behaviorId, patch, context) {
853
+ const existing = getBehaviorById(behaviorId);
854
+ if (!existing) {
855
+ return undefined;
856
+ }
857
+ const parsed = updateBehaviorSchema.parse(patch);
858
+ const updated = behaviorSchema.parse({
859
+ ...existing,
860
+ ...parsed,
861
+ updatedAt: new Date().toISOString()
862
+ });
863
+ getDatabase()
864
+ .prepare(`UPDATE psyche_behaviors
865
+ SET kind = ?, title = ?, description = ?, common_cues_json = ?, urge_story = ?, short_term_payoff = ?, long_term_cost = ?,
866
+ replacement_move = ?, repair_plan = ?, linked_pattern_ids_json = ?, linked_value_ids_json = ?, linked_schema_ids_json = ?,
867
+ linked_mode_ids_json = ?, updated_at = ?
868
+ WHERE id = ?`)
869
+ .run(updated.kind, updated.title, updated.description, JSON.stringify(updated.commonCues), updated.urgeStory, updated.shortTermPayoff, updated.longTermCost, updated.replacementMove, updated.repairPlan, JSON.stringify(updated.linkedPatternIds), JSON.stringify(updated.linkedValueIds), JSON.stringify(updated.linkedSchemaIds), JSON.stringify(updated.linkedModeIds), updated.updatedAt, behaviorId);
870
+ mapCreateUpdateContext({
871
+ entityType: "behavior",
872
+ entityId: behaviorId,
873
+ title: "Behavior updated",
874
+ eventKind: "behavior.updated",
875
+ source: context.source,
876
+ actor: context.actor ?? null,
877
+ metadata: { kind: updated.kind, domainId: updated.domainId }
878
+ });
879
+ return updated;
880
+ }
881
+ export function deleteBehavior(behaviorId, context) {
882
+ const existing = getBehaviorById(behaviorId);
883
+ if (!existing) {
884
+ return undefined;
885
+ }
886
+ return runInTransaction(() => {
887
+ removeIdFromStringArrayColumn("belief_entries", "linked_behavior_ids_json", behaviorId);
888
+ removeIdFromStringArrayColumn("mode_profiles", "linked_behavior_ids_json", behaviorId);
889
+ removeIdFromStringArrayColumn("trigger_reports", "linked_behavior_ids_json", behaviorId);
890
+ nullifyTriggerBehaviorReferences(behaviorId);
891
+ deleteEntityComments("behavior", behaviorId);
892
+ getDatabase()
893
+ .prepare(`DELETE FROM psyche_behaviors WHERE id = ?`)
894
+ .run(behaviorId);
895
+ mapCreateUpdateContext({
896
+ entityType: "behavior",
897
+ entityId: behaviorId,
898
+ title: "Behavior deleted",
899
+ eventKind: "behavior.deleted",
900
+ source: context.source,
901
+ actor: context.actor ?? null,
902
+ metadata: { kind: existing.kind, domainId: existing.domainId }
903
+ });
904
+ return existing;
905
+ });
906
+ }
907
+ export function listBeliefEntries() {
908
+ const rows = getDatabase()
909
+ .prepare(`SELECT
910
+ id, domain_id, schema_id, statement, belief_type, origin_note, confidence, evidence_for_json, evidence_against_json,
911
+ flexible_alternative, linked_value_ids_json, linked_behavior_ids_json, linked_mode_ids_json, linked_report_ids_json,
912
+ created_at, updated_at
913
+ FROM belief_entries
914
+ WHERE domain_id = ?
915
+ ORDER BY updated_at DESC`)
916
+ .all(PSYCHE_DOMAIN_ID);
917
+ return filterDeletedEntities("belief_entry", rows.map(mapBeliefEntry));
918
+ }
919
+ export function getBeliefEntryById(beliefId) {
920
+ if (isEntityDeleted("belief_entry", beliefId)) {
921
+ return undefined;
922
+ }
923
+ const row = getRow(`SELECT
924
+ id, domain_id, schema_id, statement, belief_type, origin_note, confidence, evidence_for_json, evidence_against_json,
925
+ flexible_alternative, linked_value_ids_json, linked_behavior_ids_json, linked_mode_ids_json, linked_report_ids_json,
926
+ created_at, updated_at
927
+ FROM belief_entries
928
+ WHERE id = ?`, beliefId);
929
+ return row ? mapBeliefEntry(row) : undefined;
930
+ }
931
+ export function createBeliefEntry(input, context) {
932
+ const parsed = createBeliefEntrySchema.parse(input);
933
+ const now = new Date().toISOString();
934
+ const belief = beliefEntrySchema.parse({
935
+ id: buildId("blf"),
936
+ domainId: PSYCHE_DOMAIN_ID,
937
+ ...parsed,
938
+ createdAt: now,
939
+ updatedAt: now
940
+ });
941
+ getDatabase()
942
+ .prepare(`INSERT INTO belief_entries (
943
+ id, domain_id, schema_id, statement, belief_type, origin_note, confidence, evidence_for_json, evidence_against_json,
944
+ flexible_alternative, linked_value_ids_json, linked_behavior_ids_json, linked_mode_ids_json, linked_report_ids_json,
945
+ created_at, updated_at
946
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
947
+ .run(belief.id, belief.domainId, belief.schemaId, belief.statement, belief.beliefType, belief.originNote, belief.confidence, JSON.stringify(belief.evidenceFor), JSON.stringify(belief.evidenceAgainst), belief.flexibleAlternative, JSON.stringify(belief.linkedValueIds), JSON.stringify(belief.linkedBehaviorIds), JSON.stringify(belief.linkedModeIds), JSON.stringify(belief.linkedReportIds), belief.createdAt, belief.updatedAt);
948
+ mapCreateUpdateContext({
949
+ entityType: "belief_entry",
950
+ entityId: belief.id,
951
+ title: "Belief captured",
952
+ eventKind: "belief_entry.created",
953
+ source: context.source,
954
+ actor: context.actor ?? null,
955
+ metadata: { schemaId: belief.schemaId ?? "" }
956
+ });
957
+ recordPsycheClarityReward("belief_entry", belief.id, belief.statement, "psyche_belief_captured", context);
958
+ return belief;
959
+ }
960
+ export function updateBeliefEntry(beliefId, patch, context) {
961
+ const existing = getBeliefEntryById(beliefId);
962
+ if (!existing) {
963
+ return undefined;
964
+ }
965
+ const parsed = updateBeliefEntrySchema.parse(patch);
966
+ const updated = beliefEntrySchema.parse({
967
+ ...existing,
968
+ ...parsed,
969
+ updatedAt: new Date().toISOString()
970
+ });
971
+ getDatabase()
972
+ .prepare(`UPDATE belief_entries
973
+ SET schema_id = ?, statement = ?, belief_type = ?, origin_note = ?, confidence = ?, evidence_for_json = ?,
974
+ evidence_against_json = ?, flexible_alternative = ?, linked_value_ids_json = ?, linked_behavior_ids_json = ?,
975
+ linked_mode_ids_json = ?, linked_report_ids_json = ?, updated_at = ?
976
+ WHERE id = ?`)
977
+ .run(updated.schemaId, updated.statement, updated.beliefType, updated.originNote, updated.confidence, JSON.stringify(updated.evidenceFor), JSON.stringify(updated.evidenceAgainst), updated.flexibleAlternative, JSON.stringify(updated.linkedValueIds), JSON.stringify(updated.linkedBehaviorIds), JSON.stringify(updated.linkedModeIds), JSON.stringify(updated.linkedReportIds), updated.updatedAt, beliefId);
978
+ mapCreateUpdateContext({
979
+ entityType: "belief_entry",
980
+ entityId: beliefId,
981
+ title: "Belief updated",
982
+ eventKind: "belief_entry.updated",
983
+ source: context.source,
984
+ actor: context.actor ?? null,
985
+ metadata: { schemaId: updated.schemaId ?? "" }
986
+ });
987
+ return updated;
988
+ }
989
+ export function deleteBeliefEntry(beliefId, context) {
990
+ const existing = getBeliefEntryById(beliefId);
991
+ if (!existing) {
992
+ return undefined;
993
+ }
994
+ return runInTransaction(() => {
995
+ removeIdFromStringArrayColumn("behavior_patterns", "linked_belief_ids_json", beliefId);
996
+ removeIdFromStringArrayColumn("trigger_reports", "linked_belief_ids_json", beliefId);
997
+ nullifyTriggerThoughtBeliefReferences(beliefId);
998
+ deleteEntityComments("belief_entry", beliefId);
999
+ getDatabase()
1000
+ .prepare(`DELETE FROM belief_entries WHERE id = ?`)
1001
+ .run(beliefId);
1002
+ mapCreateUpdateContext({
1003
+ entityType: "belief_entry",
1004
+ entityId: beliefId,
1005
+ title: "Belief deleted",
1006
+ eventKind: "belief_entry.deleted",
1007
+ source: context.source,
1008
+ actor: context.actor ?? null,
1009
+ metadata: { schemaId: existing.schemaId ?? "" }
1010
+ });
1011
+ return existing;
1012
+ });
1013
+ }
1014
+ export function listModeProfiles() {
1015
+ const rows = getDatabase()
1016
+ .prepare(`SELECT
1017
+ id, domain_id, family, archetype, title, persona, imagery, symbolic_form, facial_expression, fear, burden, protective_job,
1018
+ origin_context, first_appearance_at, linked_pattern_ids_json, linked_behavior_ids_json, linked_value_ids_json, created_at, updated_at
1019
+ FROM mode_profiles
1020
+ WHERE domain_id = ?
1021
+ ORDER BY family, updated_at DESC`)
1022
+ .all(PSYCHE_DOMAIN_ID);
1023
+ return filterDeletedEntities("mode_profile", rows.map(mapModeProfile));
1024
+ }
1025
+ export function getModeProfileById(modeId) {
1026
+ if (isEntityDeleted("mode_profile", modeId)) {
1027
+ return undefined;
1028
+ }
1029
+ const row = getRow(`SELECT
1030
+ id, domain_id, family, archetype, title, persona, imagery, symbolic_form, facial_expression, fear, burden, protective_job,
1031
+ origin_context, first_appearance_at, linked_pattern_ids_json, linked_behavior_ids_json, linked_value_ids_json, created_at, updated_at
1032
+ FROM mode_profiles
1033
+ WHERE id = ?`, modeId);
1034
+ return row ? mapModeProfile(row) : undefined;
1035
+ }
1036
+ export function createModeProfile(input, context) {
1037
+ const parsed = createModeProfileSchema.parse(input);
1038
+ const now = new Date().toISOString();
1039
+ const mode = modeProfileSchema.parse({
1040
+ id: buildId("mod"),
1041
+ domainId: PSYCHE_DOMAIN_ID,
1042
+ ...parsed,
1043
+ createdAt: now,
1044
+ updatedAt: now
1045
+ });
1046
+ getDatabase()
1047
+ .prepare(`INSERT INTO mode_profiles (
1048
+ id, domain_id, family, archetype, title, persona, imagery, symbolic_form, facial_expression, fear, burden, protective_job,
1049
+ origin_context, first_appearance_at, linked_pattern_ids_json, linked_behavior_ids_json, linked_value_ids_json, created_at, updated_at
1050
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
1051
+ .run(mode.id, mode.domainId, mode.family, mode.archetype, mode.title, mode.persona, mode.imagery, mode.symbolicForm, mode.facialExpression, mode.fear, mode.burden, mode.protectiveJob, mode.originContext, mode.firstAppearanceAt, JSON.stringify(mode.linkedPatternIds), JSON.stringify(mode.linkedBehaviorIds), JSON.stringify(mode.linkedValueIds), mode.createdAt, mode.updatedAt);
1052
+ mapCreateUpdateContext({
1053
+ entityType: "mode_profile",
1054
+ entityId: mode.id,
1055
+ title: "Mode profile added",
1056
+ eventKind: "mode_profile.created",
1057
+ source: context.source,
1058
+ actor: context.actor ?? null,
1059
+ metadata: { family: mode.family }
1060
+ });
1061
+ recordPsycheClarityReward("mode_profile", mode.id, mode.title, "psyche_mode_named", context);
1062
+ return mode;
1063
+ }
1064
+ export function updateModeProfile(modeId, patch, context) {
1065
+ const existing = getModeProfileById(modeId);
1066
+ if (!existing) {
1067
+ return undefined;
1068
+ }
1069
+ const parsed = updateModeProfileSchema.parse(patch);
1070
+ if (parsed.family) {
1071
+ modeFamilySchema.parse(parsed.family);
1072
+ }
1073
+ const updated = modeProfileSchema.parse({
1074
+ ...existing,
1075
+ ...parsed,
1076
+ updatedAt: new Date().toISOString()
1077
+ });
1078
+ getDatabase()
1079
+ .prepare(`UPDATE mode_profiles
1080
+ SET family = ?, archetype = ?, title = ?, persona = ?, imagery = ?, symbolic_form = ?, facial_expression = ?, fear = ?,
1081
+ burden = ?, protective_job = ?, origin_context = ?, first_appearance_at = ?, linked_pattern_ids_json = ?,
1082
+ linked_behavior_ids_json = ?, linked_value_ids_json = ?, updated_at = ?
1083
+ WHERE id = ?`)
1084
+ .run(updated.family, updated.archetype, updated.title, updated.persona, updated.imagery, updated.symbolicForm, updated.facialExpression, updated.fear, updated.burden, updated.protectiveJob, updated.originContext, updated.firstAppearanceAt, JSON.stringify(updated.linkedPatternIds), JSON.stringify(updated.linkedBehaviorIds), JSON.stringify(updated.linkedValueIds), updated.updatedAt, modeId);
1085
+ mapCreateUpdateContext({
1086
+ entityType: "mode_profile",
1087
+ entityId: modeId,
1088
+ title: "Mode profile updated",
1089
+ eventKind: "mode_profile.updated",
1090
+ source: context.source,
1091
+ actor: context.actor ?? null,
1092
+ metadata: { family: updated.family }
1093
+ });
1094
+ return updated;
1095
+ }
1096
+ export function deleteModeProfile(modeId, context) {
1097
+ const existing = getModeProfileById(modeId);
1098
+ if (!existing) {
1099
+ return undefined;
1100
+ }
1101
+ return runInTransaction(() => {
1102
+ removeIdFromStringArrayColumn("behavior_patterns", "linked_mode_ids_json", modeId);
1103
+ removeIdFromStringArrayColumn("psyche_behaviors", "linked_mode_ids_json", modeId);
1104
+ removeIdFromStringArrayColumn("belief_entries", "linked_mode_ids_json", modeId);
1105
+ removeIdFromStringArrayColumn("trigger_reports", "linked_mode_ids_json", modeId);
1106
+ nullifyTriggerTimelineModeReferences(modeId);
1107
+ deleteEntityComments("mode_profile", modeId);
1108
+ getDatabase()
1109
+ .prepare(`DELETE FROM mode_profiles WHERE id = ?`)
1110
+ .run(modeId);
1111
+ mapCreateUpdateContext({
1112
+ entityType: "mode_profile",
1113
+ entityId: modeId,
1114
+ title: "Mode profile deleted",
1115
+ eventKind: "mode_profile.deleted",
1116
+ source: context.source,
1117
+ actor: context.actor ?? null,
1118
+ metadata: { family: existing.family }
1119
+ });
1120
+ return existing;
1121
+ });
1122
+ }
1123
+ export function listModeGuideSessions(limit = 20) {
1124
+ const rows = getDatabase()
1125
+ .prepare(`SELECT id, summary, answers_json, results_json, created_at, updated_at
1126
+ FROM mode_guide_sessions
1127
+ ORDER BY created_at DESC
1128
+ LIMIT ?`)
1129
+ .all(limit);
1130
+ return filterDeletedEntities("mode_guide_session", rows.map(mapModeGuideSession));
1131
+ }
1132
+ export function getModeGuideSessionById(sessionId) {
1133
+ if (isEntityDeleted("mode_guide_session", sessionId)) {
1134
+ return undefined;
1135
+ }
1136
+ const row = getRow(`SELECT id, summary, answers_json, results_json, created_at, updated_at
1137
+ FROM mode_guide_sessions
1138
+ WHERE id = ?`, sessionId);
1139
+ return row ? mapModeGuideSession(row) : undefined;
1140
+ }
1141
+ export function createModeGuideSession(input, context) {
1142
+ const parsed = createModeGuideSessionSchema.parse(input);
1143
+ const now = new Date().toISOString();
1144
+ const session = modeGuideSessionSchema.parse({
1145
+ id: buildId("mgs"),
1146
+ summary: parsed.summary,
1147
+ answers: parsed.answers,
1148
+ results: scoreModeGuideSession(parsed),
1149
+ createdAt: now,
1150
+ updatedAt: now
1151
+ });
1152
+ getDatabase()
1153
+ .prepare(`INSERT INTO mode_guide_sessions (id, summary, answers_json, results_json, created_at, updated_at)
1154
+ VALUES (?, ?, ?, ?, ?, ?)`)
1155
+ .run(session.id, session.summary, JSON.stringify(session.answers), JSON.stringify(session.results), session.createdAt, session.updatedAt);
1156
+ recordEventLog({
1157
+ eventKind: "mode_guide_session.created",
1158
+ entityType: "system",
1159
+ entityId: session.id,
1160
+ actor: context.actor ?? null,
1161
+ source: context.source,
1162
+ metadata: { summary: session.summary }
1163
+ });
1164
+ return session;
1165
+ }
1166
+ export function updateModeGuideSession(sessionId, patch, context) {
1167
+ const existing = getModeGuideSessionById(sessionId);
1168
+ if (!existing) {
1169
+ return undefined;
1170
+ }
1171
+ const parsed = updateModeGuideSessionSchema.parse(patch);
1172
+ const summary = parsed.summary ?? existing.summary;
1173
+ const answers = parsed.answers ?? existing.answers;
1174
+ const updated = modeGuideSessionSchema.parse({
1175
+ ...existing,
1176
+ summary,
1177
+ answers,
1178
+ results: scoreModeGuideSession({ summary, answers }),
1179
+ updatedAt: new Date().toISOString()
1180
+ });
1181
+ getDatabase()
1182
+ .prepare(`UPDATE mode_guide_sessions
1183
+ SET summary = ?, answers_json = ?, results_json = ?, updated_at = ?
1184
+ WHERE id = ?`)
1185
+ .run(updated.summary, JSON.stringify(updated.answers), JSON.stringify(updated.results), updated.updatedAt, sessionId);
1186
+ recordEventLog({
1187
+ eventKind: "mode_guide_session.updated",
1188
+ entityType: "system",
1189
+ entityId: sessionId,
1190
+ actor: context.actor ?? null,
1191
+ source: context.source,
1192
+ metadata: { summary: updated.summary }
1193
+ });
1194
+ return updated;
1195
+ }
1196
+ export function deleteModeGuideSession(sessionId, context) {
1197
+ const existing = getModeGuideSessionById(sessionId);
1198
+ if (!existing) {
1199
+ return undefined;
1200
+ }
1201
+ return runInTransaction(() => {
1202
+ getDatabase()
1203
+ .prepare(`DELETE FROM mode_guide_sessions WHERE id = ?`)
1204
+ .run(sessionId);
1205
+ recordEventLog({
1206
+ eventKind: "mode_guide_session.deleted",
1207
+ entityType: "system",
1208
+ entityId: sessionId,
1209
+ actor: context.actor ?? null,
1210
+ source: context.source,
1211
+ metadata: { summary: existing.summary }
1212
+ });
1213
+ return existing;
1214
+ });
1215
+ }
1216
+ export function listTriggerReports(limit) {
1217
+ const limitSql = limit ? "LIMIT ?" : "";
1218
+ const rows = getDatabase()
1219
+ .prepare(`SELECT
1220
+ id, domain_id, title, status, event_type_id, custom_event_type, event_situation, occurred_at, emotions_json, thoughts_json,
1221
+ behaviors_json, consequences_json, linked_pattern_ids_json, linked_value_ids_json, linked_goal_ids_json, linked_project_ids_json,
1222
+ linked_task_ids_json, linked_behavior_ids_json, linked_belief_ids_json, linked_mode_ids_json, mode_overlays_json,
1223
+ schema_links_json, mode_timeline_json, next_moves_json, created_at, updated_at
1224
+ FROM trigger_reports
1225
+ WHERE domain_id = ?
1226
+ ORDER BY updated_at DESC
1227
+ ${limitSql}`)
1228
+ .all(...(limit ? [PSYCHE_DOMAIN_ID, limit] : [PSYCHE_DOMAIN_ID]));
1229
+ return filterDeletedEntities("trigger_report", rows.map(mapTriggerReport));
1230
+ }
1231
+ export function getTriggerReportById(reportId) {
1232
+ if (isEntityDeleted("trigger_report", reportId)) {
1233
+ return undefined;
1234
+ }
1235
+ const row = getRow(`SELECT
1236
+ id, domain_id, title, status, event_type_id, custom_event_type, event_situation, occurred_at, emotions_json, thoughts_json,
1237
+ behaviors_json, consequences_json, linked_pattern_ids_json, linked_value_ids_json, linked_goal_ids_json, linked_project_ids_json,
1238
+ linked_task_ids_json, linked_behavior_ids_json, linked_belief_ids_json, linked_mode_ids_json, mode_overlays_json,
1239
+ schema_links_json, mode_timeline_json, next_moves_json, created_at, updated_at
1240
+ FROM trigger_reports
1241
+ WHERE id = ?`, reportId);
1242
+ return row ? mapTriggerReport(row) : undefined;
1243
+ }
1244
+ export function createTriggerReport(input, context) {
1245
+ const parsed = createTriggerReportSchema.parse(input);
1246
+ const now = new Date().toISOString();
1247
+ const report = triggerReportSchema.parse({
1248
+ id: buildId("trg"),
1249
+ domainId: PSYCHE_DOMAIN_ID,
1250
+ title: parsed.title,
1251
+ status: parsed.status,
1252
+ eventTypeId: parsed.eventTypeId,
1253
+ customEventType: parsed.customEventType,
1254
+ eventSituation: parsed.eventSituation,
1255
+ occurredAt: parsed.occurredAt,
1256
+ emotions: enrichTriggerItems(parsed.emotions, "emo"),
1257
+ thoughts: enrichTriggerItems(parsed.thoughts, "tht"),
1258
+ behaviors: enrichTriggerItems(parsed.behaviors, "beh"),
1259
+ consequences: parsed.consequences,
1260
+ linkedPatternIds: parsed.linkedPatternIds,
1261
+ linkedValueIds: parsed.linkedValueIds,
1262
+ linkedGoalIds: parsed.linkedGoalIds,
1263
+ linkedProjectIds: parsed.linkedProjectIds,
1264
+ linkedTaskIds: parsed.linkedTaskIds,
1265
+ linkedBehaviorIds: parsed.linkedBehaviorIds,
1266
+ linkedBeliefIds: parsed.linkedBeliefIds,
1267
+ linkedModeIds: parsed.linkedModeIds,
1268
+ modeOverlays: parsed.modeOverlays,
1269
+ schemaLinks: parsed.schemaLinks,
1270
+ modeTimeline: enrichTriggerItems(parsed.modeTimeline, "mdl").map((entry) => modeTimelineEntrySchema.parse(entry)),
1271
+ nextMoves: parsed.nextMoves,
1272
+ createdAt: now,
1273
+ updatedAt: now
1274
+ });
1275
+ getDatabase()
1276
+ .prepare(`INSERT INTO trigger_reports (
1277
+ id, domain_id, title, status, event_type_id, custom_event_type, event_situation, occurred_at, emotions_json, thoughts_json, behaviors_json, consequences_json,
1278
+ linked_pattern_ids_json, linked_value_ids_json, linked_goal_ids_json, linked_project_ids_json, linked_task_ids_json,
1279
+ linked_behavior_ids_json, linked_belief_ids_json, linked_mode_ids_json, mode_overlays_json, schema_links_json, mode_timeline_json,
1280
+ next_moves_json, created_at, updated_at
1281
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
1282
+ .run(report.id, report.domainId, report.title, report.status, report.eventTypeId, report.customEventType, report.eventSituation, report.occurredAt, JSON.stringify(report.emotions), JSON.stringify(report.thoughts), JSON.stringify(report.behaviors), JSON.stringify(report.consequences), JSON.stringify(report.linkedPatternIds), JSON.stringify(report.linkedValueIds), JSON.stringify(report.linkedGoalIds), JSON.stringify(report.linkedProjectIds), JSON.stringify(report.linkedTaskIds), JSON.stringify(report.linkedBehaviorIds), JSON.stringify(report.linkedBeliefIds), JSON.stringify(report.linkedModeIds), JSON.stringify(report.modeOverlays), JSON.stringify(report.schemaLinks), JSON.stringify(report.modeTimeline), JSON.stringify(report.nextMoves), report.createdAt, report.updatedAt);
1283
+ mapCreateUpdateContext({
1284
+ entityType: "trigger_report",
1285
+ entityId: report.id,
1286
+ title: "Trigger report captured",
1287
+ eventKind: "trigger_report.created",
1288
+ source: context.source,
1289
+ actor: context.actor ?? null,
1290
+ metadata: {
1291
+ domainId: report.domainId,
1292
+ status: report.status
1293
+ }
1294
+ });
1295
+ recordPsycheReflectionReward(report.id, report.title, { actor: context.actor ?? null, source: context.source });
1296
+ return report;
1297
+ }
1298
+ export function updateTriggerReport(reportId, patch, context) {
1299
+ const existing = getTriggerReportById(reportId);
1300
+ if (!existing) {
1301
+ return undefined;
1302
+ }
1303
+ const parsed = updateTriggerReportSchema.parse(patch);
1304
+ const updated = triggerReportSchema.parse({
1305
+ ...existing,
1306
+ ...parsed,
1307
+ emotions: parsed.emotions ? enrichTriggerItems(parsed.emotions, "emo") : existing.emotions,
1308
+ thoughts: parsed.thoughts ? enrichTriggerItems(parsed.thoughts, "tht") : existing.thoughts,
1309
+ behaviors: parsed.behaviors ? enrichTriggerItems(parsed.behaviors, "beh") : existing.behaviors,
1310
+ modeTimeline: parsed.modeTimeline
1311
+ ? enrichTriggerItems(parsed.modeTimeline, "mdl").map((entry) => modeTimelineEntrySchema.parse(entry))
1312
+ : existing.modeTimeline,
1313
+ updatedAt: new Date().toISOString()
1314
+ });
1315
+ getDatabase()
1316
+ .prepare(`UPDATE trigger_reports
1317
+ SET title = ?, status = ?, event_type_id = ?, custom_event_type = ?, event_situation = ?, occurred_at = ?, emotions_json = ?, thoughts_json = ?, behaviors_json = ?,
1318
+ consequences_json = ?, linked_pattern_ids_json = ?, linked_value_ids_json = ?, linked_goal_ids_json = ?, linked_project_ids_json = ?, linked_task_ids_json = ?,
1319
+ linked_behavior_ids_json = ?, linked_belief_ids_json = ?, linked_mode_ids_json = ?, mode_overlays_json = ?, schema_links_json = ?, mode_timeline_json = ?,
1320
+ next_moves_json = ?, updated_at = ?
1321
+ WHERE id = ?`)
1322
+ .run(updated.title, updated.status, updated.eventTypeId, updated.customEventType, updated.eventSituation, updated.occurredAt, JSON.stringify(updated.emotions), JSON.stringify(updated.thoughts), JSON.stringify(updated.behaviors), JSON.stringify(updated.consequences), JSON.stringify(updated.linkedPatternIds), JSON.stringify(updated.linkedValueIds), JSON.stringify(updated.linkedGoalIds), JSON.stringify(updated.linkedProjectIds), JSON.stringify(updated.linkedTaskIds), JSON.stringify(updated.linkedBehaviorIds), JSON.stringify(updated.linkedBeliefIds), JSON.stringify(updated.linkedModeIds), JSON.stringify(updated.modeOverlays), JSON.stringify(updated.schemaLinks), JSON.stringify(updated.modeTimeline), JSON.stringify(updated.nextMoves), updated.updatedAt, reportId);
1323
+ mapCreateUpdateContext({
1324
+ entityType: "trigger_report",
1325
+ entityId: reportId,
1326
+ title: "Trigger report updated",
1327
+ eventKind: "trigger_report.updated",
1328
+ source: context.source,
1329
+ actor: context.actor ?? null,
1330
+ metadata: { status: updated.status }
1331
+ });
1332
+ return updated;
1333
+ }
1334
+ export function deleteTriggerReport(reportId, context) {
1335
+ const existing = getTriggerReportById(reportId);
1336
+ if (!existing) {
1337
+ return undefined;
1338
+ }
1339
+ return runInTransaction(() => {
1340
+ removeIdFromStringArrayColumn("belief_entries", "linked_report_ids_json", reportId);
1341
+ deleteEntityComments("trigger_report", reportId);
1342
+ getDatabase()
1343
+ .prepare(`DELETE FROM trigger_reports WHERE id = ?`)
1344
+ .run(reportId);
1345
+ mapCreateUpdateContext({
1346
+ entityType: "trigger_report",
1347
+ entityId: reportId,
1348
+ title: "Trigger report deleted",
1349
+ eventKind: "trigger_report.deleted",
1350
+ source: context.source,
1351
+ actor: context.actor ?? null,
1352
+ metadata: { status: existing.status }
1353
+ });
1354
+ return existing;
1355
+ });
1356
+ }