forge-openclaw-plugin 0.2.69 → 0.2.71

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 (34) hide show
  1. package/dist/assets/{board-BfqxFNiQ.js → board-B0TuXl4u.js} +1 -1
  2. package/dist/assets/index-DtT3Y-Bj.css +1 -0
  3. package/dist/assets/index-clNilMKr.js +91 -0
  4. package/dist/assets/{motion-C0ALlgho.js → motion-Dmjq6HPm.js} +1 -1
  5. package/dist/assets/{table-WcMjnJll.js → table-CKKimYN1.js} +1 -1
  6. package/dist/assets/{ui-B5I-3U91.js → ui-JBdCP1Qb.js} +1 -1
  7. package/dist/assets/{vendor-C56o26_3.js → vendor-fiXu5f59.js} +233 -228
  8. package/dist/index.html +7 -7
  9. package/dist/server/server/migrations/062_health_mobile_sync_sessions.sql +55 -0
  10. package/dist/server/server/migrations/063_psyche_flashcards.sql +31 -0
  11. package/dist/server/server/src/app.js +314 -20
  12. package/dist/server/server/src/health.js +525 -1
  13. package/dist/server/server/src/openapi.js +1 -0
  14. package/dist/server/server/src/psyche-types.js +54 -0
  15. package/dist/server/server/src/repositories/psyche.js +146 -1
  16. package/dist/server/server/src/services/entity-crud.js +27 -5
  17. package/dist/server/server/src/services/gamification.js +2 -0
  18. package/dist/server/server/src/services/knowledge-graph.js +87 -1
  19. package/dist/server/server/src/services/psyche-observation-calendar.js +1 -0
  20. package/dist/server/server/src/services/psyche.js +4 -1
  21. package/dist/server/server/src/types.js +3 -0
  22. package/dist/server/src/lib/api.js +43 -0
  23. package/dist/server/src/lib/entity-visuals.js +9 -0
  24. package/dist/server/src/lib/knowledge-graph-types.js +19 -0
  25. package/dist/server/src/lib/psyche-schemas.js +177 -0
  26. package/openclaw.plugin.json +1 -1
  27. package/package.json +2 -1
  28. package/server/migrations/062_health_mobile_sync_sessions.sql +55 -0
  29. package/server/migrations/063_psyche_flashcards.sql +31 -0
  30. package/skills/forge-openclaw/SKILL.md +30 -9
  31. package/skills/forge-openclaw/entity_conversation_playbooks.md +139 -7
  32. package/skills/forge-openclaw/psyche_entity_playbooks.md +64 -3
  33. package/dist/assets/index-BfLQnCNZ.js +0 -91
  34. package/dist/assets/index-DIapFz9v.css +0 -1
