forge-openclaw-plugin 0.2.27 → 0.2.28

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 (31) hide show
  1. package/README.md +1 -0
  2. package/dist/assets/{board-C6jCchjI.js → board-DPFvZf-D.js} +2 -2
  3. package/dist/assets/{board-C6jCchjI.js.map → board-DPFvZf-D.js.map} +1 -1
  4. package/dist/assets/index-Auw3JrdE.css +1 -0
  5. package/dist/assets/index-D1H7myQH.js +85 -0
  6. package/dist/assets/index-D1H7myQH.js.map +1 -0
  7. package/dist/assets/{motion-DFHrH2rd.js → motion-Bvwc85ch.js} +2 -2
  8. package/dist/assets/{motion-DFHrH2rd.js.map → motion-Bvwc85ch.js.map} +1 -1
  9. package/dist/assets/{table-ZL7Di_u3.js → table-FJQTJvUR.js} +2 -2
  10. package/dist/assets/{table-ZL7Di_u3.js.map → table-FJQTJvUR.js.map} +1 -1
  11. package/dist/assets/{ui-CKNPpz7q.js → ui-GXFcgvSw.js} +2 -2
  12. package/dist/assets/{ui-CKNPpz7q.js.map → ui-GXFcgvSw.js.map} +1 -1
  13. package/dist/assets/{vendor-DoNZuFhn.js → vendor-Cwf49UMz.js} +204 -204
  14. package/dist/assets/vendor-Cwf49UMz.js.map +1 -0
  15. package/dist/index.html +7 -7
  16. package/dist/server/server/src/app.js +244 -2
  17. package/dist/server/server/src/openapi.js +799 -2
  18. package/dist/server/server/src/repositories/calendar.js +151 -0
  19. package/dist/server/server/src/services/life-force-model.js +20 -0
  20. package/dist/server/server/src/services/life-force.js +1333 -97
  21. package/dist/server/server/src/types.js +21 -1
  22. package/dist/server/src/lib/snapshot-normalizer.js +2 -0
  23. package/openclaw.plugin.json +1 -1
  24. package/package.json +1 -1
  25. package/skills/forge-openclaw/SKILL.md +17 -0
  26. package/skills/forge-openclaw/entity_conversation_playbooks.md +238 -0
  27. package/skills/forge-openclaw/psyche_entity_playbooks.md +57 -0
  28. package/dist/assets/index-DVvS8iiU.css +0 -1
  29. package/dist/assets/index-zYB-9Dfo.js +0 -85
  30. package/dist/assets/index-zYB-9Dfo.js.map +0 -1
  31. package/dist/assets/vendor-DoNZuFhn.js.map +0 -1
