forge-openclaw-plugin 0.2.28 → 0.2.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/assets/{board-DPFvZf-D.js → board-q8cfwaAW.js} +2 -2
- package/dist/assets/{board-DPFvZf-D.js.map → board-q8cfwaAW.js.map} +1 -1
- package/dist/assets/index-C6PCeHD_.css +1 -0
- package/dist/assets/index-bfHIqj0-.js +85 -0
- package/dist/assets/index-bfHIqj0-.js.map +1 -0
- package/dist/assets/{motion-Bvwc85ch.js → motion-DHfqFntt.js} +2 -2
- package/dist/assets/{motion-Bvwc85ch.js.map → motion-DHfqFntt.js.map} +1 -1
- package/dist/assets/{table-FJQTJvUR.js → table-DLweENXt.js} +2 -2
- package/dist/assets/{table-FJQTJvUR.js.map → table-DLweENXt.js.map} +1 -1
- package/dist/assets/{ui-GXFcgvSw.js → ui-BV0OYxkH.js} +2 -2
- package/dist/assets/{ui-GXFcgvSw.js.map → ui-BV0OYxkH.js.map} +1 -1
- package/dist/assets/{vendor-Cwf49UMz.js → vendor-OwcH20PM.js} +2 -2
- package/dist/assets/{vendor-Cwf49UMz.js.map → vendor-OwcH20PM.js.map} +1 -1
- package/dist/index.html +7 -7
- package/dist/server/server/migrations/044_macos_local_calendar_provider.sql +21 -0
- package/dist/server/server/src/app.js +87 -12
- package/dist/server/server/src/openapi.js +29 -1
- package/dist/server/server/src/repositories/calendar.js +144 -12
- package/dist/server/server/src/repositories/tasks.js +36 -17
- package/dist/server/server/src/services/calendar-runtime.js +613 -32
- package/dist/server/server/src/services/macos-calendar-helper.js +748 -0
- package/dist/server/server/src/types.js +46 -2
- package/dist/server/src/lib/api-error.js +2 -0
- package/dist/server/src/lib/api.js +39 -2
- package/dist/server/src/lib/calendar-name-deduper.js +2 -0
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/server/migrations/044_macos_local_calendar_provider.sql +21 -0
- package/skills/forge-openclaw/SKILL.md +21 -5
- package/skills/forge-openclaw/entity_conversation_playbooks.md +88 -5
- package/dist/assets/index-Auw3JrdE.css +0 -1
- package/dist/assets/index-D1H7myQH.js +0 -85
- package/dist/assets/index-D1H7myQH.js.map +0 -1
|
@@ -45,7 +45,8 @@ export const calendarProviderSchema = z.enum([
|
|
|
45
45
|
"google",
|
|
46
46
|
"apple",
|
|
47
47
|
"caldav",
|
|
48
|
-
"microsoft"
|
|
48
|
+
"microsoft",
|
|
49
|
+
"macos_local"
|
|
49
50
|
]);
|
|
50
51
|
export const calendarConnectionStatusSchema = z.enum([
|
|
51
52
|
"connected",
|
|
@@ -59,8 +60,16 @@ export const calendarEventOriginSchema = z.enum([
|
|
|
59
60
|
"apple",
|
|
60
61
|
"caldav",
|
|
61
62
|
"microsoft",
|
|
63
|
+
"macos_local",
|
|
62
64
|
"derived"
|
|
63
65
|
]);
|
|
66
|
+
export const macosCalendarAccessStatusSchema = z.enum([
|
|
67
|
+
"not_determined",
|
|
68
|
+
"denied",
|
|
69
|
+
"restricted",
|
|
70
|
+
"full_access",
|
|
71
|
+
"unavailable"
|
|
72
|
+
]);
|
|
64
73
|
export const calendarAvailabilitySchema = z.enum(["busy", "free"]);
|
|
65
74
|
export const calendarEventStatusSchema = z.enum([
|
|
66
75
|
"confirmed",
|
|
@@ -792,7 +801,13 @@ export const calendarDiscoveryCalendarSchema = z.object({
|
|
|
792
801
|
isPrimary: z.boolean(),
|
|
793
802
|
canWrite: z.boolean(),
|
|
794
803
|
selectedByDefault: z.boolean(),
|
|
795
|
-
isForgeCandidate: z.boolean()
|
|
804
|
+
isForgeCandidate: z.boolean(),
|
|
805
|
+
sourceId: trimmedString.nullable().default(null),
|
|
806
|
+
sourceTitle: trimmedString.nullable().default(null),
|
|
807
|
+
sourceType: trimmedString.nullable().default(null),
|
|
808
|
+
calendarType: trimmedString.nullable().default(null),
|
|
809
|
+
hostCalendarId: trimmedString.nullable().default(null),
|
|
810
|
+
canonicalKey: trimmedString.nullable().default(null)
|
|
796
811
|
});
|
|
797
812
|
export const calendarDiscoveryPayloadSchema = z.object({
|
|
798
813
|
provider: calendarProviderSchema,
|
|
@@ -802,6 +817,19 @@ export const calendarDiscoveryPayloadSchema = z.object({
|
|
|
802
817
|
homeUrl: z.string().nullable(),
|
|
803
818
|
calendars: z.array(calendarDiscoveryCalendarSchema)
|
|
804
819
|
});
|
|
820
|
+
export const macosLocalCalendarSourceSchema = z.object({
|
|
821
|
+
sourceId: nonEmptyTrimmedString,
|
|
822
|
+
sourceTitle: trimmedString,
|
|
823
|
+
sourceType: trimmedString,
|
|
824
|
+
accountLabel: trimmedString,
|
|
825
|
+
accountIdentityKey: trimmedString,
|
|
826
|
+
calendars: z.array(calendarDiscoveryCalendarSchema)
|
|
827
|
+
});
|
|
828
|
+
export const macosLocalCalendarDiscoveryPayloadSchema = z.object({
|
|
829
|
+
status: macosCalendarAccessStatusSchema,
|
|
830
|
+
requestedAt: z.string(),
|
|
831
|
+
sources: z.array(macosLocalCalendarSourceSchema)
|
|
832
|
+
});
|
|
805
833
|
export const calendarSchema = z.object({
|
|
806
834
|
id: z.string(),
|
|
807
835
|
connectionId: z.string(),
|
|
@@ -814,6 +842,12 @@ export const calendarSchema = z.object({
|
|
|
814
842
|
canWrite: z.boolean(),
|
|
815
843
|
selectedForSync: z.boolean(),
|
|
816
844
|
forgeManaged: z.boolean(),
|
|
845
|
+
sourceId: trimmedString.nullable().default(null),
|
|
846
|
+
sourceTitle: trimmedString.nullable().default(null),
|
|
847
|
+
sourceType: trimmedString.nullable().default(null),
|
|
848
|
+
calendarType: trimmedString.nullable().default(null),
|
|
849
|
+
hostCalendarId: trimmedString.nullable().default(null),
|
|
850
|
+
canonicalKey: trimmedString.nullable().default(null),
|
|
817
851
|
lastSyncedAt: z.string().nullable(),
|
|
818
852
|
createdAt: z.string(),
|
|
819
853
|
updatedAt: z.string()
|
|
@@ -2358,6 +2392,15 @@ export const createCalendarConnectionSchema = z.discriminatedUnion("provider", [
|
|
|
2358
2392
|
label: nonEmptyTrimmedString,
|
|
2359
2393
|
authSessionId: nonEmptyTrimmedString,
|
|
2360
2394
|
selectedCalendarUrls: z.array(nonEmptyTrimmedString.url()).min(1)
|
|
2395
|
+
}),
|
|
2396
|
+
z.object({
|
|
2397
|
+
provider: z.literal("macos_local"),
|
|
2398
|
+
label: nonEmptyTrimmedString,
|
|
2399
|
+
sourceId: nonEmptyTrimmedString,
|
|
2400
|
+
selectedCalendarUrls: z.array(nonEmptyTrimmedString.url()).min(1),
|
|
2401
|
+
forgeCalendarUrl: nonEmptyTrimmedString.url().nullable().optional(),
|
|
2402
|
+
createForgeCalendar: z.boolean().optional().default(false),
|
|
2403
|
+
replaceConnectionIds: z.array(nonEmptyTrimmedString).optional().default([])
|
|
2361
2404
|
})
|
|
2362
2405
|
]);
|
|
2363
2406
|
export const discoverCalendarConnectionSchema = z.discriminatedUnion("provider", [
|
|
@@ -2834,6 +2877,7 @@ export const updateTaskSchema = z.object({
|
|
|
2834
2877
|
title: nonEmptyTrimmedString.optional(),
|
|
2835
2878
|
description: trimmedString.optional(),
|
|
2836
2879
|
status: taskStatusSchema.optional(),
|
|
2880
|
+
completedAt: dateTimeSchema.optional(),
|
|
2837
2881
|
priority: taskPrioritySchema.optional(),
|
|
2838
2882
|
owner: nonEmptyTrimmedString.optional(),
|
|
2839
2883
|
userId: nonEmptyTrimmedString.nullable().optional(),
|
|
@@ -3,6 +3,7 @@ export class ForgeApiError extends Error {
|
|
|
3
3
|
code;
|
|
4
4
|
details;
|
|
5
5
|
requestPath;
|
|
6
|
+
response;
|
|
6
7
|
constructor(input) {
|
|
7
8
|
super(input.message);
|
|
8
9
|
this.name = "ForgeApiError";
|
|
@@ -10,6 +11,7 @@ export class ForgeApiError extends Error {
|
|
|
10
11
|
this.code = input.code;
|
|
11
12
|
this.details = input.details ?? [];
|
|
12
13
|
this.requestPath = input.requestPath;
|
|
14
|
+
this.response = input.response ?? null;
|
|
13
15
|
}
|
|
14
16
|
}
|
|
15
17
|
export function describeApiError(error) {
|
|
@@ -130,7 +130,12 @@ async function request(path, init) {
|
|
|
130
130
|
? body
|
|
131
131
|
: `Request failed: ${response.status}`,
|
|
132
132
|
requestPath: path,
|
|
133
|
-
details
|
|
133
|
+
details,
|
|
134
|
+
response: typeof body === "string"
|
|
135
|
+
? body
|
|
136
|
+
: body && typeof body === "object"
|
|
137
|
+
? body
|
|
138
|
+
: null
|
|
134
139
|
});
|
|
135
140
|
}
|
|
136
141
|
return body;
|
|
@@ -161,7 +166,12 @@ async function requestBlob(path, init) {
|
|
|
161
166
|
? maybeBody.message
|
|
162
167
|
: `Request failed: ${response.status}`,
|
|
163
168
|
requestPath: path,
|
|
164
|
-
details: []
|
|
169
|
+
details: [],
|
|
170
|
+
response: typeof body === "string"
|
|
171
|
+
? body
|
|
172
|
+
: body && typeof body === "object"
|
|
173
|
+
? body
|
|
174
|
+
: null
|
|
165
175
|
});
|
|
166
176
|
}
|
|
167
177
|
const disposition = response.headers.get("content-disposition");
|
|
@@ -1109,6 +1119,33 @@ export function discoverCalendarConnection(input) {
|
|
|
1109
1119
|
discovery: dedupeCalendarDiscoveryPayload(response.discovery)
|
|
1110
1120
|
}));
|
|
1111
1121
|
}
|
|
1122
|
+
export function getMacOSLocalCalendarStatus() {
|
|
1123
|
+
return request("/api/v1/calendar/macos-local/status");
|
|
1124
|
+
}
|
|
1125
|
+
export function requestMacOSLocalCalendarAccess() {
|
|
1126
|
+
return request("/api/v1/calendar/macos-local/request-access", {
|
|
1127
|
+
method: "POST"
|
|
1128
|
+
});
|
|
1129
|
+
}
|
|
1130
|
+
export function discoverMacOSLocalCalendarSources() {
|
|
1131
|
+
return request("/api/v1/calendar/macos-local/discovery").then((response) => ({
|
|
1132
|
+
...response,
|
|
1133
|
+
discovery: {
|
|
1134
|
+
...response.discovery,
|
|
1135
|
+
sources: response.discovery.sources.map((source) => ({
|
|
1136
|
+
...source,
|
|
1137
|
+
calendars: dedupeCalendarDiscoveryPayload({
|
|
1138
|
+
provider: "macos_local",
|
|
1139
|
+
accountLabel: source.accountLabel,
|
|
1140
|
+
serverUrl: "forge-macos-local://eventkit/",
|
|
1141
|
+
principalUrl: null,
|
|
1142
|
+
homeUrl: null,
|
|
1143
|
+
calendars: source.calendars
|
|
1144
|
+
}).calendars
|
|
1145
|
+
}))
|
|
1146
|
+
}
|
|
1147
|
+
}));
|
|
1148
|
+
}
|
|
1112
1149
|
export function startGoogleCalendarOauth(input) {
|
|
1113
1150
|
return request("/api/v1/calendar/oauth/google/start", {
|
|
1114
1151
|
method: "POST",
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
ALTER TABLE calendar_calendars
|
|
2
|
+
ADD COLUMN source_id TEXT;
|
|
3
|
+
|
|
4
|
+
ALTER TABLE calendar_calendars
|
|
5
|
+
ADD COLUMN source_title TEXT;
|
|
6
|
+
|
|
7
|
+
ALTER TABLE calendar_calendars
|
|
8
|
+
ADD COLUMN source_type TEXT;
|
|
9
|
+
|
|
10
|
+
ALTER TABLE calendar_calendars
|
|
11
|
+
ADD COLUMN calendar_type TEXT;
|
|
12
|
+
|
|
13
|
+
ALTER TABLE calendar_calendars
|
|
14
|
+
ADD COLUMN host_calendar_id TEXT;
|
|
15
|
+
|
|
16
|
+
ALTER TABLE calendar_calendars
|
|
17
|
+
ADD COLUMN canonical_key TEXT;
|
|
18
|
+
|
|
19
|
+
UPDATE calendar_calendars
|
|
20
|
+
SET canonical_key = remote_id
|
|
21
|
+
WHERE canonical_key IS NULL OR TRIM(canonical_key) = '';
|
|
@@ -57,9 +57,15 @@ Entity conversation rule:
|
|
|
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
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.
|
|
60
|
+
- When the operation is not already explicit, identify the job first:
|
|
61
|
+
add, update, review, compare, navigate, link, or run. Skip that meta question
|
|
62
|
+
when the action is already obvious from the user's wording.
|
|
60
63
|
- For emotionally meaningful non-Psyche records such as goals, habits, and notes, reflect the meaning before you ask for structure.
|
|
61
64
|
- When the user is vague, ask for one small concrete example, stake, or desired outcome before you ask them to name the record.
|
|
62
65
|
- When the user is clear, say what the record seems to be becoming and ask only for the last missing detail.
|
|
66
|
+
- When the user wants to review, compare, inspect, or navigate an existing Forge
|
|
67
|
+
record, ask what they are trying to understand first and prefer the read path before
|
|
68
|
+
you reopen create or update intake.
|
|
63
69
|
- When updating an entity, start with what is changing, what should stay true, and what prompted the update now.
|
|
64
70
|
- When enough is clear, briefly summarize what you heard in the user's own language before asking for the last missing structural detail.
|
|
65
71
|
- The quick intake prompts later in this file are fallback checkpoints, not a script to read aloud.
|
|
@@ -261,8 +267,9 @@ Minimum field: `label`
|
|
|
261
267
|
Usually useful: `description`
|
|
262
268
|
Ask:
|
|
263
269
|
|
|
264
|
-
1. What
|
|
265
|
-
2. What
|
|
270
|
+
1. What kind of repeated moment or incident do you want future reports to name the same way?
|
|
271
|
+
2. What would count as inside this category, and what should stay outside it?
|
|
272
|
+
3. If the meaning is clear but the wording is not, would you like me to suggest a concise label?
|
|
266
273
|
|
|
267
274
|
`emotion_definition`
|
|
268
275
|
Use for a reusable emotion vocabulary entry.
|
|
@@ -270,9 +277,9 @@ Minimum field: `label`
|
|
|
270
277
|
Usually useful: `description`, `category`
|
|
271
278
|
Ask:
|
|
272
279
|
|
|
273
|
-
1.
|
|
274
|
-
2.
|
|
275
|
-
3.
|
|
280
|
+
1. When this feeling is present, what tells you it is this feeling and not a nearby one?
|
|
281
|
+
2. What would you want a later trigger report to mean when it uses this label?
|
|
282
|
+
3. If the felt meaning is clear but the wording is not, would you like me to suggest a concise label or broader category?
|
|
276
283
|
|
|
277
284
|
Use these rules when choosing tools.
|
|
278
285
|
|
|
@@ -296,11 +303,20 @@ Use the dedicated domain routes for specialized surfaces that are not simple bat
|
|
|
296
303
|
|
|
297
304
|
- 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
305
|
- 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.
|
|
306
|
+
- Movement read lanes map cleanly to the dedicated routes:
|
|
307
|
+
`/api/v1/movement/day`, `/api/v1/movement/month`, `/api/v1/movement/all-time`,
|
|
308
|
+
`/api/v1/movement/timeline`, `/api/v1/movement/places`,
|
|
309
|
+
`/api/v1/movement/selection`, and `/api/v1/movement/trips/:id`.
|
|
299
310
|
- 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
311
|
- 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
312
|
- 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
313
|
- 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
314
|
- 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.
|
|
315
|
+
- Workbench lane hints:
|
|
316
|
+
use `/api/v1/workbench/flows` for flow catalog and CRUD,
|
|
317
|
+
`/api/v1/workbench/flows/:id/run` or `/api/v1/workbench/run` for execution,
|
|
318
|
+
`/api/v1/workbench/flows/:id/output` for published outputs, and the run/node routes
|
|
319
|
+
under `/api/v1/workbench/flows/:id` for run history and node-level inspection.
|
|
304
320
|
- If you are unsure which specialized route family applies, check `forge_get_agent_onboarding` and use its `entityRouteModel.specializedDomainSurfaces` section before guessing.
|
|
305
321
|
|
|
306
322
|
Use live work tools for `task_run`:
|
|
@@ -15,6 +15,8 @@ Forge correctly, and gather only the structure that still matters.
|
|
|
15
15
|
naming what you think the user is trying to preserve, clarify, decide, schedule, or
|
|
16
16
|
make easier.
|
|
17
17
|
- Ask only for what is missing or still unclear.
|
|
18
|
+
- First identify the user's job when the lane is not already explicit:
|
|
19
|
+
are they trying to add, update, review, compare, navigate, link, or run something?
|
|
18
20
|
- Before every question, decide the one missing thing you are trying to clarify.
|
|
19
21
|
- Ask first for the missing thing that would change the record shape, title, or next
|
|
20
22
|
action most, not just the easiest field to fill.
|
|
@@ -78,6 +80,21 @@ Most good Forge intake flows follow this sequence:
|
|
|
78
80
|
|
|
79
81
|
That sequence is not a script. Skip steps the user already answered.
|
|
80
82
|
|
|
83
|
+
## Operation lane checkpoint
|
|
84
|
+
|
|
85
|
+
Use this before you choose an API path or ask for more structure.
|
|
86
|
+
|
|
87
|
+
- If the user has not made the operation explicit yet, clarify the job first:
|
|
88
|
+
add, update, review, compare, navigate, link, or run.
|
|
89
|
+
- Ask the lane question only when it changes the route family or the next question.
|
|
90
|
+
- Skip the meta lane question when the user already gave both the entity and the
|
|
91
|
+
action clearly, such as "pause this project", "add a home stay for that missing
|
|
92
|
+
block", or "run this flow again".
|
|
93
|
+
- For simple stored entities, once the lane is clear, fall back to the shared batch
|
|
94
|
+
CRUD flow.
|
|
95
|
+
- For specialized surfaces such as Movement, Life Force, and Workbench, use the lane
|
|
96
|
+
to choose the dedicated route family before you ask for lower-level details.
|
|
97
|
+
|
|
81
98
|
## Active-listening patterns
|
|
82
99
|
|
|
83
100
|
Use one of these shapes when the user is not yet precise.
|
|
@@ -158,6 +175,21 @@ When an adjacent record becomes visible:
|
|
|
158
175
|
- name it gently and ask whether it should be linked now, saved separately later, or
|
|
159
176
|
left alone for now
|
|
160
177
|
|
|
178
|
+
## Review And Navigation Moves
|
|
179
|
+
|
|
180
|
+
Use this when the user wants to inspect, compare, review, or navigate existing Forge
|
|
181
|
+
records rather than create something new.
|
|
182
|
+
|
|
183
|
+
- Start by asking what they are trying to understand, decide, compare, or check.
|
|
184
|
+
- Ask only for the scoping detail that changes the read path most:
|
|
185
|
+
entity, owner, timeframe, context, or comparison target.
|
|
186
|
+
- If the record already exists and the user wants review, do not reopen a creation
|
|
187
|
+
intake. Route to search, list, overview, or detail first.
|
|
188
|
+
- For review-heavy questions, the useful progression is:
|
|
189
|
+
user goal -> scope -> read path -> interpretation -> optional follow-up write.
|
|
190
|
+
- Only drift back into create or update intake if the user actually wants the record
|
|
191
|
+
changed after the review.
|
|
192
|
+
|
|
161
193
|
## Question Calibration Loop
|
|
162
194
|
|
|
163
195
|
Use this quick internal check before every follow-up question.
|
|
@@ -913,6 +945,21 @@ Helpful follow-up lanes:
|
|
|
913
945
|
distribution, versus an edit
|
|
914
946
|
- whether the edit is a missing-gap overlay versus a true recorded stay/trip patch
|
|
915
947
|
|
|
948
|
+
Lane-to-route map:
|
|
949
|
+
|
|
950
|
+
- review one day or month:
|
|
951
|
+
`/api/v1/movement/day` or `/api/v1/movement/month`
|
|
952
|
+
- review long-range behavior or dominant places:
|
|
953
|
+
`/api/v1/movement/all-time`, `/api/v1/movement/places`, or `/api/v1/movement/selection`
|
|
954
|
+
- inspect the full life timeline:
|
|
955
|
+
`/api/v1/movement/timeline`
|
|
956
|
+
- inspect one trip:
|
|
957
|
+
`/api/v1/movement/trips/:id`
|
|
958
|
+
- fill a missing span:
|
|
959
|
+
`/api/v1/movement/user-boxes/preflight` then `/api/v1/movement/user-boxes`
|
|
960
|
+
- edit an already-recorded stay, trip, or trip point:
|
|
961
|
+
`/api/v1/movement/stays/:id`, `/api/v1/movement/trips/:id`, or `/api/v1/movement/trips/:id/points/:pointId`
|
|
962
|
+
|
|
916
963
|
Ready to act when:
|
|
917
964
|
|
|
918
965
|
- the movement surface is clear
|
|
@@ -941,6 +988,17 @@ Helpful follow-up lanes:
|
|
|
941
988
|
- what part of the energy model feels off or useful
|
|
942
989
|
- what durable assumption versus real-time state is being changed
|
|
943
990
|
|
|
991
|
+
Lane-to-route map:
|
|
992
|
+
|
|
993
|
+
- understand the current energy picture:
|
|
994
|
+
`GET /api/v1/life-force`
|
|
995
|
+
- change durable profile assumptions:
|
|
996
|
+
`PATCH /api/v1/life-force/profile`
|
|
997
|
+
- change one weekday curve or template:
|
|
998
|
+
`PUT /api/v1/life-force/templates/:weekday`
|
|
999
|
+
- log a real-time tired or recovered signal:
|
|
1000
|
+
`POST /api/v1/life-force/fatigue-signals`
|
|
1001
|
+
|
|
944
1002
|
Ready to act when:
|
|
945
1003
|
|
|
946
1004
|
- the life-force lane is clear
|
|
@@ -969,6 +1027,27 @@ Helpful follow-up lanes:
|
|
|
969
1027
|
- what exact flow or run is in scope
|
|
970
1028
|
- whether they need whole-flow output or node-level detail
|
|
971
1029
|
|
|
1030
|
+
Lane-to-route map:
|
|
1031
|
+
|
|
1032
|
+
- discover or inspect flows:
|
|
1033
|
+
`/api/v1/workbench/flows`, `/api/v1/workbench/flows/:id`, or `/api/v1/workbench/flows/by-slug/:slug`
|
|
1034
|
+
- create, update, or delete a flow:
|
|
1035
|
+
`POST/PATCH/DELETE /api/v1/workbench/flows`
|
|
1036
|
+
- run a known flow:
|
|
1037
|
+
`/api/v1/workbench/flows/:id/run`
|
|
1038
|
+
- run from a payload-first contract:
|
|
1039
|
+
`/api/v1/workbench/run`
|
|
1040
|
+
- inspect published output or run history:
|
|
1041
|
+
`/api/v1/workbench/flows/:id/output` or `/api/v1/workbench/flows/:id/runs`
|
|
1042
|
+
- inspect one run or node result:
|
|
1043
|
+
`/api/v1/workbench/flows/:id/runs/:runId`,
|
|
1044
|
+
`/api/v1/workbench/flows/:id/runs/:runId/nodes`,
|
|
1045
|
+
`/api/v1/workbench/flows/:id/runs/:runId/nodes/:nodeId`
|
|
1046
|
+
- inspect the latest successful node output:
|
|
1047
|
+
`/api/v1/workbench/flows/:id/nodes/:nodeId/output`
|
|
1048
|
+
- inspect available box inputs:
|
|
1049
|
+
`/api/v1/workbench/catalog/boxes`
|
|
1050
|
+
|
|
972
1051
|
Ready to act when:
|
|
973
1052
|
|
|
974
1053
|
- the workbench lane is clear
|
|
@@ -1145,10 +1224,12 @@ consistent.
|
|
|
1145
1224
|
Arc:
|
|
1146
1225
|
|
|
1147
1226
|
1. Ask what kind of moment or incident this label should capture in lived terms.
|
|
1148
|
-
2.
|
|
1149
|
-
3. Ask
|
|
1227
|
+
2. Reflect the repeated moment back in plain language before narrowing the wording.
|
|
1228
|
+
3. Ask how narrow or broad it should be.
|
|
1229
|
+
4. Ask what would count as inside versus outside the category if that boundary is
|
|
1150
1230
|
still fuzzy.
|
|
1151
|
-
|
|
1231
|
+
5. Offer a concise label if the lived meaning is clearer than the wording.
|
|
1232
|
+
6. Ask for a short description only if the label could be ambiguous later.
|
|
1152
1233
|
|
|
1153
1234
|
If the user already offered a candidate label, keep the wording provisional and ask
|
|
1154
1235
|
what kinds of moments belong inside it before you ask whether the label is right.
|
|
@@ -1169,8 +1250,10 @@ Aim: define one reusable emotion entry clearly enough that future reports stay p
|
|
|
1169
1250
|
Arc:
|
|
1170
1251
|
|
|
1171
1252
|
1. Ask what this feeling is like in lived terms when the user says it.
|
|
1172
|
-
2.
|
|
1173
|
-
3. Ask
|
|
1253
|
+
2. Reflect the felt signature back in plain language before you settle the label.
|
|
1254
|
+
3. Ask what distinguishes it from nearby emotions if that matters.
|
|
1255
|
+
4. Offer a concise label if the felt meaning is clearer than the wording.
|
|
1256
|
+
5. Ask for a short description only if later reports would benefit from it.
|
|
1174
1257
|
|
|
1175
1258
|
Helpful follow-up lanes:
|
|
1176
1259
|
|