@@ -0,0 +1,177 @@
1
+ import { z } from "zod";
2
+ const trimmed = z.string().trim();
3
+ const nonEmpty = trimmed.min(1);
4
+ const uniqueStrings = z.array(nonEmpty).transform((values) => Array.from(new Set(values)));
5
+ const ownedUserId = z.string().trim().min(1).nullable().optional();
6
+ export const psycheValueSchema = z.object({
7
+ title: nonEmpty,
8
+ description: trimmed,
9
+ valuedDirection: nonEmpty,
10
+ whyItMatters: trimmed,
11
+ linkedGoalIds: z.array(z.string()).default([]),
12
+ linkedProjectIds: z.array(z.string()).default([]),
13
+ linkedTaskIds: z.array(z.string()).default([]),
14
+ committedActions: z.array(trimmed).default([]),
15
+ userId: ownedUserId
16
+ });
17
+ export const behaviorPatternSchema = z.object({
18
+ title: nonEmpty,
19
+ description: trimmed,
20
+ targetBehavior: nonEmpty,
21
+ cueContexts: z.array(trimmed).default([]),
22
+ shortTermPayoff: trimmed,
23
+ longTermCost: trimmed,
24
+ preferredResponse: nonEmpty,
25
+ linkedValueIds: z.array(z.string()).default([]),
26
+ linkedSchemaLabels: uniqueStrings.default([]),
27
+ linkedModeIds: z.array(z.string()).default([]),
28
+ linkedBeliefIds: z.array(z.string()).default([]),
29
+ userId: ownedUserId
30
+ });
31
+ export const behaviorSchema = z.object({
32
+ kind: z.enum(["away", "committed", "recovery"]),
33
+ title: nonEmpty,
34
+ description: trimmed,
35
+ commonCues: z.array(trimmed).default([]),
36
+ urgeStory: trimmed,
37
+ shortTermPayoff: trimmed,
38
+ longTermCost: trimmed,
39
+ replacementMove: trimmed,
40
+ repairPlan: trimmed,
41
+ linkedPatternIds: z.array(z.string()).default([]),
42
+ linkedValueIds: z.array(z.string()).default([]),
43
+ linkedSchemaIds: z.array(z.string()).default([]),
44
+ linkedModeIds: z.array(z.string()).default([]),
45
+ userId: ownedUserId
46
+ });
47
+ export const beliefEntrySchema = z.object({
48
+ schemaId: z.string().nullable(),
49
+ statement: nonEmpty,
50
+ beliefType: z.enum(["absolute", "conditional"]),
51
+ originNote: trimmed,
52
+ confidence: z.number().int().min(0).max(100),
53
+ evidenceFor: z.array(trimmed).default([]),
54
+ evidenceAgainst: z.array(trimmed).default([]),
55
+ flexibleAlternative: trimmed,
56
+ linkedValueIds: z.array(z.string()).default([]),
57
+ linkedBehaviorIds: z.array(z.string()).default([]),
58
+ linkedModeIds: z.array(z.string()).default([]),
59
+ linkedReportIds: z.array(z.string()).default([]),
60
+ userId: ownedUserId
61
+ });
62
+ export const modeProfileSchema = z.object({
63
+ family: z.enum(["coping", "child", "critic_parent", "healthy_adult", "happy_child"]),
64
+ archetype: trimmed,
65
+ title: nonEmpty,
66
+ persona: trimmed,
67
+ imagery: trimmed,
68
+ symbolicForm: trimmed,
69
+ facialExpression: trimmed,
70
+ fear: trimmed,
71
+ burden: trimmed,
72
+ protectiveJob: trimmed,
73
+ originContext: trimmed,
74
+ firstAppearanceAt: z.string().trim().nullable(),
75
+ linkedPatternIds: z.array(z.string()).default([]),
76
+ linkedBehaviorIds: z.array(z.string()).default([]),
77
+ linkedValueIds: z.array(z.string()).default([]),
78
+ userId: ownedUserId
79
+ });
80
+ export const modeGuideSessionSchema = z.object({
81
+ summary: nonEmpty,
82
+ answers: z.array(z.object({
83
+ questionKey: nonEmpty,
84
+ value: nonEmpty
85
+ })).min(1),
86
+ userId: ownedUserId
87
+ });
88
+ export const flashcardSchema = z.object({
89
+ title: trimmed.default(""),
90
+ message: nonEmpty,
91
+ triggerSentence: trimmed.default(""),
92
+ triggerSituation: trimmed.default(""),
93
+ tags: z.array(trimmed).default([]),
94
+ backgroundColor: trimmed.default("#f8fafc"),
95
+ textColor: trimmed.default("#111827"),
96
+ accentColor: trimmed.default("#6ee7b7"),
97
+ typography: z.enum(["serif", "sans", "mono", "display"]).default("serif"),
98
+ imageUrl: trimmed.default(""),
99
+ imageAlt: trimmed.default(""),
100
+ layout: z.enum(["centered", "top_left", "image_split", "poster"]).default("centered"),
101
+ visualStyle: z.enum(["calm", "urgent", "warm", "clinical", "playful"]).default("calm"),
102
+ linkedValueIds: z.array(z.string()).default([]),
103
+ linkedBehaviorIds: z.array(z.string()).default([]),
104
+ linkedPatternIds: z.array(z.string()).default([]),
105
+ linkedBeliefIds: z.array(z.string()).default([]),
106
+ linkedModeIds: z.array(z.string()).default([]),
107
+ linkedReportIds: z.array(z.string()).default([]),
108
+ userId: ownedUserId
109
+ });
110
+ export const eventTypeSchema = z.object({
111
+ label: nonEmpty,
112
+ description: trimmed,
113
+ userId: ownedUserId
114
+ });
115
+ export const emotionDefinitionSchema = z.object({
116
+ label: nonEmpty,
117
+ description: trimmed,
118
+ category: trimmed,
119
+ userId: ownedUserId
120
+ });
121
+ export const triggerEmotionSchema = z.object({
122
+ id: nonEmpty,
123
+ emotionDefinitionId: z.string().nullable(),
124
+ label: nonEmpty,
125
+ intensity: z.number().int().min(0).max(100),
126
+ note: trimmed
127
+ });
128
+ export const triggerThoughtSchema = z.object({
129
+ id: nonEmpty,
130
+ text: nonEmpty,
131
+ parentMode: trimmed,
132
+ criticMode: trimmed,
133
+ beliefId: z.string().nullable()
134
+ });
135
+ export const triggerBehaviorSchema = z.object({
136
+ id: nonEmpty,
137
+ text: nonEmpty,
138
+ mode: trimmed,
139
+ behaviorId: z.string().nullable()
140
+ });
141
+ export const modeTimelineEntrySchema = z.object({
142
+ id: nonEmpty,
143
+ stage: nonEmpty,
144
+ modeId: z.string().nullable(),
145
+ label: nonEmpty,
146
+ note: trimmed
147
+ });
148
+ export const triggerReportSchema = z.object({
149
+ title: nonEmpty,
150
+ status: z.enum(["draft", "reviewed", "integrated"]).default("draft"),
151
+ eventTypeId: z.string().nullable(),
152
+ customEventType: trimmed,
153
+ eventSituation: nonEmpty,
154
+ occurredAt: z.string().trim().nullable(),
155
+ emotions: z.array(triggerEmotionSchema).default([]),
156
+ thoughts: z.array(triggerThoughtSchema).default([]),
157
+ behaviors: z.array(triggerBehaviorSchema).default([]),
158
+ consequences: z.object({
159
+ selfShortTerm: z.array(trimmed).default([]),
160
+ selfLongTerm: z.array(trimmed).default([]),
161
+ othersShortTerm: z.array(trimmed).default([]),
162
+ othersLongTerm: z.array(trimmed).default([])
163
+ }),
164
+ linkedPatternIds: z.array(z.string()).default([]),
165
+ linkedValueIds: z.array(z.string()).default([]),
166
+ linkedGoalIds: z.array(z.string()).default([]),
167
+ linkedProjectIds: z.array(z.string()).default([]),
168
+ linkedTaskIds: z.array(z.string()).default([]),
169
+ linkedBehaviorIds: z.array(z.string()).default([]),
170
+ linkedBeliefIds: z.array(z.string()).default([]),
171
+ linkedModeIds: z.array(z.string()).default([]),
172
+ modeOverlays: z.array(trimmed).default([]),
173
+ schemaLinks: z.array(trimmed).default([]),
174
+ modeTimeline: z.array(modeTimelineEntrySchema).default([]),
175
+ nextMoves: z.array(trimmed).default([]),
176
+ userId: ownedUserId
177
+ });
@@ -2,7 +2,7 @@
2
2
  "id": "forge-openclaw-plugin",