@@ -578,6 +578,7 @@ export const lifeForcePayloadSchema = z.object({
578
578
  spentTodayAp: z.number(),
579
579
  remainingAp: z.number(),
580
580
  forecastAp: z.number(),
581
+ plannedRemainingAp: z.number(),
581
582
  targetBandMinAp: z.number().min(0),
582
583
  targetBandMaxAp: z.number().min(0),
583
584
  instantCapacityApPerHour: z.number().min(0),
@@ -591,6 +592,7 @@ export const lifeForcePayloadSchema = z.object({
591
592
  stats: z.array(lifeForceStatStateSchema),
592
593
  currentCurve: z.array(lifeForceCurvePointSchema),
593
594
  activeDrains: z.array(lifeForceDrainEntrySchema),
595
+ plannedDrains: z.array(lifeForceDrainEntrySchema),
594
596
  warnings: z.array(lifeForceWarningSchema),
595
597
  recommendations: z.array(trimmedString),
596
598
  topTaskIdsNeedingSplit: z.array(z.string()),
@@ -887,6 +889,7 @@ export const calendarEventSchema = z.object({
887
889
  categories: z.array(z.string()).default([]),
888
890
  sourceMappings: z.array(calendarEventSourceSchema).default([]),
889
891
  links: z.array(calendarEventLinkSchema).default([]),
892
+ actionProfile: actionProfileSchema.nullable().default(null),
890
893
  remoteUpdatedAt: z.string().nullable(),
891
894
  deletedAt: z.string().nullable(),
892
895
  createdAt: z.string(),
@@ -906,6 +909,7 @@ export const workBlockTemplateSchema = z
906
909
  startsOn: dateOnlySchema.nullable().default(null),
907
910
  endsOn: dateOnlySchema.nullable().default(null),
908
911
  blockingState: z.enum(["allowed", "blocked"]),
912
+ actionProfile: actionProfileSchema.nullable().default(null),
909
913
  createdAt: z.string(),
910
914
  updatedAt: z.string(),
911
915
  ...ownershipShape
@@ -937,6 +941,7 @@ export const workBlockInstanceSchema = z.object({
937
941
  color: z.string(),
938
942
  blockingState: z.enum(["allowed", "blocked"]),
939
943
  calendarEventId: z.string().nullable(),
944
+ actionProfile: actionProfileSchema.nullable().default(null),
940
945
  createdAt: z.string(),
941
946
  updatedAt: z.string()
942
947
  });
@@ -954,6 +959,7 @@ export const taskTimeboxSchema = z.object({
954
959
  startsAt: z.string(),
955
960
  endsAt: z.string(),
956
961
  overrideReason: trimmedString.nullable(),
962
+ actionProfile: actionProfileSchema.nullable().default(null),
957
963
  createdAt: z.string(),
958
964
  updatedAt: z.string(),
959
965
  ...ownershipShape
@@ -2416,7 +2422,11 @@ const workBlockTemplateMutationShape = {
2416
2422
  userId: nonEmptyTrimmedString.nullable().optional()
2417
2423
  };
2418
2424
  export const createWorkBlockTemplateSchema = z
2419
- .object(workBlockTemplateMutationShape)
2425
+ .object({
2426
+ ...workBlockTemplateMutationShape,
2427
+ activityPresetKey: trimmedString.nullable().optional(),
2428
+ customSustainRateApPerHour: z.number().min(0).nullable().optional()
2429
+ })
2420
2430
  .superRefine((value, context) => {
2421
2431
  if (value.endMinute <= value.startMinute) {
2422
2432
  context.addIssue({
@@ -2448,6 +2458,8 @@ export const updateWorkBlockTemplateSchema = z
2448
2458
  startsOn: dateOnlySchema.nullable().optional(),
2449
2459
  endsOn: dateOnlySchema.nullable().optional(),
2450
2460
  blockingState: z.enum(["allowed", "blocked"]).optional(),
2461
+ activityPresetKey: trimmedString.nullable().optional(),
2462
+ customSustainRateApPerHour: z.number().min(0).nullable().optional(),
2451
2463
  userId: nonEmptyTrimmedString.nullable().optional()
2452
2464
  })
2453
2465
  .superRefine((value, context) => {
@@ -2482,6 +2494,8 @@ export const createTaskTimeboxSchema = z
2482
2494
  source: calendarTimeboxSourceSchema.default("manual"),
2483
2495
  status: calendarTimeboxStatusSchema.default("planned"),
2484
2496
  overrideReason: trimmedString.nullable().default(null),
2497
+ activityPresetKey: trimmedString.nullable().optional(),
2498
+ customSustainRateApPerHour: z.number().min(0).nullable().optional(),
2485
2499
  userId: nonEmptyTrimmedString.nullable().optional()
2486
2500
  })
2487
2501
  .superRefine((value, context) => {
@@ -2499,6 +2513,8 @@ export const updateTaskTimeboxSchema = z.object({
2499
2513
  endsAt: z.string().datetime().optional(),
2500
2514
  status: calendarTimeboxStatusSchema.optional(),
2501
2515
  overrideReason: trimmedString.nullable().optional(),
2516
+ activityPresetKey: trimmedString.nullable().optional(),
2517
+ customSustainRateApPerHour: z.number().min(0).nullable().optional(),
2502
2518
  userId: nonEmptyTrimmedString.nullable().optional()
2503
2519
  });
2504
2520
  export const recommendTaskTimeboxesSchema = z.object({
@@ -2530,6 +2546,8 @@ export const updateCalendarEventSchema = z
2530
2546
  availability: calendarAvailabilitySchema.optional(),
2531
2547
  eventType: trimmedString.optional(),
2532
2548
  categories: z.array(trimmedString).optional(),
2549
+ activityPresetKey: trimmedString.nullable().optional(),
2550
+ customSustainRateApPerHour: z.number().min(0).nullable().optional(),
2533
2551
  preferredCalendarId: nonEmptyTrimmedString.nullable().optional(),
2534
2552
  userId: nonEmptyTrimmedString.nullable().optional(),
2535
2553
  links: z
@@ -2582,6 +2600,8 @@ export const createCalendarEventSchema = z
2582
2600
  availability: calendarAvailabilitySchema.default("busy"),
2583
2601
  eventType: trimmedString.default(""),
2584
2602
  categories: z.array(trimmedString).default([]),
2603
+ activityPresetKey: trimmedString.nullable().optional(),
2604
+ customSustainRateApPerHour: z.number().min(0).nullable().optional(),
2585
2605
  preferredCalendarId: nonEmptyTrimmedString.nullable().optional(),
2586
2606
  userId: nonEmptyTrimmedString.nullable().optional(),
2587
2607
  links: z
@@ -394,6 +394,7 @@ export function normalizeForgeSnapshot(raw) {
394
394
  spentTodayAp: 0,
395
395
  remainingAp: 200,
396
396
  forecastAp: 0,
397
+ plannedRemainingAp: 0,
397
398
  targetBandMinAp: 170,
398
399
  targetBandMaxAp: 200,
399
400
  instantCapacityApPerHour: 0,
@@ -407,6 +408,7 @@ export function normalizeForgeSnapshot(raw) {
407
408
  stats: [],
408
409
  currentCurve: [],
409
410
  activeDrains: [],
411
+ plannedDrains: [],
410
412
  warnings: [],
411
413
  recommendations: [],
412
414
  topTaskIdsNeedingSplit: [],
@@ -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.27",
5
+ "version": "0.2.28",
6
6
  "skills": [
7
7
  "./skills"
8
8
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forge-openclaw-plugin",
3
- "version": "0.2.27",
3
+ "version": "0.2.28",
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": "MIT",
@@ -56,6 +56,7 @@ Entity conversation rule:
56
56
  - Before you ask, decide the exact missing thing you need and how that answer will help you name, place, or save the record.
57
57
  - Prefer a progression of:
58
58
  concrete example or intent -> working name -> purpose or meaning -> placement in Forge -> operational details -> linked context.
59
+ - Use those same playbooks for action-heavy non-Psyche flows such as `work_adjustment`, `preference_judgment`, `preference_signal`, and specialized `movement`, `life_force`, or `workbench` requests so the conversation starts from what the user is trying to understand, change, add, update, link, or run before you choose the route.
59
60
  - For emotionally meaningful non-Psyche records such as goals, habits, and notes, reflect the meaning before you ask for structure.
60
61
  - When the user is vague, ask for one small concrete example, stake, or desired outcome before you ask them to name the record.
61
62
  - When the user is clear, say what the record seems to be becoming and ask only for the last missing detail.
@@ -291,9 +292,25 @@ Use the wiki tools for file-first memory work:
291
292
  Use the health tools for review and reflective enrichment, not as the default CRUD architecture:
292
293
  `forge_get_sleep_overview`, `forge_get_sports_overview`, `forge_update_sleep_session`, `forge_update_workout_session`
293
294
 
295
+ Use the dedicated domain routes for specialized surfaces that are not simple batch entities:
296
+
297
+ - Movement lives under `/api/v1/movement/*`. Treat it as a dedicated timeline of `stays` and `trips`, not as generic batch CRUD. A `stay` means the user remained in the same place for a span of time. A `trip` means the user traveled between places. Use the movement routes when the user wants to understand time in place, travel behavior, specific stays or trips, known places, or selected-span aggregates such as "how long was I at home in the past 2 weeks?" or "when did I travel last month?".
298
+ - Movement user actions are: query movement behavior, add a place or manual stay/trip overlay, update an existing stay/trip/place, or link a specific movement item to another Forge entity. Keep the explanation user-facing: where they stayed, when they traveled, what changed, and what this movement should be linked to.
299
+ - When the user is filling a missing-data gap, the default write path is a user-defined overlay box, not a raw stay or trip patch. Use `POST /api/v1/movement/user-boxes/preflight` if you need to confirm overlap or snap to the nearest missing interval, then `POST /api/v1/movement/user-boxes` with `kind: "stay"` or `kind: "trip"`.
300
+ - Use `PATCH /api/v1/movement/stays/:id` or `PATCH /api/v1/movement/trips/:id` only when the user is editing an existing recorded stay or recorded trip. Do not use those routes to fill a missing span.
301
+ - If the user says something as explicit as "that missing block was me staying home", do not reopen broad intake. Confirm the interval or place only if it is still ambiguous, then create the overlay and read the timeline back.
302
+ - Life Force lives under `/api/v1/life-force*`. Use `GET /api/v1/life-force` for the current energy overview, `PATCH /api/v1/life-force/profile` for durable profile changes, `PUT /api/v1/life-force/templates/:weekday` for weekday curve edits, and `POST /api/v1/life-force/fatigue-signals` for real-time tired or recovered signals.
303
+ - Workbench lives under `/api/v1/workbench/*`. Use those dedicated routes for flow catalog reads, flow CRUD, runs, published outputs, node results, and latest-node-output reads instead of trying to force Workbench through the batch entity routes.
304
+ - If you are unsure which specialized route family applies, check `forge_get_agent_onboarding` and use its `entityRouteModel.specializedDomainSurfaces` section before guessing.
305
+
294
306
  Use live work tools for `task_run`:
295
307
  `forge_log_work`, `forge_start_task_run`, `forge_heartbeat_task_run`, `forge_focus_task_run`, `forge_complete_task_run`, `forge_release_task_run`
296
308
 
309
+ Use `forge_adjust_work_minutes` for `work_adjustment` when the user wants a truthful signed minute correction on an existing task or project rather than a fake live run or a retroactive new task.
310
+
311
+ Use the dedicated Preferences action tools for `preference_judgment` and `preference_signal`:
312
+ `forge_submit_preferences_judgment`, `forge_submit_preferences_signal`, `forge_update_preferences_score`
313
+
297
314
  Use `forge_post_insight` for `insight`.
298
315
  Use the calendar tools for provider sync and planning:
299
316
  `forge_get_calendar_overview`, `forge_connect_calendar_provider`, `forge_sync_calendar_connection`, `forge_create_work_block_template`, `forge_recommend_task_timeboxes`, `forge_create_task_timebox`
@@ -11,6 +11,9 @@ Forge correctly, and gather only the structure that still matters.
11
11
  with the entity label.
12
12
  - Start by saying what seems to matter here or what the record is becoming, then ask
13
13
  the next useful question.
14
+ - Whenever you can, make the direction of the intake visible before the question by
15
+ naming what you think the user is trying to preserve, clarify, decide, schedule, or
16
+ make easier.
14
17
  - Ask only for what is missing or still unclear.
15
18
  - Before every question, decide the one missing thing you are trying to clarify.
16
19
  - Ask first for the missing thing that would change the record shape, title, or next
@@ -28,6 +31,8 @@ Forge correctly, and gather only the structure that still matters.
28
31
  short reflection -> one orienting question.
29
32
  - When the user is vague, ask for the smallest real example, desired outcome, or stake
30
33
  before you ask for wording.
34
+ - For strategic, reflective, or emotionally meaningful non-Psyche records, ask what
35
+ feels important to keep true before you ask for labels, dates, or taxonomy.
31
36
  - When the user is clear, say what the record seems to be becoming and move straight to
32
37
  the last missing structural detail.
33
38
  - For straightforward logistical entities such as tasks, calendar events, work blocks,
@@ -36,6 +41,11 @@ Forge correctly, and gather only the structure that still matters.
36
41
  - For logistical records such as tasks, calendar events, work blocks, timeboxes, and
37
42
  task runs, use a fast path:
38
43
  one brief confirming sentence -> one operational question.
44
+ - For action-heavy flows such as work adjustments, preference judgments, preference
45
+ signals, and specialized surface work in Movement, Life Force, or Workbench, first
46
+ ask what the user is trying to understand, change, add, update, link, or run, then
47
+ route to the dedicated action or surface path instead of pretending it is normal
48
+ CRUD.
39
49
  - Do not read schema fields out loud unless the user explicitly wants a checklist.
40
50
  - One focused question is the default. Ask two only when both questions serve the same
41
51
  job and the user is steady enough for it.
@@ -191,6 +201,35 @@ reusable records.
191
201
  - Once the distinction is clear, offer a candidate label yourself and invite
192
202
  correction instead of making the user wordsmith alone.
193
203
 
204
+ ## Opening move recipes
205
+
206
+ Use these when you want the first turn to feel more guided and less form-like.
207
+
208
+ Strategic record:
209
+
210
+ - "This sounds like something you want to hold onto directionally, not just list.
211
+ What would feel important to keep true here?"
212
+
213
+ Bounded-work record:
214
+
215
+ - "This sounds like it wants to become a real piece of work. What outcome would make
216
+ it feel meaningfully real for now?"
217
+
218
+ Reflective record:
219
+
220
+ - "There is something here you do not want to lose. What feels most worth capturing
221
+ before we decide where to store it?"
222
+
223
+ Reusable record:
224
+
225
+ - "Before we settle the label, what future decision, comparison, or retrieval moment
226
+ should this help with?"
227
+
228
+ Operational record:
229
+
230
+ - "I can turn that into a concrete Forge action. What is the one timing, owner, or
231
+ placement detail that still needs to be decided?"
232
+
194
233
  ## Name, Define, Connect
195
234
 
196
235
  Once the core record is visible, use this short checkpoint.
@@ -208,6 +247,17 @@ Connect:
208
247
  - ask about links only after the record itself feels named and defined enough to stay
209
248
  stable
210
249
 
250
+ ## Close cleanly
251
+
252
+ - Once the record has a working shape, tell the user what is now clear and what one
253
+ detail, if any, is still worth deciding.
254
+ - If no detail is still decision-relevant, summarize the record in plain language and
255
+ move to the save.
256
+ - Prefer "what I have now is..." or "what seems clear now is..." over a cold final
257
+ field check.
258
+ - If the user gives a correction, revise the working formulation once and close again
259
+ instead of reopening the whole intake.
260
+
211
261
  ## Question design rules
212
262
 
213
263
  - Let each question have one job:
@@ -249,6 +299,8 @@ Connect:
249
299
  inside them.
250
300
  - After the user answers, prefer "what is becoming clearer is..." over a cold jump to
251
301
  the next field.
302
+ - For reusable or abstract records, it is often better to say "what this would help
303
+ you decide later is..." before asking for the final wording.
252
304
 
253
305
  ## Ready-to-save check
254
306
 
@@ -644,6 +696,33 @@ Preferred opening question:
644
696
 
645
697
  - "Which task should I start?"
646
698
 
699
+ ## Work Adjustment
700
+
701
+ Aim: correct tracked minutes truthfully without pretending a live run happened.
702
+
703
+ Arc:
704
+
705
+ 1. Ask what existing task or project the minutes belong to.
706
+ 2. Ask whether time should be added or removed.
707
+ 3. Ask what real work or correction the adjustment is meant to capture.
708
+ 4. Ask for a short audit note only if the reason would otherwise be unclear later.
709
+
710
+ Helpful follow-up lanes:
711
+
712
+ - what record the correction belongs to
713
+ - whether the adjustment is positive or negative
714
+ - what truthful reason should stay attached to the correction
715
+
716
+ Ready to act when:
717
+
718
+ - the target task or project is clear
719
+ - the minute delta is clear
720
+ - the note is clear enough when an audit trail matters
721
+
722
+ Preferred opening question:
723
+
724
+ - "Which task or project should this time correction belong to?"
725
+
647
726
  ## Self Observation
648
727
 
649
728
  Aim: capture one observation clearly enough that it can support later reflection
@@ -741,6 +820,165 @@ Preferred opening question:
741
820
 
742
821
  - "Which calendar provider are you trying to connect, and what do you want Forge to do with it?"
743
822
 
823
+ ## Preference Judgment
824
+
825
+ Aim: capture one pairwise preference decision with the right context, not just log a
826
+ left-versus-right click.
827
+
828
+ Arc:
829
+
830
+ 1. Ask what comparison the user is actually trying to settle.
831
+ 2. Ask which context or domain this judgment belongs to.
832
+ 3. Ask whether the result is left, right, tie, or skip.
833
+ 4. Ask for reason tags or strength only if they will improve later interpretation.
834
+
835
+ Helpful follow-up lanes:
836
+
837
+ - what the comparison is really about
838
+ - which preference context should own the signal
839
+ - whether the choice feels decisive, weak, tied, or not ready
840
+
841
+ Ready to act when:
842
+
843
+ - the left and right items are clear
844
+ - the outcome is clear
845
+ - the relevant context or profile is clear enough
846
+
847
+ Preferred opening question:
848
+
849
+ - "What comparison are you actually trying to settle here?"
850
+
851
+ ## Preference Signal
852
+
853
+ Aim: store a direct preference signal such as favorite, veto, bookmark, or
854
+ compare-later with the context that makes it interpretable later.
855
+
856
+ Arc:
857
+
858
+ 1. Ask what item the user wants to mark.
859
+ 2. Ask what signal they want to give it.
860
+ 3. Ask what domain or context this belongs to if that is still unclear.
861
+ 4. Ask about strength only if the user is expressing a gradient rather than a simple mark.
862
+
863
+ Helpful follow-up lanes:
864
+
865
+ - what item is being marked
866
+ - whether this is a favorite, veto, bookmark, neutral, or compare-later signal
867
+ - what context makes the signal meaningful
868
+
869
+ Ready to act when:
870
+
871
+ - the item is clear
872
+ - the signal type is clear
873
+ - the context is clear enough if it changes interpretation
874
+
875
+ Preferred opening question:
876
+
877
+ - "What do you want Forge to remember about this item right now?"
878
+
879
+ ## Movement
880
+
881
+ Aim: clarify whether the user wants to understand time in place, review travel
882
+ behavior, add or update a stay or trip, inspect one place, or link movement context to
883
+ another Forge record before choosing the dedicated route family.
884
+
885
+ Arc:
886
+
887
+ 1. Ask whether the user is trying to query behavior, add something manually, update an existing movement item, or link movement to another Forge entity.
888
+ 2. Ask whether the focus is a stay, a trip, a place, a timeline window, or a selected span.
889
+ 3. Ask for the time window, place, or movement item that makes the question concrete.
890
+ 4. Ask what they are trying to notice, preserve, or answer through that movement context.
891
+ 5. Route to the dedicated movement read or write path once the surface is clear.
892
+
893
+ Direct action rules:
894
+
895
+ - If the user is clearly talking about a missing-data gap that should become a stay or
896
+ trip, use a user-defined movement box.
897
+ - Preflight with `/api/v1/movement/user-boxes/preflight` when overlap or exact timing
898
+ is unclear, then create the overlay with `/api/v1/movement/user-boxes`.
899
+ - Use `kind: "stay"` when the user stayed in one place and `kind: "trip"` when they
900
+ traveled.
901
+ - Use raw `PATCH /api/v1/movement/stays/:id` or `/api/v1/movement/trips/:id` only for
902
+ editing an already-recorded stay or trip, not for filling a missing span.
903
+ - When the user has already given the real answer, for example "I stayed home during
904
+ that missing block", do not ask a broad review question again. Confirm only the
905
+ interval or place if that is still ambiguous, then act.
906
+
907
+ Helpful follow-up lanes:
908
+
909
+ - whether the user wants time-in-place, travel history, one specific stay or trip, a
910
+ place summary, or a link
911
+ - what time window, place, stay, trip, or selection is in scope
912
+ - whether the question is behavioral, such as time at home, travel frequency, or place
913
+ distribution, versus an edit
914
+ - whether the edit is a missing-gap overlay versus a true recorded stay/trip patch
915
+
916
+ Ready to act when:
917
+
918
+ - the movement surface is clear
919
+ - the time range, place, stay, trip, or selection is clear enough
920
+ - the user goal is clear enough to choose the route
921
+
922
+ Preferred opening question:
923
+
924
+ - "Are you trying to understand where you stayed and traveled, change one stay or trip, or answer a question about your movement behavior?"
925
+
926
+ ## Life Force
927
+
928
+ Aim: clarify whether the user wants to review current energy state, change durable
929
+ profile assumptions, edit weekday curves, or log a real-time fatigue signal.
930
+
931
+ Arc:
932
+
933
+ 1. Ask whether the job is overview, profile change, weekday-template change, or fatigue signaling.
934
+ 2. Ask what part of the current energy picture feels most important or inaccurate.
935
+ 3. Ask what should stay true if they are changing profile or template assumptions.
936
+ 4. Route to the dedicated life-force path once the lane is clear.
937
+
938
+ Helpful follow-up lanes:
939
+
940
+ - whether the user wants explanation, editing, or signaling
941
+ - what part of the energy model feels off or useful
942
+ - what durable assumption versus real-time state is being changed
943
+
944
+ Ready to act when:
945
+
946
+ - the life-force lane is clear
947
+ - the relevant weekday, profile field, or signal is clear enough
948
+ - the user intent is clear enough to choose overview versus mutation
949
+
950
+ Preferred opening question:
951
+
952
+ - "Do you want to understand the current energy picture, change how Forge models it, or log how you feel right now?"
953
+
954
+ ## Workbench
955
+
956
+ Aim: clarify whether the user wants to inspect a flow, edit it, run it, or inspect
957
+ results so the agent uses the dedicated workbench contract instead of vague CRUD.
958
+
959
+ Arc:
960
+
961
+ 1. Ask whether the job is flow discovery, one flow edit, execution, run history, published output, node-level inspection, or latest-node-output lookup.
962
+ 2. Ask which flow, slug, run, or node the request is about.
963
+ 3. Ask what the user is trying to learn, repair, or publish through that flow.
964
+ 4. Route to the dedicated workbench route family once the execution lane is clear.
965
+
966
+ Helpful follow-up lanes:
967
+
968
+ - whether the user wants structure, execution, or results
969
+ - what exact flow or run is in scope
970
+ - whether they need whole-flow output or node-level detail
971
+
972
+ Ready to act when:
973
+
974
+ - the workbench lane is clear
975
+ - the flow, run, or node is clear enough
976
+ - the requested read or mutation is clear enough to choose the route
977
+
978
+ Preferred opening question:
979
+
980
+ - "Are you trying to inspect a flow, change it, run it, or inspect one run's outputs?"
981
+
744
982
  ## Preference Catalog
745
983
 
746
984
  Aim: define a useful comparison pool, not just a list with no decision purpose.
@@ -11,6 +11,15 @@ Forge without turning the conversation into a worksheet.
11
11
  experience, not like a schema form and not like a lecturer.
12
12
  - Name the emotional center or lived stake in plain language before the next question
13
13
  whenever that would help the user feel accurately understood.
14
+ - Begin close to the living center of the moment:
15
+ danger,
16
+ shame,
17
+ grief,
18
+ anger,
19
+ collapse,
20
+ longing,
21
+ pressure,
22
+ or protection.
14
23
  - Stay collaborative. Do not claim certainty about what a belief, pattern, or mode
15
24
  "really is".
16
25
  - Start from lived experience before abstraction.
@@ -40,6 +49,8 @@ Forge without turning the conversation into a worksheet.
40
49
  the user can feel understood and correct you if needed.
41
50
  - When the material is charged, ask permission before moving from understanding into
42
51
  naming, challenging, or solution-finding.
52
+ - Your first job is not interpretation. It is to make the moment feel graspable enough
53
+ that the user can stay with it and describe it.
43
54
  - Before you ask for change, naming, or repair, usually ask what the experience is
44
55
  trying to protect, prevent, or hold onto.
45
56
  - The warmth should come from accuracy and steadiness, not from extra softness,
@@ -58,6 +69,42 @@ Forge without turning the conversation into a worksheet.
58
69
  - When the user has said enough for an accurate working formulation, stop deepening and
59
70
  help them name it cleanly.
60
71
 
72
+ ## First reflection menu
73
+
74
+ Use one brief reflection that matches the center of the moment before you deepen.
75
+
76
+ Threat:
77
+
78
+ - "Something in this landed as danger very quickly."
79
+
80
+ Shame or collapse:
81
+
82
+ - "The painful part seems to be what this starts to say about your worth."
83
+
84
+ Pressure or control:
85
+
86
+ - "It sounds like a part of you moved fast to keep things from getting worse."
87
+
88
+ Loss or longing:
89
+
90
+ - "There is a lot of ache in what mattered there."
91
+
92
+ Confusion:
93
+
94
+ - "The moment still feels tangled, so let us stay close to one slice of it."
95
+
96
+ ## Permission pivots
97
+
98
+ Use these when you are about to move from understanding into naming, interpretation,
99
+ or change.
100
+
101
+ - "I think I have the shape of it more clearly now. Do you want me to stay with the
102
+ experience a little longer, or try putting language around it?"
103
+ - "There may be a belief or mode here. Do you want a tentative formulation, or should
104
+ we keep clarifying the moment first?"
105
+ - "I can help think about what might help next time, but I want to check whether the
106
+ experience itself feels understood enough first."
107
+
61
108
  ## Therapist micro-skills
62
109
 
63
110
  Use these in small doses rather than as a script.
@@ -281,6 +328,7 @@ When the lived experience is clear enough to name:
281
328
  - invite correction without defensiveness
282
329
  - if the wording is close but not right, revise it with the user once instead of
283
330
  restarting the whole intake
331
+ - say in plain language what makes you think the proposed wording fits
284
332
 
285
333
  Example shape:
286
334
 
@@ -308,6 +356,15 @@ If the entity is not yet clear:
308
356
  - once the user accepts the wording, do not reopen deeper exploration unless they ask
309
357
  for it
310
358
 
359
+ ## Change and save pivots
360
+
361
+ - Before change-oriented questions, check whether the user wants understanding,
362
+ naming, or next-step help.
363
+ - When the user says the formulation lands, summarize it once in their language and
364
+ move to the write.
365
+ - If another belief, value, pattern, mode, or note becomes visible, name it gently but
366
+ do not switch containers unless the user wants to.
367
+
311
368
  ## Psyche update loop
312
369
 
313
370
  Use this when the user is revising an existing Psyche record rather than creating one