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.
- package/README.md +1 -0
- package/dist/assets/{board-C6jCchjI.js → board-DPFvZf-D.js} +2 -2
- package/dist/assets/{board-C6jCchjI.js.map → board-DPFvZf-D.js.map} +1 -1
- package/dist/assets/index-Auw3JrdE.css +1 -0
- package/dist/assets/index-D1H7myQH.js +85 -0
- package/dist/assets/index-D1H7myQH.js.map +1 -0
- package/dist/assets/{motion-DFHrH2rd.js → motion-Bvwc85ch.js} +2 -2
- package/dist/assets/{motion-DFHrH2rd.js.map → motion-Bvwc85ch.js.map} +1 -1
- package/dist/assets/{table-ZL7Di_u3.js → table-FJQTJvUR.js} +2 -2
- package/dist/assets/{table-ZL7Di_u3.js.map → table-FJQTJvUR.js.map} +1 -1
- package/dist/assets/{ui-CKNPpz7q.js → ui-GXFcgvSw.js} +2 -2
- package/dist/assets/{ui-CKNPpz7q.js.map → ui-GXFcgvSw.js.map} +1 -1
- package/dist/assets/{vendor-DoNZuFhn.js → vendor-Cwf49UMz.js} +204 -204
- package/dist/assets/vendor-Cwf49UMz.js.map +1 -0
- package/dist/index.html +7 -7
- package/dist/server/server/src/app.js +244 -2
- package/dist/server/server/src/openapi.js +799 -2
- package/dist/server/server/src/repositories/calendar.js +151 -0
- 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/types.js +21 -1
- package/dist/server/src/lib/snapshot-normalizer.js +2 -0
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/skills/forge-openclaw/SKILL.md +17 -0
- package/skills/forge-openclaw/entity_conversation_playbooks.md +238 -0
- 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
|
@@ -4,6 +4,7 @@ import { recordActivityEvent } from "./activity-events.js";
|
|
|
4
4
|
import { decorateOwnedEntity, filterOwnedEntities, inferFirstOwnedUserId, setEntityOwner } from "./entity-ownership.js";
|
|
5
5
|
import { getProjectById } from "./projects.js";
|
|
6
6
|
import { getTaskById } from "./tasks.js";
|
|
7
|
+
import { buildCalendarEventActionProfile, buildTaskTimeboxActionProfile, buildWorkBlockTemplateActionProfile, readEntityActionProfile, upsertEntityActionProfile } from "../services/life-force.js";
|
|
7
8
|
import { calendarConnectionSchema, calendarContextConflictSchema, calendarEventSchema, calendarEventLinkSchema, calendarEventSourceSchema, calendarOverviewPayloadSchema, calendarSchema, calendarSchedulingRulesSchema, taskTimeboxSchema, workBlockInstanceSchema, workBlockTemplateSchema } from "../types.js";
|
|
8
9
|
const DEFAULT_SCHEDULING_RULES = {
|
|
9
10
|
allowWorkBlockKinds: [],
|
|
@@ -149,6 +150,11 @@ function mapEvent(row) {
|
|
|
149
150
|
categories: JSON.parse(row.categories_json || "[]"),
|
|
150
151
|
sourceMappings,
|
|
151
152
|
links: listEventLinksForEvent(row.id),
|
|
153
|
+
actionProfile: readEntityActionProfile("calendar_event", row.id, {
|
|
154
|
+
profileKey: `calendar_event_${row.id}`,
|
|
155
|
+
title: row.title,
|
|
156
|
+
entityType: "calendar_event"
|
|
157
|
+
}),
|
|
152
158
|
remoteUpdatedAt: primarySource?.lastSyncedAt ?? null,
|
|
153
159
|
deletedAt: row.deleted_at,
|
|
154
160
|
createdAt: row.created_at,
|
|
@@ -168,11 +174,17 @@ function mapWorkBlockTemplate(row) {
|
|
|
168
174
|
startsOn: row.starts_on,
|
|
169
175
|
endsOn: row.ends_on,
|
|
170
176
|
blockingState: row.blocking_state,
|
|
177
|
+
actionProfile: readEntityActionProfile("work_block_template", row.id, {
|
|
178
|
+
profileKey: `work_block_template_${row.id}`,
|
|
179
|
+
title: row.title,
|
|
180
|
+
entityType: "work_block_template"
|
|
181
|
+
}),
|
|
171
182
|
createdAt: row.created_at,
|
|
172
183
|
updatedAt: row.updated_at
|
|
173
184
|
});
|
|
174
185
|
}
|
|
175
186
|
function mapTimebox(row) {
|
|
187
|
+
const task = getTaskById(row.task_id);
|
|
176
188
|
return taskTimeboxSchema.parse({
|
|
177
189
|
id: row.id,
|
|
178
190
|
taskId: row.task_id,
|
|
@@ -187,6 +199,21 @@ function mapTimebox(row) {
|
|
|
187
199
|
startsAt: row.starts_at,
|
|
188
200
|
endsAt: row.ends_at,
|
|
189
201
|
overrideReason: row.override_reason,
|
|
202
|
+
actionProfile: readEntityActionProfile("task_timebox", row.id, {
|
|
203
|
+
profileKey: `task_timebox_${row.id}`,
|
|
204
|
+
title: row.title,
|
|
205
|
+
entityType: "task_timebox"
|
|
206
|
+
}) ??
|
|
207
|
+
(task
|
|
208
|
+
? buildTaskTimeboxActionProfile({
|
|
209
|
+
timeboxId: row.id,
|
|
210
|
+
title: row.title,
|
|
211
|
+
taskId: row.task_id,
|
|
212
|
+
taskPlannedDurationSeconds: task.plannedDurationSeconds,
|
|
213
|
+
startsAt: row.starts_at,
|
|
214
|
+
endsAt: row.ends_at
|
|
215
|
+
})
|
|
216
|
+
: null),
|
|
190
217
|
createdAt: row.created_at,
|
|
191
218
|
updatedAt: row.updated_at
|
|
192
219
|
});
|
|
@@ -597,6 +624,20 @@ export function createCalendarEvent(input) {
|
|
|
597
624
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
598
625
|
.run(id, preferredCalendar?.connectionId ?? null, preferredCalendar?.id ?? null, "forge", "native", "confirmed", input.title, input.description, input.location, place.label || input.location, place.address, place.timezone, place.latitude, place.longitude, place.source, place.externalPlaceId, input.startAt, input.endAt, normalizeTimezone(input.timezone), input.isAllDay ? 1 : 0, input.availability, input.eventType, JSON.stringify(input.categories), now, now);
|
|
599
626
|
replaceEventLinks(id, input.links);
|
|
627
|
+
upsertEntityActionProfile({
|
|
628
|
+
entityType: "calendar_event",
|
|
629
|
+
entityId: id,
|
|
630
|
+
profile: buildCalendarEventActionProfile({
|
|
631
|
+
eventId: id,
|
|
632
|
+
title: input.title,
|
|
633
|
+
eventType: input.eventType,
|
|
634
|
+
availability: input.availability,
|
|
635
|
+
startAt: input.startAt,
|
|
636
|
+
endAt: input.endAt,
|
|
637
|
+
activityPresetKey: input.activityPresetKey ?? null,
|
|
638
|
+
customSustainRateApPerHour: input.customSustainRateApPerHour ?? null
|
|
639
|
+
})
|
|
640
|
+
});
|
|
600
641
|
setEntityOwner("calendar_event", id, inferCalendarEventOwnerId(input));
|
|
601
642
|
return getCalendarEventById(id);
|
|
602
643
|
}
|
|
@@ -652,6 +693,34 @@ export function updateCalendarEvent(eventId, patch) {
|
|
|
652
693
|
if (patch.links) {
|
|
653
694
|
replaceEventLinks(eventId, patch.links);
|
|
654
695
|
}
|
|
696
|
+
if (patch.title !== undefined ||
|
|
697
|
+
patch.startAt !== undefined ||
|
|
698
|
+
patch.endAt !== undefined ||
|
|
699
|
+
patch.availability !== undefined ||
|
|
700
|
+
patch.eventType !== undefined ||
|
|
701
|
+
patch.activityPresetKey !== undefined ||
|
|
702
|
+
patch.customSustainRateApPerHour !== undefined) {
|
|
703
|
+
upsertEntityActionProfile({
|
|
704
|
+
entityType: "calendar_event",
|
|
705
|
+
entityId: eventId,
|
|
706
|
+
profile: buildCalendarEventActionProfile({
|
|
707
|
+
eventId,
|
|
708
|
+
title: next.title,
|
|
709
|
+
eventType: next.eventType,
|
|
710
|
+
availability: next.availability,
|
|
711
|
+
startAt: next.startAt,
|
|
712
|
+
endAt: next.endAt,
|
|
713
|
+
activityPresetKey: patch.activityPresetKey === undefined
|
|
714
|
+
? current.actionProfile?.metadata?.activityPresetKey
|
|
715
|
+
: patch.activityPresetKey,
|
|
716
|
+
customSustainRateApPerHour: patch.customSustainRateApPerHour === undefined
|
|
717
|
+
? (typeof current.actionProfile?.metadata?.customSustainRateApPerHour === "number"
|
|
718
|
+
? current.actionProfile.metadata.customSustainRateApPerHour
|
|
719
|
+
: null)
|
|
720
|
+
: patch.customSustainRateApPerHour
|
|
721
|
+
})
|
|
722
|
+
});
|
|
723
|
+
}
|
|
655
724
|
if (patch.userId !== undefined || patch.links !== undefined) {
|
|
656
725
|
setEntityOwner("calendar_event", eventId, patch.userId === undefined
|
|
657
726
|
? inferCalendarEventOwnerId({
|
|
@@ -699,6 +768,19 @@ export function createWorkBlockTemplate(input) {
|
|
|
699
768
|
)
|
|
700
769
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
701
770
|
.run(id, input.title, input.kind, input.color, normalizeTimezone(input.timezone), JSON.stringify(input.weekDays), input.startMinute, input.endMinute, input.startsOn ?? null, input.endsOn ?? null, input.blockingState, now, now);
|
|
771
|
+
upsertEntityActionProfile({
|
|
772
|
+
entityType: "work_block_template",
|
|
773
|
+
entityId: id,
|
|
774
|
+
profile: buildWorkBlockTemplateActionProfile({
|
|
775
|
+
templateId: id,
|
|
776
|
+
title: input.title,
|
|
777
|
+
kind: input.kind,
|
|
778
|
+
startMinute: input.startMinute,
|
|
779
|
+
endMinute: input.endMinute,
|
|
780
|
+
activityPresetKey: input.activityPresetKey ?? null,
|
|
781
|
+
customSustainRateApPerHour: input.customSustainRateApPerHour ?? null
|
|
782
|
+
})
|
|
783
|
+
});
|
|
702
784
|
setEntityOwner("work_block_template", id, input.userId);
|
|
703
785
|
return getWorkBlockTemplateById(id);
|
|
704
786
|
});
|
|
@@ -744,6 +826,32 @@ export function updateWorkBlockTemplate(templateId, patch) {
|
|
|
744
826
|
SET title = ?, kind = ?, color = ?, timezone = ?, weekdays_json = ?, start_minute = ?, end_minute = ?, starts_on = ?, ends_on = ?, blocking_state = ?, updated_at = ?
|
|
745
827
|
WHERE id = ?`)
|
|
746
828
|
.run(next.title, next.kind, next.color, next.timezone, JSON.stringify(next.weekDays), next.startMinute, next.endMinute, next.startsOn, next.endsOn, next.blockingState, next.updatedAt, templateId);
|
|
829
|
+
if (patch.title !== undefined ||
|
|
830
|
+
patch.kind !== undefined ||
|
|
831
|
+
patch.startMinute !== undefined ||
|
|
832
|
+
patch.endMinute !== undefined ||
|
|
833
|
+
patch.activityPresetKey !== undefined ||
|
|
834
|
+
patch.customSustainRateApPerHour !== undefined) {
|
|
835
|
+
upsertEntityActionProfile({
|
|
836
|
+
entityType: "work_block_template",
|
|
837
|
+
entityId: templateId,
|
|
838
|
+
profile: buildWorkBlockTemplateActionProfile({
|
|
839
|
+
templateId,
|
|
840
|
+
title: next.title,
|
|
841
|
+
kind: next.kind,
|
|
842
|
+
startMinute: next.startMinute,
|
|
843
|
+
endMinute: next.endMinute,
|
|
844
|
+
activityPresetKey: patch.activityPresetKey === undefined
|
|
845
|
+
? current.actionProfile?.metadata?.activityPresetKey
|
|
846
|
+
: patch.activityPresetKey,
|
|
847
|
+
customSustainRateApPerHour: patch.customSustainRateApPerHour === undefined
|
|
848
|
+
? (typeof current.actionProfile?.metadata?.customSustainRateApPerHour === "number"
|
|
849
|
+
? current.actionProfile.metadata.customSustainRateApPerHour
|
|
850
|
+
: null)
|
|
851
|
+
: patch.customSustainRateApPerHour
|
|
852
|
+
})
|
|
853
|
+
});
|
|
854
|
+
}
|
|
747
855
|
if (patch.userId !== undefined) {
|
|
748
856
|
setEntityOwner("work_block_template", templateId, patch.userId);
|
|
749
857
|
}
|
|
@@ -790,6 +898,7 @@ function deriveWorkBlockInstances(template, query) {
|
|
|
790
898
|
color: template.color,
|
|
791
899
|
blockingState: template.blockingState,
|
|
792
900
|
calendarEventId: null,
|
|
901
|
+
actionProfile: template.actionProfile ?? null,
|
|
793
902
|
createdAt: template.createdAt,
|
|
794
903
|
updatedAt: template.updatedAt
|
|
795
904
|
}));
|
|
@@ -836,12 +945,27 @@ export function getTaskTimeboxById(timeboxId) {
|
|
|
836
945
|
export function createTaskTimebox(input) {
|
|
837
946
|
const now = nowIso();
|
|
838
947
|
const id = `timebox_${randomUUID().replaceAll("-", "").slice(0, 10)}`;
|
|
948
|
+
const task = getTaskById(input.taskId);
|
|
839
949
|
getDatabase()
|
|
840
950
|
.prepare(`INSERT INTO task_timeboxes (
|
|
841
951
|
id, task_id, project_id, connection_id, calendar_id, linked_task_run_id, status, source, title, starts_at, ends_at, override_reason, created_at, updated_at
|
|
842
952
|
)
|
|
843
953
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
844
954
|
.run(id, input.taskId, input.projectId ?? null, input.connectionId ?? null, input.calendarId ?? null, input.linkedTaskRunId ?? null, input.status ?? "planned", input.source ?? "manual", input.title, input.startsAt, input.endsAt, input.overrideReason ?? null, now, now);
|
|
955
|
+
upsertEntityActionProfile({
|
|
956
|
+
entityType: "task_timebox",
|
|
957
|
+
entityId: id,
|
|
958
|
+
profile: buildTaskTimeboxActionProfile({
|
|
959
|
+
timeboxId: id,
|
|
960
|
+
title: input.title,
|
|
961
|
+
taskId: input.taskId,
|
|
962
|
+
taskPlannedDurationSeconds: task?.plannedDurationSeconds ?? null,
|
|
963
|
+
startsAt: input.startsAt,
|
|
964
|
+
endsAt: input.endsAt,
|
|
965
|
+
activityPresetKey: input.activityPresetKey ?? null,
|
|
966
|
+
customSustainRateApPerHour: input.customSustainRateApPerHour ?? null
|
|
967
|
+
})
|
|
968
|
+
});
|
|
845
969
|
setEntityOwner("task_timebox", id, inferTaskTimeboxOwnerId(input));
|
|
846
970
|
return getTaskTimeboxById(id);
|
|
847
971
|
}
|
|
@@ -869,6 +993,33 @@ export function updateTaskTimebox(timeboxId, patch) {
|
|
|
869
993
|
starts_at = ?, ends_at = ?, override_reason = ?, updated_at = ?
|
|
870
994
|
WHERE id = ?`)
|
|
871
995
|
.run(next.connectionId, next.calendarId, next.remoteEventId, next.linkedTaskRunId, next.status, next.source, next.title, next.startsAt, next.endsAt, next.overrideReason, next.updatedAt, timeboxId);
|
|
996
|
+
if (patch.title !== undefined ||
|
|
997
|
+
patch.startsAt !== undefined ||
|
|
998
|
+
patch.endsAt !== undefined ||
|
|
999
|
+
patch.activityPresetKey !== undefined ||
|
|
1000
|
+
patch.customSustainRateApPerHour !== undefined) {
|
|
1001
|
+
const task = getTaskById(current.taskId);
|
|
1002
|
+
upsertEntityActionProfile({
|
|
1003
|
+
entityType: "task_timebox",
|
|
1004
|
+
entityId: timeboxId,
|
|
1005
|
+
profile: buildTaskTimeboxActionProfile({
|
|
1006
|
+
timeboxId,
|
|
1007
|
+
title: next.title,
|
|
1008
|
+
taskId: current.taskId,
|
|
1009
|
+
taskPlannedDurationSeconds: task?.plannedDurationSeconds ?? null,
|
|
1010
|
+
startsAt: next.startsAt,
|
|
1011
|
+
endsAt: next.endsAt,
|
|
1012
|
+
activityPresetKey: patch.activityPresetKey === undefined
|
|
1013
|
+
? current.actionProfile?.metadata?.activityPresetKey
|
|
1014
|
+
: patch.activityPresetKey,
|
|
1015
|
+
customSustainRateApPerHour: patch.customSustainRateApPerHour === undefined
|
|
1016
|
+
? (typeof current.actionProfile?.metadata?.customSustainRateApPerHour === "number"
|
|
1017
|
+
? current.actionProfile.metadata.customSustainRateApPerHour
|
|
1018
|
+
: null)
|
|
1019
|
+
: patch.customSustainRateApPerHour
|
|
1020
|
+
})
|
|
1021
|
+
});
|
|
1022
|
+
}
|
|
872
1023
|
if (patch.userId !== undefined) {
|
|
873
1024
|
setEntityOwner("task_timebox", timeboxId, patch.userId);
|
|
874
1025
|
}
|
|
@@ -3,6 +3,13 @@ export const DEFAULT_TASK_TOTAL_AP = 100;
|
|
|
3
3
|
export const DEFAULT_TASK_EXPECTED_DURATION_SECONDS = 24 * 60 * 60;
|
|
4
4
|
export const TASK_SPLIT_THRESHOLD_SECONDS = 2 * DEFAULT_TASK_EXPECTED_DURATION_SECONDS;
|
|
5
5
|
export const MIN_LIFE_FORCE_POINT_GAP_MINUTES = 20;
|
|
6
|
+
const COST_RELEVANT_STAT_KEYS = [
|
|
7
|
+
"activation",
|
|
8
|
+
"focus",
|
|
9
|
+
"vigor",
|
|
10
|
+
"composure",
|
|
11
|
+
"flow"
|
|
12
|
+
];
|
|
6
13
|
export function clamp(value, min, max) {
|
|
7
14
|
return Math.min(max, Math.max(min, value));
|
|
8
15
|
}
|
|
@@ -114,6 +121,19 @@ export function buildTaskSplitSuggestion(input) {
|
|
|
114
121
|
thresholdSeconds
|
|
115
122
|
};
|
|
116
123
|
}
|
|
124
|
+
export function computeLifeForceLevelMultiplier(level) {
|
|
125
|
+
return 1 + Math.max(0, level - 1) * 0.03;
|
|
126
|
+
}
|
|
127
|
+
export function computeStatCostModifier(level) {
|
|
128
|
+
return clamp(1 - Math.max(0, level - 1) * 0.02, 0.55, 1.25);
|
|
129
|
+
}
|
|
130
|
+
export function computeActionCostModifier(weights, levels) {
|
|
131
|
+
const relief = COST_RELEVANT_STAT_KEYS.reduce((sum, key) => {
|
|
132
|
+
const level = Math.max(1, levels[key] ?? 1);
|
|
133
|
+
return sum + weights[key] * Math.max(0, level - 1) * 0.02;
|
|
134
|
+
}, 0);
|
|
135
|
+
return clamp(Number((1 - relief).toFixed(4)), 0.55, 1.25);
|
|
136
|
+
}
|
|
117
137
|
export function computeCurveArea(points) {
|
|
118
138
|
if (points.length < 2) {
|
|
119
139
|
return 0;
|