forge-openclaw-plugin 0.2.26 → 0.2.27
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 +59 -3
- package/dist/assets/{board-ta0rUHOf.js → board-C6jCchjI.js} +2 -2
- package/dist/assets/{board-ta0rUHOf.js.map → board-C6jCchjI.js.map} +1 -1
- package/dist/assets/index-DVvS8iiU.css +1 -0
- package/dist/assets/index-zYB-9Dfo.js +85 -0
- package/dist/assets/index-zYB-9Dfo.js.map +1 -0
- package/dist/assets/knowledge-graph-layout.worker-DRvzPxhP.js +2 -0
- package/dist/assets/knowledge-graph-layout.worker-DRvzPxhP.js.map +1 -0
- package/dist/assets/{motion-fBKPB6yw.js → motion-DFHrH2rd.js} +2 -2
- package/dist/assets/{motion-fBKPB6yw.js.map → motion-DFHrH2rd.js.map} +1 -1
- package/dist/assets/{table-C-IGTQni.js → table-ZL7Di_u3.js} +2 -2
- package/dist/assets/{table-C-IGTQni.js.map → table-ZL7Di_u3.js.map} +1 -1
- package/dist/assets/{ui-DInOpaYF.js → ui-CKNPpz7q.js} +2 -2
- package/dist/assets/{ui-DInOpaYF.js.map → ui-CKNPpz7q.js.map} +1 -1
- package/dist/assets/vendor-DoNZuFhn.js +1247 -0
- package/dist/assets/vendor-DoNZuFhn.js.map +1 -0
- package/dist/index.html +7 -7
- package/dist/openclaw/local-runtime.js +16 -0
- package/dist/openclaw/routes.d.ts +27 -0
- package/dist/openclaw/routes.js +16 -12
- package/dist/server/server/migrations/037_workbench_public_inputs_and_run_inputs.sql +5 -0
- package/dist/server/server/migrations/038_data_management_settings.sql +11 -0
- package/dist/server/server/migrations/039_life_force_and_action_points.sql +114 -0
- package/dist/server/server/migrations/040_screen_time_domain.sql +89 -0
- package/dist/server/server/migrations/041_companion_source_states.sql +21 -0
- package/dist/server/server/migrations/042_movement_boxes.sql +47 -0
- package/dist/server/server/migrations/043_movement_box_overlap_overrides.sql +26 -0
- package/dist/server/server/src/app.js +1684 -117
- package/dist/server/server/src/connectors/box-registry.js +44 -9
- package/dist/server/server/src/data-management-types.js +107 -0
- package/dist/server/server/src/db.js +68 -4
- package/dist/server/server/src/demo-data.js +2 -2
- package/dist/server/server/src/health.js +702 -18
- package/dist/server/server/src/managers/platform/llm-manager.js +7 -4
- package/dist/server/server/src/managers/platform/mock-workbench-provider.js +149 -0
- package/dist/server/server/src/managers/platform/secrets-manager.js +18 -1
- package/dist/server/server/src/managers/runtime.js +9 -0
- package/dist/server/server/src/movement.js +1971 -112
- package/dist/server/server/src/openapi.js +489 -1
- package/dist/server/server/src/psyche-types.js +9 -1
- package/dist/server/server/src/repositories/activity-events.js +8 -0
- package/dist/server/server/src/repositories/ai-connectors.js +522 -74
- package/dist/server/server/src/repositories/habits.js +37 -1
- package/dist/server/server/src/repositories/model-settings.js +13 -3
- package/dist/server/server/src/repositories/notes.js +3 -0
- package/dist/server/server/src/repositories/settings.js +380 -18
- package/dist/server/server/src/repositories/tasks.js +170 -10
- package/dist/server/server/src/runtime-data-root.js +82 -0
- package/dist/server/server/src/screen-time.js +802 -0
- package/dist/server/server/src/services/data-management.js +788 -0
- package/dist/server/server/src/services/entity-crud.js +205 -2
- package/dist/server/server/src/services/knowledge-graph.js +1455 -0
- package/dist/server/server/src/services/life-force-model.js +197 -0
- package/dist/server/server/src/services/life-force.js +1270 -0
- package/dist/server/server/src/services/psyche-observation-calendar.js +383 -16
- package/dist/server/server/src/types.js +286 -13
- package/dist/server/server/src/web.js +228 -13
- package/dist/server/src/components/customization/utility-widgets.js +136 -27
- package/dist/server/src/components/ui/info-tooltip.js +25 -0
- package/dist/server/src/components/workbench-boxes/calendar/calendar-boxes.js +78 -0
- package/dist/server/src/components/workbench-boxes/goals/goals-boxes.js +62 -0
- package/dist/server/src/components/workbench-boxes/habits/habits-boxes.js +62 -0
- package/dist/server/src/components/workbench-boxes/health/health-boxes.js +63 -8
- package/dist/server/src/components/workbench-boxes/insights/insights-boxes.js +50 -0
- package/dist/server/src/components/workbench-boxes/kanban/kanban-boxes.js +62 -54
- package/dist/server/src/components/workbench-boxes/movement/movement-boxes.js +18 -8
- package/dist/server/src/components/workbench-boxes/notes/notes-boxes.js +56 -38
- package/dist/server/src/components/workbench-boxes/overview/overview-boxes.js +65 -0
- package/dist/server/src/components/workbench-boxes/preferences/preferences-boxes.js +78 -0
- package/dist/server/src/components/workbench-boxes/projects/projects-boxes.js +35 -30
- package/dist/server/src/components/workbench-boxes/psyche/psyche-boxes.js +88 -0
- package/dist/server/src/components/workbench-boxes/questionnaires/questionnaires-boxes.js +61 -0
- package/dist/server/src/components/workbench-boxes/review/review-boxes.js +53 -0
- package/dist/server/src/components/workbench-boxes/shared/define-workbench-box.js +3 -1
- package/dist/server/src/components/workbench-boxes/shared/generic-node-view.js +39 -3
- package/dist/server/src/components/workbench-boxes/strategies/strategies-boxes.js +62 -0
- package/dist/server/src/components/workbench-boxes/tasks/tasks-boxes.js +76 -0
- package/dist/server/src/components/workbench-boxes/today/today-boxes.js +47 -32
- package/dist/server/src/components/workbench-boxes/wiki/wiki-boxes.js +60 -0
- package/dist/server/src/lib/api.js +280 -21
- package/dist/server/src/lib/data-management-types.js +1 -0
- package/dist/server/src/lib/entity-visuals.js +279 -0
- package/dist/server/src/lib/knowledge-graph-types.js +276 -0
- package/dist/server/src/lib/knowledge-graph.js +470 -0
- package/dist/server/src/lib/schemas.js +4 -0
- package/dist/server/src/lib/snapshot-normalizer.js +43 -1
- package/dist/server/src/lib/workbench/contracts.js +229 -0
- package/dist/server/src/lib/workbench/nodes.js +200 -0
- package/dist/server/src/lib/workbench/registry.js +52 -5
- package/dist/server/src/lib/workbench/runtime.js +254 -38
- package/dist/server/src/lib/workbench/tool-catalog.js +68 -0
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/server/migrations/037_workbench_public_inputs_and_run_inputs.sql +5 -0
- package/server/migrations/038_data_management_settings.sql +11 -0
- package/server/migrations/039_life_force_and_action_points.sql +114 -0
- package/server/migrations/040_screen_time_domain.sql +89 -0
- package/server/migrations/041_companion_source_states.sql +21 -0
- package/server/migrations/042_movement_boxes.sql +47 -0
- package/server/migrations/043_movement_box_overlap_overrides.sql +26 -0
- package/skills/forge-openclaw/SKILL.md +24 -11
- package/skills/forge-openclaw/entity_conversation_playbooks.md +210 -34
- package/skills/forge-openclaw/psyche_entity_playbooks.md +113 -17
- package/dist/assets/index-Ro0ZF_az.css +0 -1
- package/dist/assets/index-ytlpSj23.js +0 -79
- package/dist/assets/index-ytlpSj23.js.map +0 -1
- package/dist/assets/vendor-lE3tZJcC.js +0 -876
- package/dist/assets/vendor-lE3tZJcC.js.map +0 -1
|
@@ -3,48 +3,109 @@ function asRecord(value) {
|
|
|
3
3
|
? value
|
|
4
4
|
: null;
|
|
5
5
|
}
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
json
|
|
6
|
+
function readTextValue(...values) {
|
|
7
|
+
for (const value of values) {
|
|
8
|
+
if (typeof value === "string") {
|
|
9
|
+
return value;
|
|
11
10
|
}
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
11
|
+
}
|
|
12
|
+
return "";
|
|
13
|
+
}
|
|
14
|
+
function readNumberValue(...values) {
|
|
15
|
+
for (const value of values) {
|
|
16
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
17
|
+
return value;
|
|
18
|
+
}
|
|
19
|
+
if (typeof value === "string") {
|
|
20
|
+
const parsed = Number(value);
|
|
21
|
+
if (Number.isFinite(parsed)) {
|
|
22
|
+
return parsed;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
function readStringArrayValue(...values) {
|
|
29
|
+
for (const value of values) {
|
|
30
|
+
if (Array.isArray(value)) {
|
|
31
|
+
const normalized = value.filter((entry) => typeof entry === "string" && entry.trim().length > 0);
|
|
32
|
+
if (normalized.length > 0) {
|
|
33
|
+
return normalized;
|
|
34
|
+
}
|
|
19
35
|
continue;
|
|
20
36
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
37
|
+
if (typeof value === "string") {
|
|
38
|
+
const trimmed = value.trim();
|
|
39
|
+
if (!trimmed) {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
const parsed = JSON.parse(trimmed);
|
|
44
|
+
if (Array.isArray(parsed)) {
|
|
45
|
+
const normalized = parsed.filter((entry) => typeof entry === "string" && entry.trim().length > 0);
|
|
46
|
+
if (normalized.length > 0) {
|
|
47
|
+
return normalized;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
const normalized = trimmed
|
|
53
|
+
.split(",")
|
|
54
|
+
.map((entry) => entry.trim())
|
|
55
|
+
.filter((entry) => entry.length > 0);
|
|
56
|
+
if (normalized.length > 0) {
|
|
57
|
+
return normalized;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
30
61
|
}
|
|
62
|
+
return [];
|
|
63
|
+
}
|
|
64
|
+
export function buildWorkbenchOutputMap(text, json, outputs) {
|
|
65
|
+
const outputMap = {};
|
|
66
|
+
const declaredOutputs = outputs.length > 0 ? outputs : [{ key: "summary" }];
|
|
67
|
+
declaredOutputs.forEach((output, index) => {
|
|
68
|
+
const rawValue = json && output.key in json
|
|
69
|
+
? json[output.key]
|
|
70
|
+
: index === 0 || output.key === "summary"
|
|
71
|
+
? text
|
|
72
|
+
: null;
|
|
73
|
+
outputMap[output.key] = {
|
|
74
|
+
text: typeof rawValue === "string"
|
|
75
|
+
? rawValue
|
|
76
|
+
: Array.isArray(rawValue) || asRecord(rawValue)
|
|
77
|
+
? JSON.stringify(rawValue, null, 2)
|
|
78
|
+
: String(rawValue ?? ""),
|
|
79
|
+
json: asRecord(rawValue)
|
|
80
|
+
};
|
|
81
|
+
});
|
|
31
82
|
return outputMap;
|
|
32
83
|
}
|
|
84
|
+
function normalizeWorkbenchOutputPayload(definition, output, primaryText) {
|
|
85
|
+
const declaredOutputs = definition.output ?? [];
|
|
86
|
+
if (!output && declaredOutputs.length === 0) {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
const normalized = output ? { ...output } : {};
|
|
90
|
+
if (declaredOutputs.length > 0) {
|
|
91
|
+
const leadKey = declaredOutputs[0]?.key;
|
|
92
|
+
if (leadKey && !(leadKey in normalized)) {
|
|
93
|
+
normalized[leadKey] = primaryText;
|
|
94
|
+
}
|
|
95
|
+
if (declaredOutputs.some((entry) => entry.key === "summary") &&
|
|
96
|
+
!("summary" in normalized)) {
|
|
97
|
+
normalized.summary = primaryText;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return normalized;
|
|
101
|
+
}
|
|
33
102
|
export function buildWorkbenchExecutionEnvelope(input, value) {
|
|
34
|
-
const payload =
|
|
35
|
-
nodeId: input.nodeId,
|
|
36
|
-
nodeType: input.definition.id,
|
|
37
|
-
title: input.definition.title,
|
|
38
|
-
inputs: input.inputs,
|
|
39
|
-
params: input.params,
|
|
40
|
-
output: value.output,
|
|
41
|
-
logs: value.logs ?? []
|
|
42
|
-
};
|
|
103
|
+
const payload = normalizeWorkbenchOutputPayload(input.definition, value.output, value.primaryText);
|
|
43
104
|
return {
|
|
44
105
|
primaryText: value.primaryText,
|
|
45
106
|
payload,
|
|
46
107
|
logs: value.logs ?? [],
|
|
47
|
-
outputMap: buildWorkbenchOutputMap(value.primaryText, payload,
|
|
108
|
+
outputMap: buildWorkbenchOutputMap(value.primaryText, payload, input.definition.output)
|
|
48
109
|
};
|
|
49
110
|
}
|
|
50
111
|
export function buildStaticWorkbenchExecution(input, output, primaryText, logs) {
|
|
@@ -86,17 +147,25 @@ export function searchWorkbenchEntities(context, definition, input) {
|
|
|
86
147
|
summaryText: summaryLines.length > 0
|
|
87
148
|
? summaryLines.join("\n")
|
|
88
149
|
: `No ${definition.title.toLowerCase()} matches found.`,
|
|
89
|
-
limit
|
|
150
|
+
limit,
|
|
151
|
+
query: input.query
|
|
90
152
|
};
|
|
91
153
|
}
|
|
92
154
|
export function buildSearchWorkbenchExecution(input, config) {
|
|
93
|
-
const
|
|
155
|
+
const query = readTextValue(input.inputs.query, input.params.query, config.query).trim();
|
|
156
|
+
const entityTypes = readStringArrayValue(input.inputs.entityTypes, input.params.entityTypes, config.entityTypes);
|
|
157
|
+
const limit = readNumberValue(input.inputs.limit, input.params.limit, config.limit) ?? config.limit ?? 12;
|
|
158
|
+
const summary = searchWorkbenchEntities(input.context, input.definition, {
|
|
159
|
+
query,
|
|
160
|
+
entityTypes,
|
|
161
|
+
limit
|
|
162
|
+
});
|
|
94
163
|
return buildWorkbenchExecutionEnvelope(input, {
|
|
95
164
|
primaryText: summary.summaryText,
|
|
96
165
|
output: {
|
|
166
|
+
summary: summary.summaryText,
|
|
97
167
|
matches: summary.matches,
|
|
98
|
-
|
|
99
|
-
entityTypes: config.entityTypes
|
|
168
|
+
matchCount: summary.matches.length
|
|
100
169
|
}
|
|
101
170
|
});
|
|
102
171
|
}
|
|
@@ -116,6 +185,9 @@ export function buildMovementPlacesExecution(input) {
|
|
|
116
185
|
.join("\n")
|
|
117
186
|
: "No known places are stored yet.",
|
|
118
187
|
output: {
|
|
188
|
+
summary: places.length > 0
|
|
189
|
+
? `${places.length} place${places.length === 1 ? "" : "s"} available.`
|
|
190
|
+
: "No known places are stored yet.",
|
|
119
191
|
places
|
|
120
192
|
}
|
|
121
193
|
});
|
|
@@ -126,7 +198,14 @@ export function buildSleepWorkbenchExecution(input) {
|
|
|
126
198
|
primaryText: payload && typeof payload === "object"
|
|
127
199
|
? "Sleep history and derived patterns are available."
|
|
128
200
|
: "No sleep data is available.",
|
|
129
|
-
output:
|
|
201
|
+
output: payload && typeof payload === "object"
|
|
202
|
+
? {
|
|
203
|
+
summary: "Sleep history and derived patterns are available.",
|
|
204
|
+
sleepView: payload
|
|
205
|
+
}
|
|
206
|
+
: {
|
|
207
|
+
summary: "No sleep data is available."
|
|
208
|
+
}
|
|
130
209
|
});
|
|
131
210
|
}
|
|
132
211
|
export function buildSportsWorkbenchExecution(input) {
|
|
@@ -135,11 +214,146 @@ export function buildSportsWorkbenchExecution(input) {
|
|
|
135
214
|
primaryText: payload && typeof payload === "object"
|
|
136
215
|
? "Workout history and composition are available."
|
|
137
216
|
: "No sports data is available.",
|
|
138
|
-
output:
|
|
217
|
+
output: payload && typeof payload === "object"
|
|
218
|
+
? {
|
|
219
|
+
summary: "Workout history and composition are available.",
|
|
220
|
+
sportsView: payload
|
|
221
|
+
}
|
|
222
|
+
: {
|
|
223
|
+
summary: "No sports data is available."
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
export function buildOverviewWorkbenchExecution(input) {
|
|
228
|
+
const payload = input.context.services.overview.getContext?.() ?? null;
|
|
229
|
+
const record = asRecord(payload);
|
|
230
|
+
const summary = record
|
|
231
|
+
? [
|
|
232
|
+
`Projects: ${Array.isArray(record.projects) ? record.projects.length : 0}`,
|
|
233
|
+
`Goals: ${Array.isArray(record.activeGoals) ? record.activeGoals.length : 0}`,
|
|
234
|
+
`Top tasks: ${Array.isArray(record.topTasks) ? record.topTasks.length : 0}`,
|
|
235
|
+
`Due habits: ${Array.isArray(record.dueHabits) ? record.dueHabits.length : 0}`
|
|
236
|
+
].join("\n")
|
|
237
|
+
: "No overview context is available.";
|
|
238
|
+
return buildWorkbenchExecutionEnvelope(input, {
|
|
239
|
+
primaryText: summary,
|
|
240
|
+
output: record
|
|
241
|
+
? {
|
|
242
|
+
summary,
|
|
243
|
+
context: record
|
|
244
|
+
}
|
|
245
|
+
: {
|
|
246
|
+
summary
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
export function buildInsightsWorkbenchExecution(input) {
|
|
251
|
+
const payload = input.context.services.overview.getInsights?.() ?? null;
|
|
252
|
+
const record = asRecord(payload);
|
|
253
|
+
const status = asRecord(record?.status);
|
|
254
|
+
const coaching = asRecord(record?.coaching);
|
|
255
|
+
const summary = record
|
|
256
|
+
? [
|
|
257
|
+
typeof status?.systemStatus === "string" ? status.systemStatus : "Insights ready",
|
|
258
|
+
typeof coaching?.title === "string" ? coaching.title : null,
|
|
259
|
+
typeof coaching?.summary === "string" ? coaching.summary : null
|
|
260
|
+
]
|
|
261
|
+
.filter(Boolean)
|
|
262
|
+
.join("\n")
|
|
263
|
+
: "No insights payload is available.";
|
|
264
|
+
return buildWorkbenchExecutionEnvelope(input, {
|
|
265
|
+
primaryText: summary,
|
|
266
|
+
output: record
|
|
267
|
+
? {
|
|
268
|
+
summary,
|
|
269
|
+
insights: record
|
|
270
|
+
}
|
|
271
|
+
: {
|
|
272
|
+
summary
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
export function buildWeeklyReviewWorkbenchExecution(input) {
|
|
277
|
+
const payload = input.context.services.overview.getWeeklyReview?.() ?? null;
|
|
278
|
+
const record = asRecord(payload);
|
|
279
|
+
const momentum = asRecord(record?.momentumSummary);
|
|
280
|
+
const summary = record
|
|
281
|
+
? [
|
|
282
|
+
typeof record.windowLabel === "string" ? record.windowLabel : "Weekly review",
|
|
283
|
+
typeof momentum?.totalXp === "number" ? `${momentum.totalXp} XP` : null,
|
|
284
|
+
typeof momentum?.focusHours === "number"
|
|
285
|
+
? `${momentum.focusHours} focus hours`
|
|
286
|
+
: null
|
|
287
|
+
]
|
|
288
|
+
.filter(Boolean)
|
|
289
|
+
.join("\n")
|
|
290
|
+
: "No weekly review payload is available.";
|
|
291
|
+
return buildWorkbenchExecutionEnvelope(input, {
|
|
292
|
+
primaryText: summary,
|
|
293
|
+
output: record
|
|
294
|
+
? {
|
|
295
|
+
summary,
|
|
296
|
+
weeklyReview: record
|
|
297
|
+
}
|
|
298
|
+
: {
|
|
299
|
+
summary
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
export function buildWikiPagesWorkbenchExecution(input) {
|
|
304
|
+
const pages = input.context.services.wiki.listPages?.() ?? [];
|
|
305
|
+
const summary = pages.length > 0
|
|
306
|
+
? pages
|
|
307
|
+
.slice(0, 12)
|
|
308
|
+
.map((page) => typeof page.title === "string"
|
|
309
|
+
? page.title
|
|
310
|
+
: typeof page.slug === "string"
|
|
311
|
+
? page.slug
|
|
312
|
+
: typeof page.id === "string"
|
|
313
|
+
? page.id
|
|
314
|
+
: "Wiki page")
|
|
315
|
+
.join("\n")
|
|
316
|
+
: "No wiki pages are available.";
|
|
317
|
+
return buildWorkbenchExecutionEnvelope(input, {
|
|
318
|
+
primaryText: summary,
|
|
319
|
+
output: {
|
|
320
|
+
summary,
|
|
321
|
+
pages
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
export function buildWikiHealthWorkbenchExecution(input) {
|
|
326
|
+
const payload = input.context.services.wiki.getHealth?.() ?? null;
|
|
327
|
+
const record = asRecord(payload);
|
|
328
|
+
const unresolvedLinks = Array.isArray(record?.unresolvedLinks)
|
|
329
|
+
? record.unresolvedLinks.length
|
|
330
|
+
: null;
|
|
331
|
+
const orphanPages = Array.isArray(record?.orphanPages)
|
|
332
|
+
? record.orphanPages.length
|
|
333
|
+
: null;
|
|
334
|
+
const summary = record
|
|
335
|
+
? [
|
|
336
|
+
"Wiki health summary",
|
|
337
|
+
unresolvedLinks !== null ? `${unresolvedLinks} unresolved links` : null,
|
|
338
|
+
orphanPages !== null ? `${orphanPages} orphan pages` : null
|
|
339
|
+
]
|
|
340
|
+
.filter(Boolean)
|
|
341
|
+
.join("\n")
|
|
342
|
+
: "No wiki health payload is available.";
|
|
343
|
+
return buildWorkbenchExecutionEnvelope(input, {
|
|
344
|
+
primaryText: summary,
|
|
345
|
+
output: record
|
|
346
|
+
? {
|
|
347
|
+
summary,
|
|
348
|
+
health: record
|
|
349
|
+
}
|
|
350
|
+
: {
|
|
351
|
+
summary
|
|
352
|
+
}
|
|
139
353
|
});
|
|
140
354
|
}
|
|
141
355
|
export function mapWorkbenchTools(tools) {
|
|
142
|
-
return tools.map((
|
|
356
|
+
return tools.map((tool) => tool);
|
|
143
357
|
}
|
|
144
358
|
export function executeCommonWorkbenchTool(context, definition, toolKey, args) {
|
|
145
359
|
if (toolKey === "forge.search_entities") {
|
|
@@ -173,6 +387,8 @@ export function executeCommonWorkbenchTool(context, definition, toolKey, args) {
|
|
|
173
387
|
title: typeof args.title === "string" ? args.title : "Workbench note",
|
|
174
388
|
contentMarkdown: typeof args.markdown === "string" ? args.markdown : "",
|
|
175
389
|
summary: typeof args.summary === "string" ? args.summary : "",
|
|
390
|
+
links: [],
|
|
391
|
+
tags: [],
|
|
176
392
|
sourcePath: "workbench",
|
|
177
393
|
author: "Workbench"
|
|
178
394
|
});
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
function rankAccessMode(mode) {
|
|
2
|
+
switch (mode) {
|
|
3
|
+
case "exec":
|
|
4
|
+
return 4;
|
|
5
|
+
case "read_write":
|
|
6
|
+
return 3;
|
|
7
|
+
case "write":
|
|
8
|
+
return 2;
|
|
9
|
+
case "read":
|
|
10
|
+
default:
|
|
11
|
+
return 1;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function preferAccessMode(left, right) {
|
|
15
|
+
return rankAccessMode(left) >= rankAccessMode(right) ? left : right;
|
|
16
|
+
}
|
|
17
|
+
function normalizeToolDescription(toolKey, descriptions) {
|
|
18
|
+
if (toolKey === "forge.search_entities") {
|
|
19
|
+
return "Search across Forge entities. You can optionally narrow the search to specific entity types.";
|
|
20
|
+
}
|
|
21
|
+
if (toolKey === "forge.create_note") {
|
|
22
|
+
return "Create a Forge note from generated content or captured markdown.";
|
|
23
|
+
}
|
|
24
|
+
if (toolKey === "forge.update_task_status") {
|
|
25
|
+
return "Move a task between execution states such as backlog, focus, in progress, blocked, and done.";
|
|
26
|
+
}
|
|
27
|
+
return descriptions.sort((left, right) => right.length - left.length)[0] ?? "Workbench tool";
|
|
28
|
+
}
|
|
29
|
+
export function buildWorkbenchToolCatalog(boxes) {
|
|
30
|
+
const byKey = new Map();
|
|
31
|
+
for (const box of boxes) {
|
|
32
|
+
for (const tool of box.tools) {
|
|
33
|
+
const current = byKey.get(tool.key);
|
|
34
|
+
if (!current) {
|
|
35
|
+
byKey.set(tool.key, {
|
|
36
|
+
key: tool.key,
|
|
37
|
+
label: tool.label,
|
|
38
|
+
description: normalizeToolDescription(tool.key, [tool.description]),
|
|
39
|
+
accessMode: tool.accessMode,
|
|
40
|
+
argsSchema: tool.argsSchema,
|
|
41
|
+
sources: [box.title],
|
|
42
|
+
sourceSurfaceIds: box.surfaceId ? [box.surfaceId] : []
|
|
43
|
+
});
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
current.accessMode = preferAccessMode(current.accessMode, tool.accessMode);
|
|
47
|
+
current.label = current.label.length >= tool.label.length ? current.label : tool.label;
|
|
48
|
+
current.description = normalizeToolDescription(tool.key, [
|
|
49
|
+
current.description,
|
|
50
|
+
tool.description
|
|
51
|
+
]);
|
|
52
|
+
current.argsSchema = current.argsSchema ?? tool.argsSchema;
|
|
53
|
+
if (!current.sources.includes(box.title)) {
|
|
54
|
+
current.sources.push(box.title);
|
|
55
|
+
}
|
|
56
|
+
if (box.surfaceId && !current.sourceSurfaceIds.includes(box.surfaceId)) {
|
|
57
|
+
current.sourceSurfaceIds.push(box.surfaceId);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return [...byKey.values()].sort((left, right) => {
|
|
62
|
+
const accessDelta = rankAccessMode(right.accessMode) - rankAccessMode(left.accessMode);
|
|
63
|
+
if (accessDelta !== 0) {
|
|
64
|
+
return accessDelta;
|
|
65
|
+
}
|
|
66
|
+
return left.label.localeCompare(right.label);
|
|
67
|
+
});
|
|
68
|
+
}
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS data_management_settings (
|
|
2
|
+
id INTEGER PRIMARY KEY CHECK (id = 1),
|
|
3
|
+
preferred_data_root TEXT NOT NULL DEFAULT '',
|
|
4
|
+
backup_directory TEXT NOT NULL DEFAULT '',
|
|
5
|
+
backup_frequency_hours INTEGER,
|
|
6
|
+
auto_repair_enabled INTEGER NOT NULL DEFAULT 1,
|
|
7
|
+
last_auto_backup_at TEXT,
|
|
8
|
+
last_manual_backup_at TEXT,
|
|
9
|
+
created_at TEXT NOT NULL,
|
|
10
|
+
updated_at TEXT NOT NULL
|
|
11
|
+
);
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
ALTER TABLE tasks
|
|
2
|
+
ADD COLUMN resolution_kind TEXT;
|
|
3
|
+
|
|
4
|
+
ALTER TABLE tasks
|
|
5
|
+
ADD COLUMN split_parent_task_id TEXT;
|
|
6
|
+
|
|
7
|
+
CREATE TABLE IF NOT EXISTS life_force_profiles (
|
|
8
|
+
user_id TEXT PRIMARY KEY,
|
|
9
|
+
base_daily_ap INTEGER NOT NULL DEFAULT 200,
|
|
10
|
+
readiness_multiplier REAL NOT NULL DEFAULT 1.0,
|
|
11
|
+
life_force_level INTEGER NOT NULL DEFAULT 1,
|
|
12
|
+
activation_level INTEGER NOT NULL DEFAULT 1,
|
|
13
|
+
focus_level INTEGER NOT NULL DEFAULT 1,
|
|
14
|
+
vigor_level INTEGER NOT NULL DEFAULT 1,
|
|
15
|
+
composure_level INTEGER NOT NULL DEFAULT 1,
|
|
16
|
+
flow_level INTEGER NOT NULL DEFAULT 1,
|
|
17
|
+
created_at TEXT NOT NULL,
|
|
18
|
+
updated_at TEXT NOT NULL
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
CREATE TABLE IF NOT EXISTS life_force_weekday_templates (
|
|
22
|
+
id TEXT PRIMARY KEY,
|
|
23
|
+
user_id TEXT NOT NULL,
|
|
24
|
+
weekday INTEGER NOT NULL,
|
|
25
|
+
baseline_daily_ap INTEGER NOT NULL DEFAULT 200,
|
|
26
|
+
points_json TEXT NOT NULL,
|
|
27
|
+
created_at TEXT NOT NULL,
|
|
28
|
+
updated_at TEXT NOT NULL,
|
|
29
|
+
UNIQUE(user_id, weekday)
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
CREATE TABLE IF NOT EXISTS life_force_day_snapshots (
|
|
33
|
+
id TEXT PRIMARY KEY,
|
|
34
|
+
user_id TEXT NOT NULL,
|
|
35
|
+
date_key TEXT NOT NULL,
|
|
36
|
+
daily_budget_ap REAL NOT NULL,
|
|
37
|
+
sleep_recovery_multiplier REAL NOT NULL DEFAULT 1.0,
|
|
38
|
+
readiness_multiplier REAL NOT NULL DEFAULT 1.0,
|
|
39
|
+
fatigue_debt_carry REAL NOT NULL DEFAULT 0,
|
|
40
|
+
points_json TEXT NOT NULL,
|
|
41
|
+
created_at TEXT NOT NULL,
|
|
42
|
+
updated_at TEXT NOT NULL,
|
|
43
|
+
UNIQUE(user_id, date_key)
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
CREATE TABLE IF NOT EXISTS action_profile_templates (
|
|
47
|
+
id TEXT PRIMARY KEY,
|
|
48
|
+
profile_key TEXT NOT NULL UNIQUE,
|
|
49
|
+
entity_type TEXT,
|
|
50
|
+
title TEXT NOT NULL,
|
|
51
|
+
profile_json TEXT NOT NULL,
|
|
52
|
+
created_at TEXT NOT NULL,
|
|
53
|
+
updated_at TEXT NOT NULL
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
CREATE TABLE IF NOT EXISTS entity_action_profiles (
|
|
57
|
+
id TEXT PRIMARY KEY,
|
|
58
|
+
entity_type TEXT NOT NULL,
|
|
59
|
+
entity_id TEXT NOT NULL,
|
|
60
|
+
profile_json TEXT NOT NULL,
|
|
61
|
+
created_at TEXT NOT NULL,
|
|
62
|
+
updated_at TEXT NOT NULL,
|
|
63
|
+
UNIQUE(entity_type, entity_id)
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
CREATE TABLE IF NOT EXISTS ap_ledger_events (
|
|
67
|
+
id TEXT PRIMARY KEY,
|
|
68
|
+
user_id TEXT NOT NULL,
|
|
69
|
+
date_key TEXT NOT NULL,
|
|
70
|
+
entity_type TEXT NOT NULL,
|
|
71
|
+
entity_id TEXT NOT NULL,
|
|
72
|
+
event_kind TEXT NOT NULL,
|
|
73
|
+
source_kind TEXT NOT NULL,
|
|
74
|
+
starts_at TEXT,
|
|
75
|
+
ends_at TEXT,
|
|
76
|
+
total_ap REAL NOT NULL,
|
|
77
|
+
rate_ap_per_hour REAL,
|
|
78
|
+
metadata_json TEXT NOT NULL DEFAULT '{}',
|
|
79
|
+
created_at TEXT NOT NULL
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
CREATE INDEX IF NOT EXISTS idx_ap_ledger_user_date
|
|
83
|
+
ON ap_ledger_events(user_id, date_key, created_at DESC);
|
|
84
|
+
|
|
85
|
+
CREATE INDEX IF NOT EXISTS idx_ap_ledger_entity
|
|
86
|
+
ON ap_ledger_events(entity_type, entity_id, created_at DESC);
|
|
87
|
+
|
|
88
|
+
CREATE TABLE IF NOT EXISTS stat_xp_events (
|
|
89
|
+
id TEXT PRIMARY KEY,
|
|
90
|
+
user_id TEXT NOT NULL,
|
|
91
|
+
stat_key TEXT NOT NULL,
|
|
92
|
+
delta_xp REAL NOT NULL,
|
|
93
|
+
entity_type TEXT,
|
|
94
|
+
entity_id TEXT,
|
|
95
|
+
metadata_json TEXT NOT NULL DEFAULT '{}',
|
|
96
|
+
created_at TEXT NOT NULL
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
CREATE INDEX IF NOT EXISTS idx_stat_xp_user_stat
|
|
100
|
+
ON stat_xp_events(user_id, stat_key, created_at DESC);
|
|
101
|
+
|
|
102
|
+
CREATE TABLE IF NOT EXISTS fatigue_signals (
|
|
103
|
+
id TEXT PRIMARY KEY,
|
|
104
|
+
user_id TEXT NOT NULL,
|
|
105
|
+
date_key TEXT NOT NULL,
|
|
106
|
+
signal_type TEXT NOT NULL,
|
|
107
|
+
observed_at TEXT NOT NULL,
|
|
108
|
+
note TEXT NOT NULL DEFAULT '',
|
|
109
|
+
delta REAL NOT NULL DEFAULT 0,
|
|
110
|
+
created_at TEXT NOT NULL
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
CREATE INDEX IF NOT EXISTS idx_fatigue_signals_user_date
|
|
114
|
+
ON fatigue_signals(user_id, date_key, observed_at DESC);
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS screen_time_settings (
|
|
2
|
+
user_id TEXT PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
|
|
3
|
+
tracking_enabled INTEGER NOT NULL DEFAULT 0,
|
|
4
|
+
sync_enabled INTEGER NOT NULL DEFAULT 1,
|
|
5
|
+
authorization_status TEXT NOT NULL DEFAULT 'not_determined',
|
|
6
|
+
capture_state TEXT NOT NULL DEFAULT 'disabled',
|
|
7
|
+
last_captured_day_key TEXT,
|
|
8
|
+
last_capture_started_at TEXT,
|
|
9
|
+
last_capture_ended_at TEXT,
|
|
10
|
+
metadata_json TEXT NOT NULL DEFAULT '{}',
|
|
11
|
+
created_at TEXT NOT NULL,
|
|
12
|
+
updated_at TEXT NOT NULL
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
CREATE TABLE IF NOT EXISTS screen_time_day_summaries (
|
|
16
|
+
id TEXT PRIMARY KEY,
|
|
17
|
+
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
18
|
+
pairing_session_id TEXT REFERENCES companion_pairing_sessions(id) ON DELETE SET NULL,
|
|
19
|
+
source_device TEXT NOT NULL DEFAULT 'iPhone',
|
|
20
|
+
date_key TEXT NOT NULL,
|
|
21
|
+
total_activity_seconds INTEGER NOT NULL DEFAULT 0,
|
|
22
|
+
pickup_count INTEGER NOT NULL DEFAULT 0,
|
|
23
|
+
notification_count INTEGER NOT NULL DEFAULT 0,
|
|
24
|
+
first_pickup_at TEXT,
|
|
25
|
+
longest_activity_seconds INTEGER NOT NULL DEFAULT 0,
|
|
26
|
+
top_app_bundle_ids_json TEXT NOT NULL DEFAULT '[]',
|
|
27
|
+
top_category_labels_json TEXT NOT NULL DEFAULT '[]',
|
|
28
|
+
metadata_json TEXT NOT NULL DEFAULT '{}',
|
|
29
|
+
created_at TEXT NOT NULL,
|
|
30
|
+
updated_at TEXT NOT NULL,
|
|
31
|
+
UNIQUE (user_id, source_device, date_key)
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
CREATE INDEX IF NOT EXISTS idx_screen_time_day_summaries_user
|
|
35
|
+
ON screen_time_day_summaries(user_id, date_key DESC);
|
|
36
|
+
|
|
37
|
+
CREATE TABLE IF NOT EXISTS screen_time_hourly_segments (
|
|
38
|
+
id TEXT PRIMARY KEY,
|
|
39
|
+
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
40
|
+
pairing_session_id TEXT REFERENCES companion_pairing_sessions(id) ON DELETE SET NULL,
|
|
41
|
+
source_device TEXT NOT NULL DEFAULT 'iPhone',
|
|
42
|
+
date_key TEXT NOT NULL,
|
|
43
|
+
hour_index INTEGER NOT NULL,
|
|
44
|
+
started_at TEXT NOT NULL,
|
|
45
|
+
ended_at TEXT NOT NULL,
|
|
46
|
+
total_activity_seconds INTEGER NOT NULL DEFAULT 0,
|
|
47
|
+
pickup_count INTEGER NOT NULL DEFAULT 0,
|
|
48
|
+
notification_count INTEGER NOT NULL DEFAULT 0,
|
|
49
|
+
first_pickup_at TEXT,
|
|
50
|
+
longest_activity_started_at TEXT,
|
|
51
|
+
longest_activity_ended_at TEXT,
|
|
52
|
+
metadata_json TEXT NOT NULL DEFAULT '{}',
|
|
53
|
+
created_at TEXT NOT NULL,
|
|
54
|
+
updated_at TEXT NOT NULL,
|
|
55
|
+
UNIQUE (user_id, source_device, date_key, hour_index)
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
CREATE INDEX IF NOT EXISTS idx_screen_time_hourly_segments_user
|
|
59
|
+
ON screen_time_hourly_segments(user_id, started_at DESC);
|
|
60
|
+
|
|
61
|
+
CREATE TABLE IF NOT EXISTS screen_time_app_usage (
|
|
62
|
+
id TEXT PRIMARY KEY,
|
|
63
|
+
segment_id TEXT NOT NULL REFERENCES screen_time_hourly_segments(id) ON DELETE CASCADE,
|
|
64
|
+
bundle_identifier TEXT NOT NULL,
|
|
65
|
+
display_name TEXT NOT NULL DEFAULT '',
|
|
66
|
+
category_label TEXT,
|
|
67
|
+
total_activity_seconds INTEGER NOT NULL DEFAULT 0,
|
|
68
|
+
pickup_count INTEGER NOT NULL DEFAULT 0,
|
|
69
|
+
notification_count INTEGER NOT NULL DEFAULT 0,
|
|
70
|
+
created_at TEXT NOT NULL,
|
|
71
|
+
updated_at TEXT NOT NULL,
|
|
72
|
+
UNIQUE (segment_id, bundle_identifier)
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
CREATE INDEX IF NOT EXISTS idx_screen_time_app_usage_segment
|
|
76
|
+
ON screen_time_app_usage(segment_id, total_activity_seconds DESC);
|
|
77
|
+
|
|
78
|
+
CREATE TABLE IF NOT EXISTS screen_time_category_usage (
|
|
79
|
+
id TEXT PRIMARY KEY,
|
|
80
|
+
segment_id TEXT NOT NULL REFERENCES screen_time_hourly_segments(id) ON DELETE CASCADE,
|
|
81
|
+
category_label TEXT NOT NULL,
|
|
82
|
+
total_activity_seconds INTEGER NOT NULL DEFAULT 0,
|
|
83
|
+
created_at TEXT NOT NULL,
|
|
84
|
+
updated_at TEXT NOT NULL,
|
|
85
|
+
UNIQUE (segment_id, category_label)
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
CREATE INDEX IF NOT EXISTS idx_screen_time_category_usage_segment
|
|
89
|
+
ON screen_time_category_usage(segment_id, total_activity_seconds DESC);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS companion_pairing_source_states (
|
|
2
|
+
id TEXT PRIMARY KEY,
|
|
3
|
+
pairing_session_id TEXT NOT NULL REFERENCES companion_pairing_sessions(id) ON DELETE CASCADE,
|
|
4
|
+
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
5
|
+
source_key TEXT NOT NULL,
|
|
6
|
+
desired_enabled INTEGER NOT NULL DEFAULT 1,
|
|
7
|
+
applied_enabled INTEGER NOT NULL DEFAULT 0,
|
|
8
|
+
authorization_status TEXT NOT NULL DEFAULT 'not_determined',
|
|
9
|
+
sync_eligible INTEGER NOT NULL DEFAULT 0,
|
|
10
|
+
last_observed_at TEXT,
|
|
11
|
+
metadata_json TEXT NOT NULL DEFAULT '{}',
|
|
12
|
+
created_at TEXT NOT NULL,
|
|
13
|
+
updated_at TEXT NOT NULL,
|
|
14
|
+
UNIQUE (pairing_session_id, source_key)
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
CREATE INDEX IF NOT EXISTS idx_companion_pairing_source_states_pairing
|
|
18
|
+
ON companion_pairing_source_states(pairing_session_id, source_key);
|
|
19
|
+
|
|
20
|
+
CREATE INDEX IF NOT EXISTS idx_companion_pairing_source_states_user
|
|
21
|
+
ON companion_pairing_source_states(user_id, updated_at DESC);
|