forge-openclaw-plugin 0.2.27 → 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 +2 -1
- package/dist/assets/{board-C6jCchjI.js → board-q8cfwaAW.js} +2 -2
- package/dist/assets/{board-C6jCchjI.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-DFHrH2rd.js → motion-DHfqFntt.js} +2 -2
- package/dist/assets/{motion-DFHrH2rd.js.map → motion-DHfqFntt.js.map} +1 -1
- package/dist/assets/{table-ZL7Di_u3.js → table-DLweENXt.js} +2 -2
- package/dist/assets/{table-ZL7Di_u3.js.map → table-DLweENXt.js.map} +1 -1
- package/dist/assets/{ui-CKNPpz7q.js → ui-BV0OYxkH.js} +2 -2
- package/dist/assets/{ui-CKNPpz7q.js.map → ui-BV0OYxkH.js.map} +1 -1
- package/dist/assets/{vendor-DoNZuFhn.js → vendor-OwcH20PM.js} +204 -204
- package/dist/assets/vendor-OwcH20PM.js.map +1 -0
- 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 +331 -14
- package/dist/server/server/src/openapi.js +828 -3
- package/dist/server/server/src/repositories/calendar.js +295 -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/life-force-model.js +20 -0
- package/dist/server/server/src/services/life-force.js +1333 -97
- package/dist/server/server/src/services/macos-calendar-helper.js +748 -0
- package/dist/server/server/src/types.js +67 -3
- 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/dist/server/src/lib/snapshot-normalizer.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 +38 -5
- package/skills/forge-openclaw/entity_conversation_playbooks.md +326 -5
- package/skills/forge-openclaw/psyche_entity_playbooks.md +57 -0
- package/dist/assets/index-DVvS8iiU.css +0 -1
- package/dist/assets/index-zYB-9Dfo.js +0 -85
- package/dist/assets/index-zYB-9Dfo.js.map +0 -1
- package/dist/assets/vendor-DoNZuFhn.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",
|
|
@@ -578,6 +587,7 @@ export const lifeForcePayloadSchema = z.object({
|
|
|
578
587
|
spentTodayAp: z.number(),
|
|
579
588
|
remainingAp: z.number(),
|
|
580
589
|
forecastAp: z.number(),
|
|
590
|
+
plannedRemainingAp: z.number(),
|
|
581
591
|
targetBandMinAp: z.number().min(0),
|
|
582
592
|
targetBandMaxAp: z.number().min(0),
|
|
583
593
|
instantCapacityApPerHour: z.number().min(0),
|
|
@@ -591,6 +601,7 @@ export const lifeForcePayloadSchema = z.object({
|
|
|
591
601
|
stats: z.array(lifeForceStatStateSchema),
|
|
592
602
|
currentCurve: z.array(lifeForceCurvePointSchema),
|
|
593
603
|
activeDrains: z.array(lifeForceDrainEntrySchema),
|
|
604
|
+
plannedDrains: z.array(lifeForceDrainEntrySchema),
|
|
594
605
|
warnings: z.array(lifeForceWarningSchema),
|
|
595
606
|
recommendations: z.array(trimmedString),
|
|
596
607
|
topTaskIdsNeedingSplit: z.array(z.string()),
|
|
@@ -790,7 +801,13 @@ export const calendarDiscoveryCalendarSchema = z.object({
|
|
|
790
801
|
isPrimary: z.boolean(),
|
|
791
802
|
canWrite: z.boolean(),
|
|
792
803
|
selectedByDefault: z.boolean(),
|
|
793
|
-
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)
|
|
794
811
|
});
|
|
795
812
|
export const calendarDiscoveryPayloadSchema = z.object({
|
|
796
813
|
provider: calendarProviderSchema,
|
|
@@ -800,6 +817,19 @@ export const calendarDiscoveryPayloadSchema = z.object({
|
|
|
800
817
|
homeUrl: z.string().nullable(),
|
|
801
818
|
calendars: z.array(calendarDiscoveryCalendarSchema)
|
|
802
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
|
+
});
|
|
803
833
|
export const calendarSchema = z.object({
|
|
804
834
|
id: z.string(),
|
|
805
835
|
connectionId: z.string(),
|
|
@@ -812,6 +842,12 @@ export const calendarSchema = z.object({
|
|
|
812
842
|
canWrite: z.boolean(),
|
|
813
843
|
selectedForSync: z.boolean(),
|
|
814
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),
|
|
815
851
|
lastSyncedAt: z.string().nullable(),
|
|
816
852
|
createdAt: z.string(),
|
|
817
853
|
updatedAt: z.string()
|
|
@@ -887,6 +923,7 @@ export const calendarEventSchema = z.object({
|
|
|
887
923
|
categories: z.array(z.string()).default([]),
|
|
888
924
|
sourceMappings: z.array(calendarEventSourceSchema).default([]),
|
|
889
925
|
links: z.array(calendarEventLinkSchema).default([]),
|
|
926
|
+
actionProfile: actionProfileSchema.nullable().default(null),
|
|
890
927
|
remoteUpdatedAt: z.string().nullable(),
|
|
891
928
|
deletedAt: z.string().nullable(),
|
|
892
929
|
createdAt: z.string(),
|
|
@@ -906,6 +943,7 @@ export const workBlockTemplateSchema = z
|
|
|
906
943
|
startsOn: dateOnlySchema.nullable().default(null),
|
|
907
944
|
endsOn: dateOnlySchema.nullable().default(null),
|
|
908
945
|
blockingState: z.enum(["allowed", "blocked"]),
|
|
946
|
+
actionProfile: actionProfileSchema.nullable().default(null),
|
|
909
947
|
createdAt: z.string(),
|
|
910
948
|
updatedAt: z.string(),
|
|
911
949
|
...ownershipShape
|
|
@@ -937,6 +975,7 @@ export const workBlockInstanceSchema = z.object({
|
|
|
937
975
|
color: z.string(),
|
|
938
976
|
blockingState: z.enum(["allowed", "blocked"]),
|
|
939
977
|
calendarEventId: z.string().nullable(),
|
|
978
|
+
actionProfile: actionProfileSchema.nullable().default(null),
|
|
940
979
|
createdAt: z.string(),
|
|
941
980
|
updatedAt: z.string()
|
|
942
981
|
});
|
|
@@ -954,6 +993,7 @@ export const taskTimeboxSchema = z.object({
|
|
|
954
993
|
startsAt: z.string(),
|
|
955
994
|
endsAt: z.string(),
|
|
956
995
|
overrideReason: trimmedString.nullable(),
|
|
996
|
+
actionProfile: actionProfileSchema.nullable().default(null),
|
|
957
997
|
createdAt: z.string(),
|
|
958
998
|
updatedAt: z.string(),
|
|
959
999
|
...ownershipShape
|
|
@@ -2352,6 +2392,15 @@ export const createCalendarConnectionSchema = z.discriminatedUnion("provider", [
|
|
|
2352
2392
|
label: nonEmptyTrimmedString,
|
|
2353
2393
|
authSessionId: nonEmptyTrimmedString,
|
|
2354
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([])
|
|
2355
2404
|
})
|
|
2356
2405
|
]);
|
|
2357
2406
|
export const discoverCalendarConnectionSchema = z.discriminatedUnion("provider", [
|
|
@@ -2416,7 +2465,11 @@ const workBlockTemplateMutationShape = {
|
|
|
2416
2465
|
userId: nonEmptyTrimmedString.nullable().optional()
|
|
2417
2466
|
};
|
|
2418
2467
|
export const createWorkBlockTemplateSchema = z
|
|
2419
|
-
.object(
|
|
2468
|
+
.object({
|
|
2469
|
+
...workBlockTemplateMutationShape,
|
|
2470
|
+
activityPresetKey: trimmedString.nullable().optional(),
|
|
2471
|
+
customSustainRateApPerHour: z.number().min(0).nullable().optional()
|
|
2472
|
+
})
|
|
2420
2473
|
.superRefine((value, context) => {
|
|
2421
2474
|
if (value.endMinute <= value.startMinute) {
|
|
2422
2475
|
context.addIssue({
|
|
@@ -2448,6 +2501,8 @@ export const updateWorkBlockTemplateSchema = z
|
|
|
2448
2501
|
startsOn: dateOnlySchema.nullable().optional(),
|
|
2449
2502
|
endsOn: dateOnlySchema.nullable().optional(),
|
|
2450
2503
|
blockingState: z.enum(["allowed", "blocked"]).optional(),
|
|
2504
|
+
activityPresetKey: trimmedString.nullable().optional(),
|
|
2505
|
+
customSustainRateApPerHour: z.number().min(0).nullable().optional(),
|
|
2451
2506
|
userId: nonEmptyTrimmedString.nullable().optional()
|
|
2452
2507
|
})
|
|
2453
2508
|
.superRefine((value, context) => {
|
|
@@ -2482,6 +2537,8 @@ export const createTaskTimeboxSchema = z
|
|
|
2482
2537
|
source: calendarTimeboxSourceSchema.default("manual"),
|
|
2483
2538
|
status: calendarTimeboxStatusSchema.default("planned"),
|
|
2484
2539
|
overrideReason: trimmedString.nullable().default(null),
|
|
2540
|
+
activityPresetKey: trimmedString.nullable().optional(),
|
|
2541
|
+
customSustainRateApPerHour: z.number().min(0).nullable().optional(),
|
|
2485
2542
|
userId: nonEmptyTrimmedString.nullable().optional()
|
|
2486
2543
|
})
|
|
2487
2544
|
.superRefine((value, context) => {
|
|
@@ -2499,6 +2556,8 @@ export const updateTaskTimeboxSchema = z.object({
|
|
|
2499
2556
|
endsAt: z.string().datetime().optional(),
|
|
2500
2557
|
status: calendarTimeboxStatusSchema.optional(),
|
|
2501
2558
|
overrideReason: trimmedString.nullable().optional(),
|
|
2559
|
+
activityPresetKey: trimmedString.nullable().optional(),
|
|
2560
|
+
customSustainRateApPerHour: z.number().min(0).nullable().optional(),
|
|
2502
2561
|
userId: nonEmptyTrimmedString.nullable().optional()
|
|
2503
2562
|
});
|
|
2504
2563
|
export const recommendTaskTimeboxesSchema = z.object({
|
|
@@ -2530,6 +2589,8 @@ export const updateCalendarEventSchema = z
|
|
|
2530
2589
|
availability: calendarAvailabilitySchema.optional(),
|
|
2531
2590
|
eventType: trimmedString.optional(),
|
|
2532
2591
|
categories: z.array(trimmedString).optional(),
|
|
2592
|
+
activityPresetKey: trimmedString.nullable().optional(),
|
|
2593
|
+
customSustainRateApPerHour: z.number().min(0).nullable().optional(),
|
|
2533
2594
|
preferredCalendarId: nonEmptyTrimmedString.nullable().optional(),
|
|
2534
2595
|
userId: nonEmptyTrimmedString.nullable().optional(),
|
|
2535
2596
|
links: z
|
|
@@ -2582,6 +2643,8 @@ export const createCalendarEventSchema = z
|
|
|
2582
2643
|
availability: calendarAvailabilitySchema.default("busy"),
|
|
2583
2644
|
eventType: trimmedString.default(""),
|
|
2584
2645
|
categories: z.array(trimmedString).default([]),
|
|
2646
|
+
activityPresetKey: trimmedString.nullable().optional(),
|
|
2647
|
+
customSustainRateApPerHour: z.number().min(0).nullable().optional(),
|
|
2585
2648
|
preferredCalendarId: nonEmptyTrimmedString.nullable().optional(),
|
|
2586
2649
|
userId: nonEmptyTrimmedString.nullable().optional(),
|
|
2587
2650
|
links: z
|
|
@@ -2814,6 +2877,7 @@ export const updateTaskSchema = z.object({
|
|
|
2814
2877
|
title: nonEmptyTrimmedString.optional(),
|
|
2815
2878
|
description: trimmedString.optional(),
|
|
2816
2879
|
status: taskStatusSchema.optional(),
|
|
2880
|
+
completedAt: dateTimeSchema.optional(),
|
|
2817
2881
|
priority: taskPrioritySchema.optional(),
|
|
2818
2882
|
owner: nonEmptyTrimmedString.optional(),
|
|
2819
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",
|
|
@@ -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: [],
|
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) = '';
|
|
@@ -56,9 +56,16 @@ 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.
|
|
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.
|
|
59
63
|
- For emotionally meaningful non-Psyche records such as goals, habits, and notes, reflect the meaning before you ask for structure.
|
|
60
64
|
- When the user is vague, ask for one small concrete example, stake, or desired outcome before you ask them to name the record.
|
|
61
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.
|
|
62
69
|
- When updating an entity, start with what is changing, what should stay true, and what prompted the update now.
|
|
63
70
|
- When enough is clear, briefly summarize what you heard in the user's own language before asking for the last missing structural detail.
|
|
64
71
|
- The quick intake prompts later in this file are fallback checkpoints, not a script to read aloud.
|
|
@@ -260,8 +267,9 @@ Minimum field: `label`
|
|
|
260
267
|
Usually useful: `description`
|
|
261
268
|
Ask:
|
|
262
269
|
|
|
263
|
-
1. What
|
|
264
|
-
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?
|
|
265
273
|
|
|
266
274
|
`emotion_definition`
|
|
267
275
|
Use for a reusable emotion vocabulary entry.
|
|
@@ -269,9 +277,9 @@ Minimum field: `label`
|
|
|
269
277
|
Usually useful: `description`, `category`
|
|
270
278
|
Ask:
|
|
271
279
|
|
|
272
|
-
1.
|
|
273
|
-
2.
|
|
274
|
-
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?
|
|
275
283
|
|
|
276
284
|
Use these rules when choosing tools.
|
|
277
285
|
|
|
@@ -291,9 +299,34 @@ Use the wiki tools for file-first memory work:
|
|
|
291
299
|
Use the health tools for review and reflective enrichment, not as the default CRUD architecture:
|
|
292
300
|
`forge_get_sleep_overview`, `forge_get_sports_overview`, `forge_update_sleep_session`, `forge_update_workout_session`
|
|
293
301
|
|
|
302
|
+
Use the dedicated domain routes for specialized surfaces that are not simple batch entities:
|
|
303
|
+
|
|
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?".
|
|
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`.
|
|
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"`.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
320
|
+
- If you are unsure which specialized route family applies, check `forge_get_agent_onboarding` and use its `entityRouteModel.specializedDomainSurfaces` section before guessing.
|
|
321
|
+
|
|
294
322
|
Use live work tools for `task_run`:
|
|
295
323
|
`forge_log_work`, `forge_start_task_run`, `forge_heartbeat_task_run`, `forge_focus_task_run`, `forge_complete_task_run`, `forge_release_task_run`
|
|
296
324
|
|
|
325
|
+
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.
|
|
326
|
+
|
|
327
|
+
Use the dedicated Preferences action tools for `preference_judgment` and `preference_signal`:
|
|
328
|
+
`forge_submit_preferences_judgment`, `forge_submit_preferences_signal`, `forge_update_preferences_score`
|
|
329
|
+
|
|
297
330
|
Use `forge_post_insight` for `insight`.
|
|
298
331
|
Use the calendar tools for provider sync and planning:
|
|
299
332
|
`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`
|