3
3
  "name": "Forge",
4
4
  "description": "Curated OpenClaw adapter for the Forge collaboration API, UI entrypoint, and localhost auto-start runtime.",
5
- "version": "0.2.69",
5
+ "version": "0.2.71",
6
6
  "activation": {
7
7
  "onStartup": true,
8
8
  "onCapabilities": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forge-openclaw-plugin",
3
- "version": "0.2.69",
3
+ "version": "0.2.71",
4
4
  "description": "Curated OpenClaw adapter for the Forge collaboration API, UI entrypoint, and localhost auto-start runtime.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -105,6 +105,7 @@
105
105
  "follow-redirects": "^1.16.0",
106
106
  "hono": "^4.12.18",
107
107
  "ip-address": "^10.2.0",
108
+ "ws": "^8.20.1",
108
109
  "uuid": "^14.0.0"
109
110
  },
110
111
  "scripts": {
@@ -0,0 +1,55 @@
1
+ CREATE TABLE IF NOT EXISTS health_mobile_sync_sessions (
2
+ id TEXT PRIMARY KEY,
3
+ pairing_session_id TEXT NOT NULL REFERENCES companion_pairing_sessions(id) ON DELETE CASCADE,
4
+ user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
5
+ status TEXT NOT NULL DEFAULT 'running',
6
+ schema_version TEXT NOT NULL DEFAULT 'healthkit-sync-v2',
7
+ requested_families_json TEXT NOT NULL DEFAULT '[]',
8
+ source_metadata_json TEXT NOT NULL DEFAULT '{}',
9
+ expected_counts_json TEXT NOT NULL DEFAULT '{}',
10
+ received_counts_json TEXT NOT NULL DEFAULT '{}',
11
+ byte_totals_json TEXT NOT NULL DEFAULT '{}',
12
+ affected_workout_ids_json TEXT NOT NULL DEFAULT '[]',
13
+ error_json TEXT NOT NULL DEFAULT '{}',
14
+ started_at TEXT NOT NULL,
15
+ completed_at TEXT,
16
+ failed_at TEXT,
17
+ aborted_at TEXT,
18
+ expired_at TEXT,
19
+ created_at TEXT NOT NULL,
20
+ updated_at TEXT NOT NULL
21
+ );
22
+
23
+ CREATE INDEX IF NOT EXISTS idx_health_mobile_sync_sessions_pairing_status
24
+ ON health_mobile_sync_sessions(pairing_session_id, status, started_at DESC);
25
+
26
+ CREATE TABLE IF NOT EXISTS health_mobile_sync_chunks (
27
+ id TEXT PRIMARY KEY,
28
+ sync_session_id TEXT NOT NULL REFERENCES health_mobile_sync_sessions(id) ON DELETE CASCADE,
29
+ chunk_id TEXT NOT NULL,
30
+ sequence INTEGER NOT NULL,
31
+ family TEXT NOT NULL,
32
+ checksum_sha256 TEXT NOT NULL,
33
+ record_count INTEGER NOT NULL DEFAULT 0,
34
+ byte_count INTEGER NOT NULL DEFAULT 0,
35
+ payload_json TEXT NOT NULL DEFAULT '{}',
36
+ payload_summary_json TEXT NOT NULL DEFAULT '{}',
37
+ received_at TEXT NOT NULL,
38
+ applied_at TEXT,
39
+ created_at TEXT NOT NULL,
40
+ updated_at TEXT NOT NULL,
41
+ UNIQUE(sync_session_id, chunk_id)
42
+ );
43
+
44
+ CREATE INDEX IF NOT EXISTS idx_health_mobile_sync_chunks_session_sequence
45
+ ON health_mobile_sync_chunks(sync_session_id, sequence);
46
+
47
+ CREATE TABLE IF NOT EXISTS health_mobile_sync_family_cursors (
48
+ id TEXT PRIMARY KEY,
49
+ pairing_session_id TEXT NOT NULL REFERENCES companion_pairing_sessions(id) ON DELETE CASCADE,
50
+ user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
51
+ family TEXT NOT NULL,
52
+ cursor_json TEXT NOT NULL DEFAULT '{}',
53
+ updated_at TEXT NOT NULL,
54
+ UNIQUE(pairing_session_id, family)
55
+ );
@@ -0,0 +1,31 @@
1
+ CREATE TABLE IF NOT EXISTS psyche_flashcards (
2
+ id TEXT PRIMARY KEY,
3
+ domain_id TEXT NOT NULL REFERENCES domains(id) ON DELETE CASCADE,
4
+ title TEXT NOT NULL DEFAULT '',
5
+ message TEXT NOT NULL,
6
+ trigger_sentence TEXT NOT NULL DEFAULT '',
7
+ trigger_situation TEXT NOT NULL DEFAULT '',
8
+ tags_json TEXT NOT NULL DEFAULT '[]',
9
+ background_color TEXT NOT NULL DEFAULT '#f8fafc',
10
+ text_color TEXT NOT NULL DEFAULT '#111827',
11
+ accent_color TEXT NOT NULL DEFAULT '#6ee7b7',
12
+ typography TEXT NOT NULL DEFAULT 'serif',
13
+ image_url TEXT NOT NULL DEFAULT '',
14
+ image_alt TEXT NOT NULL DEFAULT '',
15
+ layout TEXT NOT NULL DEFAULT 'centered',
16
+ visual_style TEXT NOT NULL DEFAULT 'calm',
17
+ linked_value_ids_json TEXT NOT NULL DEFAULT '[]',
18
+ linked_behavior_ids_json TEXT NOT NULL DEFAULT '[]',
19
+ linked_pattern_ids_json TEXT NOT NULL DEFAULT '[]',
20
+ linked_belief_ids_json TEXT NOT NULL DEFAULT '[]',
21
+ linked_mode_ids_json TEXT NOT NULL DEFAULT '[]',
22
+ linked_report_ids_json TEXT NOT NULL DEFAULT '[]',
23
+ created_at TEXT NOT NULL,
24
+ updated_at TEXT NOT NULL
25
+ );
26
+
27
+ CREATE INDEX IF NOT EXISTS idx_psyche_flashcards_domain_updated
28
+ ON psyche_flashcards(domain_id, updated_at DESC);
29
+
30
+ CREATE INDEX IF NOT EXISTS idx_psyche_flashcards_trigger_sentence
31
+ ON psyche_flashcards(trigger_sentence);
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: forge-openclaw-plugin
3
- description: use when the user wants to save, search, update, review, start, stop, reward, explain, compare, or run Forge records, or when the conversation is clearly about a Forge entity or domain surface such as a goal, project, strategy, task, habit, note, wiki_page, calendar_event, calendar_connection, work_block_template, task_timebox, task_run, work_adjustment, insight, preference item, preference context, preference catalog, preference judgment, preference signal, questionnaire instrument, questionnaire run, self observation, movement, life_force, workbench, psyche_value, behavior_pattern, behavior, belief_entry, mode_profile, mode_guide_session, trigger_report, event_type, emotion_definition, sleep_session, or workout_session. identify the exact Forge object or specialized surface, keep the main conversation natural, guide psyche intake with active listening before storing it, and for psyche issues that need understanding first usually begin with one exploratory question before any formulation or save suggestion.
3
+ description: use when the user wants to save, search, update, review, start, stop, reward, explain, compare, or run Forge records, or when the conversation is clearly about a Forge entity or domain surface such as a goal, project, strategy, task, habit, note, wiki_page, calendar_event, calendar_connection, work_block_template, task_timebox, task_run, work_adjustment, insight, preference item, preference context, preference catalog, preference judgment, preference signal, questionnaire instrument, questionnaire run, self observation, movement, life_force, workbench, psyche_value, behavior_pattern, behavior, belief_entry, mode_profile, mode_guide_session, flashcard, trigger_report, event_type, emotion_definition, sleep_session, or workout_session. identify the exact Forge object or specialized surface, keep the main conversation natural, guide psyche intake with active listening before storing it, and for psyche issues that need understanding first usually begin with one exploratory question before any formulation or save suggestion.
4
4
  ---
5
5
 
6
6
  Forge is the user's structured system for planning work, doing work, reflecting on patterns, and keeping a truthful record of what is happening. Use it when the user is clearly working inside that system, or when they are describing something that naturally belongs there and would benefit from being stored, updated, reviewed, or acted on in Forge. Keep the conversation natural first. Do not turn every message into intake. When a real Forge entity is clearly present, name the exact entity type plainly, help with the substance of the conversation, and then offer Forge once, lightly, if storing it would genuinely help.
@@ -59,7 +59,7 @@ PM surface rule:
59
59
  human/bot ownership filters.
60
60
  - Guided modal flows handle create, edit, move, link, and closeout actions.
61
61
 
62
- Forge has four major stored-entity surfaces and three specialized domain surfaces. The planning side covers goals, projects, strategies, tasks, habits, notes, calendar events, recurring work blocks, task timeboxes, live work sessions, and agent-authored insights. The Health side covers sleep sessions, sports and workout sessions, companion pairing, and habit-generated workout records that should still stay linked to the broader Forge graph. The Preferences side covers contextual taste modeling, pairwise comparisons, direct signals, editable concept libraries, and preference items that can come from Forge entities or seeded concept domains such as food, activities, places, countries, fashion, people, media, and tools. The Psyche side covers values, patterns, behaviors, beliefs, modes, guided mode sessions, trigger reports, event types, and reusable emotion definitions. The specialized domain surfaces are Movement, Life Force, and Workbench; agents must use their dedicated route families instead of forcing them through batch CRUD. Forge also has a SQLite-backed Wiki memory layer with explicit spaces, Markdown content in database rows, backlinks, optional embeddings, and structured links back to Forge entities. Forge is also multi-user: every entity can belong to a typed `human` or `bot` user through `userId`, and read routes can scope to one or many users with `userId` or repeated `userIds`. The current access posture is configurable through a directional user graph, but the live default is still permissive: Forge can list users directly, every relationship edge starts open, and a user can read or affect another user's linked records when the route explicitly asks for them. Use `forge_get_user_directory` when owner identity or cross-user access matters. Strategies can also be locked into a contract with `isLocked`; once locked, do not mutate the graph or target structure unless the user explicitly wants the strategy unlocked first. The model should use the real entity names, not vague substitutes. Say `project`, not “initiative”. Say `behavior_pattern`, not “theme”. Say `trigger_report`, not “incident note”.
62
+ Forge has four major stored-entity surfaces and three specialized domain surfaces. The planning side covers goals, projects, strategies, tasks, habits, notes, calendar events, recurring work blocks, task timeboxes, live work sessions, and agent-authored insights. The Health side covers sleep sessions, sports and workout sessions, companion pairing, and habit-generated workout records that should still stay linked to the broader Forge graph. The Preferences side covers contextual taste modeling, pairwise comparisons, direct signals, editable concept libraries, and preference items that can come from Forge entities or seeded concept domains such as food, activities, places, countries, fashion, people, media, and tools. The Psyche side covers values, patterns, behaviors, beliefs, modes, guided mode sessions, flashcards, trigger reports, event types, and reusable emotion definitions. The specialized domain surfaces are Movement, Life Force, and Workbench; agents must use their dedicated route families instead of forcing them through batch CRUD. Forge also has a SQLite-backed Wiki memory layer with explicit spaces, Markdown content in database rows, backlinks, optional embeddings, and structured links back to Forge entities. Forge is also multi-user: every entity can belong to a typed `human` or `bot` user through `userId`, and read routes can scope to one or many users with `userId` or repeated `userIds`. The current access posture is configurable through a directional user graph, but the live default is still permissive: Forge can list users directly, every relationship edge starts open, and a user can read or affect another user's linked records when the route explicitly asks for them. Use `forge_get_user_directory` when owner identity or cross-user access matters. Strategies can also be locked into a contract with `isLocked`; once locked, do not mutate the graph or target structure unless the user explicitly wants the strategy unlocked first. The model should use the real entity names, not vague substitutes. Say `project`, not “initiative”. Say `behavior_pattern`, not “theme”. Say `trigger_report`, not “incident note”.
63
63
  Habits are a first-class recurring entity in the planning side.
64
64
  NEGATIVE HABIT CHECK-IN RULE: for a `negative` habit, the correct aligned/resisted outcome is `missed`. `missed` means the bad habit was resisted, the user stayed aligned, and the habit should award its XP bonus.
65
65
 
@@ -185,11 +185,16 @@ Health rule:
185
185
 
186
186
  - Sleep and sports records are first-class health surfaces, not generic notes or tasks.
187
187
  - Use `forge_get_sleep_overview` and `forge_get_sports_overview` for review and trend reading.
188
- - In `forge_get_agent_onboarding.entityRouteModel.readModelOnlySurfaces`, the health
189
- overview routes are published under both the plain names `sleepOverview` and
190
- `sportsOverview` and the entity-style aliases `sleep_overview` and
191
- `sports_overview`. Treat those as read-only overview surfaces, not batch CRUD
192
- entities.
188
+ - In `forge_get_agent_onboarding.entityRouteModel.readModelOnlySurfaces`, operator,
189
+ calendar, self-observation, sleep, and sports read models are published with
190
+ both camelCase names and entity-style aliases where useful, including
191
+ `operatorOverview`, `operatorContext`, `calendarOverview`, `sleepOverview`,
192
+ `sportsOverview`, `operator_overview`, `operator_context`,
193
+ `calendar_overview`, `self_observation`, `sleep_overview`, and
194
+ `sports_overview`. Treat those as read-only surfaces, not batch CRUD entities.
195
+ - Use `forge_get_operator_overview` for a broad Forge status read, `forge_get_operator_context`
196
+ for current work and risk, and `forge_get_calendar_overview` before calendar-aware
197
+ planning or scheduling mutations.
193
198
  - Use the shared batch entity tools for ordinary `sleep_session` and `workout_session` create, update, delete, and search work. Do not force agents into a large one-route-per-entity mental model when the batch routes already cover the record cleanly.
194
199
  - Use `forge_update_sleep_session` and `forge_update_workout_session` only when the job is reflective enrichment on one existing health record after review, such as attaching notes, tags, mood, meaning, or Forge links.
195
200
  - Habit-generated workouts and imported HealthKit workouts belong to the same workout record model, so do not invent a separate storage path for sport sessions.
@@ -232,7 +237,7 @@ Forge data location rule:
232
237
 
233
238
  Psyche interview rule:
234
239
 
235
- - For `psyche_value`, `behavior_pattern`, `behavior`, `belief_entry`, `mode_profile`, `mode_guide_session`, `trigger_report`, `event_type`, and `emotion_definition`, do not jump straight to raw field collection.
240
+ - For `psyche_value`, `behavior_pattern`, `behavior`, `belief_entry`, `mode_profile`, `mode_guide_session`, `flashcard`, `trigger_report`, `event_type`, and `emotion_definition`, do not jump straight to raw field collection.
236
241
  - Treat `event_type` and `emotion_definition` as psychologically meaningful Psyche records, not cold taxonomy labels; start from the repeated lived moment or felt signature before wording the reusable label.
237
242
  - First use the active-listening playbooks in [`psyche_entity_playbooks.md`](./psyche_entity_playbooks.md).
238
243
  - Ask permission before going deeper, ask one or two focused questions at a time, reflect back what you heard, and summarize before moving on.
@@ -271,6 +276,8 @@ Self-observation rule:
271
276
  - If the core is a sentence the user believes, prefer `belief_entry`.
272
277
  - If a part-state, protector, critic, child state, or healthy-adult stance is active,
273
278
  prefer `mode_guide_session` or `mode_profile`.
279
+ - If the user needs a brief rehearsable message during an urge, trigger, belief
280
+ activation, mode shift, or relapse-prevention moment, prefer `flashcard`.
274
281
  - If a schema theme is visible, do not bury it in self-observation: preserve it as
275
282
  the belief, recurring pattern, active mode, guided mode session, trigger report, or
276
283
  wiki explanation that best matches the material.
@@ -313,6 +320,10 @@ Use these exact entity meanings when deciding what the user is describing.
313
320
 
314
321
  `mode_guide_session` is a guided exploration record used to understand what mode may be active right now. It is a structured worksheet, not the final durable profile unless the user wants it that way.
315
322
 
323
+ `flashcard` is a small therapeutic reminder card. Use it when the user wants a sentence or short message that can be shown back during an urge, trigger, mode activation, belief activation, or values-based pivot. The message is the main content; title is optional and compact. Tags, trigger sentence, trigger situation, and Psyche links matter most for retrieval. Styling fields such as colors, typography, layout, visual tone, and image make the card easier to recognize but should come after the therapeutic sentence is clear.
324
+
325
+ When a user says something like "I feel the urge to drink" or "help me not do this", search existing `flashcard` records first with `forge_search_entities` using `entityTypes: ["flashcard"]` and the user's urge, trigger words, tags, and situation language. If a matching card exists, show the flashcard message first, then add brief psychotherapy-informed support around it: grounding, urge surfing, cognitive defusion, schema/mode-aware reflection, or a values pivot. Do not create a new card until you have checked whether an existing one already fits.
326
+
316
327
  `trigger_report` is one specific emotionally meaningful episode described as what happened, what was felt, what was thought, what was done, what happened next, and what would help next time.
317
328
 
318
329
  `event_type` is a reusable category for trigger reports, such as rejection, criticism, conflict, uncertainty, or abandonment cue.
@@ -435,6 +446,16 @@ Only ask if missing or unclear:
435
446
  2. If it had a voice, what would it say, fear, or need?
436
447
  3. Would it help if we suggested one or two candidate mode labels, with reasons, before deciding whether to store a durable profile?
437
448
 
449
+ `flashcard`
450
+ Use for a small therapeutic card to retrieve during an urge, trigger, mode activation, belief activation, or values-based pivot.
451
+ Minimum field: `message`
452
+ Usually useful: `triggerSentence`, `triggerSituation`, `tags`, optional compact `title`, visual styling, optional `imageUrl`, links to values, behaviors, patterns, beliefs, modes, or reports
453
+ Only ask if missing or unclear:
454
+
455
+ 1. What exact urge sentence, trigger, or situation should bring this card up?
456
+ 2. What one simple message should be centered on the card when that moment hits?
457
+ 3. What tags or trigger wording will help us find it later, and only then what visual tone, colors, typography, or image should it use?
458
+
438
459
  `trigger_report`
439
460
  Use for one specific emotionally important episode.
440
461
  Minimum field: `title`
@@ -475,7 +496,7 @@ Use the batch entity tools for stored records:
475
496
  `forge_search_entities`, `forge_create_entities`, `forge_update_entities`, `forge_delete_entities`, `forge_restore_entities`
476
497
 
477
498
  These tools operate on:
478
- `goal`, `project`, `strategy`, `task`, `habit`, `tag`, `note`, `insight`, `calendar_event`, `work_block_template`, `task_timebox`, `psyche_value`, `behavior_pattern`, `behavior`, `belief_entry`, `mode_profile`, `mode_guide_session`, `trigger_report`, `event_type`, `emotion_definition`, `preference_catalog`, `preference_catalog_item`, `preference_context`, `preference_item`, `questionnaire_instrument`, `sleep_session`, `workout_session`
499
+ `goal`, `project`, `strategy`, `task`, `habit`, `tag`, `note`, `insight`, `calendar_event`, `work_block_template`, `task_timebox`, `psyche_value`, `behavior_pattern`, `behavior`, `belief_entry`, `mode_profile`, `mode_guide_session`, `flashcard`, `trigger_report`, `event_type`, `emotion_definition`, `preference_catalog`, `preference_catalog_item`, `preference_context`, `preference_item`, `questionnaire_instrument`, `sleep_session`, `workout_session`
479
500
 
480
501
  Use the wiki tools for SQLite-backed memory work:
481
502
  `forge_get_wiki_settings`, `forge_list_wiki_pages`, `forge_get_wiki_page`, `forge_search_wiki`, `forge_upsert_wiki_page`, `forge_get_wiki_health`, `forge_sync_wiki_vault`, `forge_reindex_wiki_embeddings`, `forge_ingest_wiki_source`
@@ -237,10 +237,11 @@ Use this quick split before the conversation gets too detailed.
237
237
  `preference_signal`, and `self_observation` are action workflows. Start from what
238
238
  the user is trying to do, then use the dedicated action tool or note-backed write
239
239
  model.
240
- - `sleep_overview` and `sports_overview` are read-model-only surfaces. Use them when
241
- the user wants to review nights, workouts, training load, recovery context, or
242
- health patterns before deciding whether one stored `sleep_session` or
243
- `workout_session` needs enrichment.
240
+ - `operator_overview`, `operator_context`, `calendar_overview`, `sleep_overview`,
241
+ and `sports_overview` are read-model-only surfaces. Use them when the user wants
242
+ to understand current Forge state, work risk, calendar commitments, nights,
243
+ workouts, training load, recovery context, or health patterns before deciding
244
+ whether a stored entity needs creation or enrichment.
244
245
  - Movement, Life Force, and Workbench are specialized domain areas. Use their
245
246
  dedicated route families for timelines and overlays, energy profile/templates and
246
247
  fatigue signals, and Workbench flow execution or result artifacts. When available,
@@ -274,7 +275,8 @@ still knowing the exact write/read family before it acts.
274
275
  CRUD. Use health overview/read helpers for review and reflective update helpers only
275
276
  when enriching one already-known record after review.
276
277
  - `psyche_value`, `behavior_pattern`, `behavior`, `belief_entry`, `mode_profile`,
277
- `mode_guide_session`, `trigger_report`, `event_type`, and `emotion_definition`:
278
+ `mode_guide_session`, `flashcard`, `trigger_report`, `event_type`, and
279
+ `emotion_definition`:
278
280
  psychologically meaningful records, but normal stored entities for API purposes.
279
281
  Search and mutate through shared batch entity routes after the formulation is clear.
280
282
  - `wiki_page`: specialized CRUD. Use wiki page/search/upsert routes so page rows,
@@ -282,6 +284,19 @@ still knowing the exact write/read family before it acts.
282
284
  - `calendar_connection`: specialized CRUD. Use provider discovery, connection CRUD,
283
285
  selected-calendar rediscovery, sync, and delete routes rather than batch entity
284
286
  tools.
287
+ - `operator_overview`: read-model-only operator surface. Use
288
+ `forge_get_operator_overview` or `/api/v1/operator/overview` when the user wants
289
+ the current Forge picture, attention cues, or broad status before choosing a
290
+ specific entity action.
291
+ - `operator_context`: read-model-only operator surface. Use
292
+ `forge_get_operator_context` or `/api/v1/operator/context` when the user wants
293
+ current work, active runs, risks, board context, or next moves before mutating
294
+ anything.
295
+ - `calendar_overview`: read-model-only calendar surface. Use
296
+ `forge_get_calendar_overview` or `/api/v1/calendar/overview` when the user wants
297
+ mirrored events, work blocks, timeboxes, provider state, or availability before
298
+ creating a `calendar_event`, `work_block_template`, `task_timebox`, or
299
+ `calendar_connection`.
285
300
  - `task_run`: action workflow. Use task-run start, heartbeat, focus, complete, and
286
301
  release routes; never treat status changes as proof of live work.
287
302
  - `work_adjustment`: action workflow. Use the signed work-adjustment route for real
@@ -1061,6 +1076,81 @@ Preferred opening question:
1061
1076
 
1062
1077
  - "Which task or project should this time correction belong to?"
1063
1078
 
1079
+ ## Operator Overview
1080
+
1081
+ Aim: read the broad Forge state before choosing a specific action, without turning a
1082
+ status check into generic intake.
1083
+
1084
+ Arc:
1085
+
1086
+ 1. Ask what the user is trying to understand about Forge overall.
1087
+ 2. Read the operator overview before asking the user to reconstruct active work,
1088
+ attention cues, or broad status from memory.
1089
+ 3. Reflect the practical decision the overview should support.
1090
+ 4. Move into a specific entity flow only when the overview points to a concrete goal,
1091
+ project, task, habit, note, Psyche record, or follow-up action.
1092
+
1093
+ Helpful follow-up lanes:
1094
+
1095
+ - whether the user wants a broad status read, a priority decision, or a handoff
1096
+ - which owner or user scope matters if several humans or bots are involved
1097
+ - what decision the overview should help them make next
1098
+
1099
+ Route note:
1100
+
1101
+ - `operator_overview` is a read-model-only operator surface. Use
1102
+ `forge_get_operator_overview` or `/api/v1/operator/overview`; do not create,
1103
+ update, or delete `operator_overview` through batch CRUD.
1104
+ - If the read reveals a specific record that needs work, switch to that record's
1105
+ normal route posture after the user chooses the follow-up.
1106
+
1107
+ Ready to review when:
1108
+
1109
+ - the broad question is clear enough
1110
+ - any owner or user scope that changes the read is clear enough
1111
+
1112
+ Preferred opening question:
1113
+
1114
+ - "What are you trying to understand about Forge overall right now?"
1115
+
1116
+ ## Operator Context
1117
+
1118
+ Aim: inspect current work, active runs, risk, and next moves before changing records.
1119
+
1120
+ Arc:
1121
+
1122
+ 1. Ask whether the user is checking current work, risk, blockers, active sessions, or
1123
+ the next move.
1124
+ 2. Read operator context before reopening a create or update intake.
1125
+ 3. Reflect what the read is meant to decide: continue, stop, reprioritize, update, or
1126
+ create.
1127
+ 4. Move to task-run, work-adjustment, task, project, or note flow only when one
1128
+ concrete follow-up is visible.
1129
+
1130
+ Helpful follow-up lanes:
1131
+
1132
+ - current task or active run
1133
+ - blocked or stale work
1134
+ - next move versus broad review
1135
+ - owner or user scope when bot and human work are both present
1136
+
1137
+ Route note:
1138
+
1139
+ - `operator_context` is a read-model-only operator surface. Use
1140
+ `forge_get_operator_context` or `/api/v1/operator/context`; do not mutate it
1141
+ through batch CRUD.
1142
+ - If the user decides to start, complete, release, or adjust work after the read,
1143
+ switch to the dedicated action workflow for that operation.
1144
+
1145
+ Ready to review when:
1146
+
1147
+ - the current-work question is clear
1148
+ - any user or owner scope is clear enough
1149
+
1150
+ Preferred opening question:
1151
+
1152
+ - "What current work, risk, or next move are you trying to check?"
1153
+
1064
1154
  ## Self Observation
1065
1155
 
1066
1156
  Aim: capture one observed episode in a structured chain without letting a loose note
@@ -1081,7 +1171,8 @@ Arc:
1081
1171
  visible.
1082
1172
  6. Decide whether this should stay a lightweight self-observation or become a
1083
1173
  `trigger_report`, `behavior_pattern`, `behavior`, `belief_entry`, `mode_profile`,
1084
- `mode_guide_session`, `event_type`, `emotion_definition`, or wiki page.
1174
+ `mode_guide_session`, `flashcard`, `event_type`, `emotion_definition`, or wiki
1175
+ page.
1085
1176
  7. Link the observation to the structured record when the structured record is the
1086
1177
  real container.
1087
1178
 
@@ -1104,7 +1195,8 @@ Route note:
1104
1195
  - Do not promote self-observation over functional analysis. If the user is describing
1105
1196
  a loop, use `behavior_pattern`; if they are describing one emotionally meaningful
1106
1197
  episode, use `trigger_report`; if a part-state is central, use `mode_guide_session`
1107
- or `mode_profile`; if a belief sentence is central, use `belief_entry`.
1198
+ or `mode_profile`; if a belief sentence is central, use `belief_entry`; if the
1199
+ user needs a rehearsable reminder during the trigger or urge, use `flashcard`.
1108
1200
  - If the user wants to remember a source, concept, book, article, or durable personal
1109
1201
  explanation, use `wiki_page` rather than self-observation.
1110
1202
 
@@ -1251,6 +1343,46 @@ Preferred opening question:
1251
1343
 
1252
1344
  - "What are you trying to understand from your workout picture right now?"
1253
1345
 
1346
+ ## Calendar Overview
1347
+
1348
+ Aim: review commitments, work blocks, provider state, and existing timeboxes before
1349
+ creating or changing calendar records.
1350
+
1351
+ Arc:
1352
+
1353
+ 1. Ask what the user is trying to understand or decide from the calendar picture.
1354
+ 2. Ask for the date range or owner scope only if it changes the read.
1355
+ 3. Read the calendar overview before asking the user to recreate availability from
1356
+ memory.
1357
+ 4. Reflect the practical decision the overview should support.
1358
+ 5. Move to `calendar_event`, `work_block_template`, `task_timebox`, or
1359
+ `calendar_connection` only when a specific follow-up action is visible.
1360
+
1361
+ Helpful follow-up lanes:
1362
+
1363
+ - which day, week, or date range matters
1364
+ - whether the question is availability, conflicts, provider health, work blocks, or
1365
+ existing timeboxes
1366
+ - what scheduling or planning decision the review should support
1367
+
1368
+ Route note:
1369
+
1370
+ - `calendar_overview` is a read-model-only calendar surface. Use
1371
+ `forge_get_calendar_overview` or `/api/v1/calendar/overview`; do not create,
1372
+ update, or delete `calendar_overview` through batch CRUD.
1373
+ - If the review reveals a concrete scheduling action, switch to the stored
1374
+ `calendar_event`, `work_block_template`, or `task_timebox` batch route, or to the
1375
+ specialized `calendar_connection` lifecycle route.
1376
+
1377
+ Ready to review when:
1378
+
1379
+ - the user's practical calendar question is clear
1380
+ - the relevant date range or owner scope is clear enough
1381
+
1382
+ Preferred opening question:
1383
+
1384
+ - "What are you trying to understand or decide from your calendar picture?"
1385
+
1254
1386
  ## Calendar Connection
1255
1387
 
1256
1388
  Aim: connect the right provider deliberately without turning setup into a credential