forge-openclaw-plugin 0.2.25 → 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-VmF4FAfr.js → board-C6jCchjI.js} +3 -3
- package/dist/assets/{board-VmF4FAfr.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-DvkU14p-.js → motion-DFHrH2rd.js} +2 -2
- package/dist/assets/{motion-DvkU14p-.js.map → motion-DFHrH2rd.js.map} +1 -1
- package/dist/assets/{table-DgiPof9E.js → table-ZL7Di_u3.js} +2 -2
- package/dist/assets/{table-DgiPof9E.js.map → table-ZL7Di_u3.js.map} +1 -1
- package/dist/assets/{ui-nYfoC0Gq.js → ui-CKNPpz7q.js} +2 -2
- package/dist/assets/{ui-nYfoC0Gq.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 -8
- package/dist/openclaw/local-runtime.d.ts +3 -1
- package/dist/openclaw/local-runtime.js +67 -15
- package/dist/openclaw/plugin-entry-shared.js +24 -2
- package/dist/openclaw/plugin-sdk-types.d.ts +17 -0
- package/dist/openclaw/routes.d.ts +27 -0
- package/dist/openclaw/routes.js +16 -12
- package/dist/openclaw/tools.js +0 -3
- package/dist/server/server/migrations/001_core.sql +411 -0
- package/dist/server/server/migrations/002_psyche.sql +392 -0
- package/dist/server/server/migrations/003_habits.sql +30 -0
- package/dist/server/server/migrations/004_habit_links.sql +8 -0
- package/dist/server/server/migrations/005_habit_psyche_links.sql +24 -0
- package/dist/server/server/migrations/006_work_adjustments.sql +14 -0
- package/dist/server/server/migrations/007_weekly_review_closures.sql +17 -0
- package/dist/server/server/migrations/008_calendar_execution.sql +147 -0
- package/dist/server/server/migrations/009_true_calendar_events.sql +195 -0
- package/dist/server/server/migrations/010_calendar_selection_state.sql +6 -0
- package/dist/server/server/migrations/011_calendar_timezone_backfill.sql +11 -0
- package/dist/server/server/migrations/012_work_block_ranges.sql +7 -0
- package/dist/server/server/migrations/013_microsoft_local_auth_settings.sql +8 -0
- package/dist/server/server/migrations/014_note_tags_and_ephemeral.sql +8 -0
- package/dist/server/server/migrations/015_multi_user_and_strategies.sql +244 -0
- package/dist/server/server/migrations/016_health_companion.sql +158 -0
- package/dist/server/server/migrations/016_strategy_contracts_and_user_graph.sql +22 -0
- package/dist/server/server/migrations/017_preferences.sql +131 -0
- package/dist/server/server/migrations/018_preference_catalogs.sql +31 -0
- package/dist/server/server/migrations/019_wiki_memory.sql +255 -0
- package/dist/server/server/migrations/020_wiki_page_hierarchy.sql +11 -0
- package/dist/server/server/migrations/021_hide_evidence_from_wiki_index.sql +3 -0
- package/dist/server/server/migrations/022_wiki_ingest_background.sql +85 -0
- package/dist/server/server/migrations/023_diagnostic_logs.sql +28 -0
- package/dist/server/server/migrations/024_questionnaires.sql +96 -0
- package/dist/server/server/migrations/025_ai_model_connections.sql +26 -0
- package/dist/server/server/migrations/026_custom_theme_settings.sql +2 -0
- package/dist/server/server/migrations/027_ai_processors.sql +31 -0
- package/dist/server/server/migrations/028_movement_domain.sql +136 -0
- package/dist/server/server/migrations/029_watch_micro_capture.sql +23 -0
- package/dist/server/server/migrations/030_surface_layouts.sql +5 -0
- package/dist/server/server/migrations/031_ai_processor_runtime_upgrades.sql +10 -0
- package/dist/server/server/migrations/032_ai_connectors.sql +44 -0
- package/dist/server/server/migrations/033_movement_trip_point_sync.sql +36 -0
- package/dist/server/server/migrations/034_movement_segment_sync.sql +49 -0
- package/dist/server/server/migrations/035_google_local_auth_settings.sql +2 -0
- package/dist/server/server/migrations/036_google_local_auth_client_secret.sql +2 -0
- 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/{app.js → server/src/app.js} +2112 -414
- package/dist/server/server/src/connectors/box-registry.js +223 -0
- package/dist/server/server/src/data-management-types.js +107 -0
- package/dist/server/{db.js → server/src/db.js} +72 -4
- package/dist/server/server/src/debug.js +19 -0
- package/dist/server/{demo-data.js → server/src/demo-data.js} +2 -2
- package/dist/server/{health.js → server/src/health.js} +702 -18
- package/dist/server/{managers → 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/{managers → server/src/managers}/platform/secrets-manager.js +18 -1
- package/dist/server/{managers → server/src/managers}/runtime.js +9 -0
- package/dist/server/{movement.js → server/src/movement.js} +1971 -112
- package/dist/server/{openapi.js → server/src/openapi.js} +491 -3
- package/dist/server/{psyche-types.js → server/src/psyche-types.js} +9 -1
- package/dist/server/{repositories → server/src/repositories}/activity-events.js +8 -0
- package/dist/server/{repositories → server/src/repositories}/ai-connectors.js +758 -47
- package/dist/server/{repositories → server/src/repositories}/calendar.js +1 -1
- package/dist/server/{repositories → server/src/repositories}/habits.js +37 -1
- package/dist/server/{repositories → server/src/repositories}/model-settings.js +13 -3
- package/dist/server/{repositories → server/src/repositories}/notes.js +3 -0
- package/dist/server/{repositories → server/src/repositories}/settings.js +431 -21
- package/dist/server/{repositories → 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/{services → server/src/services}/calendar-runtime.js +775 -58
- package/dist/server/server/src/services/data-management.js +788 -0
- package/dist/server/{services → server/src/services}/entity-crud.js +205 -2
- package/dist/server/server/src/services/google-calendar-oauth-config.js +176 -0
- 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 +413 -0
- package/dist/server/{types.js → server/src/types.js} +420 -29
- package/dist/server/server/src/web.js +332 -0
- package/dist/server/src/components/customization/utility-widgets.js +439 -0
- 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 +147 -0
- package/dist/server/src/components/workbench-boxes/insights/insights-boxes.js +50 -0
- package/dist/server/src/components/workbench-boxes/kanban/kanban-boxes.js +136 -0
- package/dist/server/src/components/workbench-boxes/movement/movement-boxes.js +47 -0
- package/dist/server/src/components/workbench-boxes/notes/notes-boxes.js +132 -0
- 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 +62 -0
- 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 +6 -0
- package/dist/server/src/components/workbench-boxes/shared/generic-node-view.js +49 -0
- 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 +78 -0
- package/dist/server/src/components/workbench-boxes/wiki/wiki-boxes.js +60 -0
- package/dist/server/src/lib/api-error.js +37 -0
- package/dist/server/src/lib/api.js +2118 -0
- package/dist/server/src/lib/calendar-name-deduper.js +144 -0
- package/dist/server/src/lib/data-management-types.js +1 -0
- package/dist/server/src/lib/diagnostics.js +67 -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/psyche-types.js +1 -0
- package/dist/server/src/lib/questionnaire-types.js +1 -0
- package/dist/server/src/lib/runtime-paths.js +24 -0
- package/dist/server/src/lib/schemas.js +238 -0
- package/dist/server/src/lib/snapshot-normalizer.js +416 -0
- package/dist/server/src/lib/theme-system.js +319 -0
- package/dist/server/src/lib/types.js +1 -0
- package/dist/server/src/lib/utils.js +22 -0
- package/dist/server/src/lib/workbench/boxes.js +16 -0
- package/dist/server/src/lib/workbench/contracts.js +229 -0
- package/dist/server/src/lib/workbench/nodes.js +215 -0
- package/dist/server/src/lib/workbench/registry.js +120 -0
- package/dist/server/src/lib/workbench/runtime.js +397 -0
- package/dist/server/src/lib/workbench/tool-catalog.js +68 -0
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/server/index.js +68 -0
- package/server/migrations/035_google_local_auth_settings.sql +2 -0
- package/server/migrations/036_google_local_auth_client_secret.sql +2 -0
- 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 +27 -11
- package/skills/forge-openclaw/entity_conversation_playbooks.md +411 -46
- package/skills/forge-openclaw/psyche_entity_playbooks.md +195 -20
- package/dist/assets/index-CFCKDIMH.js +0 -67
- package/dist/assets/index-CFCKDIMH.js.map +0 -1
- package/dist/assets/index-ZPY6U1TU.css +0 -1
- package/dist/assets/vendor-D9PTEPSB.js +0 -824
- package/dist/assets/vendor-D9PTEPSB.js.map +0 -1
- package/dist/assets/viz-Cqb6s--o.js +0 -34
- package/dist/assets/viz-Cqb6s--o.js.map +0 -1
- package/dist/server/connectors/box-registry.js +0 -257
- package/dist/server/services/psyche-observation-calendar.js +0 -46
- package/dist/server/web.js +0 -98
- /package/dist/server/{discovery-advertiser.js → server/src/discovery-advertiser.js} +0 -0
- /package/dist/server/{e2e-server.js → server/src/e2e-server.js} +0 -0
- /package/dist/server/{errors.js → server/src/errors.js} +0 -0
- /package/dist/server/{index.js → server/src/index.js} +0 -0
- /package/dist/server/{managers → server/src/managers}/base.js +0 -0
- /package/dist/server/{managers → server/src/managers}/contracts.js +0 -0
- /package/dist/server/{managers → server/src/managers}/platform/api-gateway-manager.js +0 -0
- /package/dist/server/{managers → server/src/managers}/platform/audit-manager.js +0 -0
- /package/dist/server/{managers → server/src/managers}/platform/authentication-manager.js +0 -0
- /package/dist/server/{managers → server/src/managers}/platform/authorization-manager.js +0 -0
- /package/dist/server/{managers → server/src/managers}/platform/background-job-manager.js +0 -0
- /package/dist/server/{managers → server/src/managers}/platform/configuration-manager.js +0 -0
- /package/dist/server/{managers → server/src/managers}/platform/database-manager.js +0 -0
- /package/dist/server/{managers → server/src/managers}/platform/event-bus-manager.js +0 -0
- /package/dist/server/{managers → server/src/managers}/platform/external-service-manager.js +0 -0
- /package/dist/server/{managers → server/src/managers}/platform/health-manager.js +0 -0
- /package/dist/server/{managers → server/src/managers}/platform/migration-manager.js +0 -0
- /package/dist/server/{managers → server/src/managers}/platform/openai-responses-provider.js +0 -0
- /package/dist/server/{managers → server/src/managers}/platform/search-index-manager.js +0 -0
- /package/dist/server/{managers → server/src/managers}/platform/session-manager.js +0 -0
- /package/dist/server/{managers → server/src/managers}/platform/storage-manager.js +0 -0
- /package/dist/server/{managers → server/src/managers}/platform/token-manager.js +0 -0
- /package/dist/server/{managers → server/src/managers}/platform/transaction-manager.js +0 -0
- /package/dist/server/{managers → server/src/managers}/platform/trusted-network.js +0 -0
- /package/dist/server/{managers → server/src/managers}/type-guards.js +0 -0
- /package/dist/server/{preferences-seeds.js → server/src/preferences-seeds.js} +0 -0
- /package/dist/server/{preferences-types.js → server/src/preferences-types.js} +0 -0
- /package/dist/server/{questionnaire-flow.js → server/src/questionnaire-flow.js} +0 -0
- /package/dist/server/{questionnaire-seeds.js → server/src/questionnaire-seeds.js} +0 -0
- /package/dist/server/{questionnaire-types.js → server/src/questionnaire-types.js} +0 -0
- /package/dist/server/{repositories → server/src/repositories}/ai-processors.js +0 -0
- /package/dist/server/{repositories → server/src/repositories}/collaboration.js +0 -0
- /package/dist/server/{repositories → server/src/repositories}/deleted-entities.js +0 -0
- /package/dist/server/{repositories → server/src/repositories}/diagnostic-logs.js +0 -0
- /package/dist/server/{repositories → server/src/repositories}/domains.js +0 -0
- /package/dist/server/{repositories → server/src/repositories}/entity-ownership.js +0 -0
- /package/dist/server/{repositories → server/src/repositories}/event-log.js +0 -0
- /package/dist/server/{repositories → server/src/repositories}/goals.js +0 -0
- /package/dist/server/{repositories → server/src/repositories}/preferences.js +0 -0
- /package/dist/server/{repositories → server/src/repositories}/projects.js +0 -0
- /package/dist/server/{repositories → server/src/repositories}/psyche.js +0 -0
- /package/dist/server/{repositories → server/src/repositories}/questionnaires.js +0 -0
- /package/dist/server/{repositories → server/src/repositories}/rewards.js +0 -0
- /package/dist/server/{repositories → server/src/repositories}/strategies.js +0 -0
- /package/dist/server/{repositories → server/src/repositories}/surface-layouts.js +0 -0
- /package/dist/server/{repositories → server/src/repositories}/tags.js +0 -0
- /package/dist/server/{repositories → server/src/repositories}/task-runs.js +0 -0
- /package/dist/server/{repositories → server/src/repositories}/users.js +0 -0
- /package/dist/server/{repositories → server/src/repositories}/weekly-reviews.js +0 -0
- /package/dist/server/{repositories → server/src/repositories}/wiki-memory.js +0 -0
- /package/dist/server/{repositories → server/src/repositories}/work-adjustments.js +0 -0
- /package/dist/server/{seed-demo.js → server/src/seed-demo.js} +0 -0
- /package/dist/server/{services → server/src/services}/context.js +0 -0
- /package/dist/server/{services → server/src/services}/dashboard.js +0 -0
- /package/dist/server/{services → server/src/services}/gamification.js +0 -0
- /package/dist/server/{services → server/src/services}/insights.js +0 -0
- /package/dist/server/{services → server/src/services}/openai-codex-oauth.js +0 -0
- /package/dist/server/{services → server/src/services}/projects.js +0 -0
- /package/dist/server/{services → server/src/services}/psyche.js +0 -0
- /package/dist/server/{services → server/src/services}/relations.js +0 -0
- /package/dist/server/{services → server/src/services}/reviews.js +0 -0
- /package/dist/server/{services → server/src/services}/run-recovery.js +0 -0
- /package/dist/server/{services → server/src/services}/tagging.js +0 -0
- /package/dist/server/{services → server/src/services}/task-run-watchdog.js +0 -0
- /package/dist/server/{services → server/src/services}/work-time.js +0 -0
- /package/dist/server/{watch-mobile.js → server/src/watch-mobile.js} +0 -0
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
function asRecord(value) {
|
|
2
|
+
return value && typeof value === "object" && !Array.isArray(value)
|
|
3
|
+
? value
|
|
4
|
+
: null;
|
|
5
|
+
}
|
|
6
|
+
function readTextValue(...values) {
|
|
7
|
+
for (const value of values) {
|
|
8
|
+
if (typeof value === "string") {
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
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
|
+
}
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
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
|
+
}
|
|
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
|
+
});
|
|
82
|
+
return outputMap;
|
|
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
|
+
}
|
|
102
|
+
export function buildWorkbenchExecutionEnvelope(input, value) {
|
|
103
|
+
const payload = normalizeWorkbenchOutputPayload(input.definition, value.output, value.primaryText);
|
|
104
|
+
return {
|
|
105
|
+
primaryText: value.primaryText,
|
|
106
|
+
payload,
|
|
107
|
+
logs: value.logs ?? [],
|
|
108
|
+
outputMap: buildWorkbenchOutputMap(value.primaryText, payload, input.definition.output)
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
export function buildStaticWorkbenchExecution(input, output, primaryText, logs) {
|
|
112
|
+
return buildWorkbenchExecutionEnvelope(input, {
|
|
113
|
+
primaryText: primaryText ??
|
|
114
|
+
`${input.definition.title}\n${input.definition.description}\nRoute: ${input.definition.routePath ?? "n/a"}`,
|
|
115
|
+
output,
|
|
116
|
+
logs
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
export function searchWorkbenchEntities(context, definition, input) {
|
|
120
|
+
const limit = Math.max(1, Math.min(50, Math.round(input.limit ?? 12)));
|
|
121
|
+
const result = context.services.entities.search({
|
|
122
|
+
searches: [
|
|
123
|
+
{
|
|
124
|
+
query: input.query,
|
|
125
|
+
entityTypes: input.entityTypes,
|
|
126
|
+
limit
|
|
127
|
+
}
|
|
128
|
+
]
|
|
129
|
+
}).results[0];
|
|
130
|
+
const matches = result?.ok ? result.matches ?? [] : [];
|
|
131
|
+
const summaryLines = matches
|
|
132
|
+
.slice(0, limit)
|
|
133
|
+
.map((match) => {
|
|
134
|
+
const title = typeof match.title === "string"
|
|
135
|
+
? match.title
|
|
136
|
+
: typeof match.name === "string"
|
|
137
|
+
? match.name
|
|
138
|
+
: typeof match.id === "string"
|
|
139
|
+
? match.id
|
|
140
|
+
: "Untitled";
|
|
141
|
+
const entityType = typeof match.entityType === "string" ? match.entityType : "entity";
|
|
142
|
+
return `${entityType}: ${title}`;
|
|
143
|
+
});
|
|
144
|
+
return {
|
|
145
|
+
title: definition.title,
|
|
146
|
+
matches,
|
|
147
|
+
summaryText: summaryLines.length > 0
|
|
148
|
+
? summaryLines.join("\n")
|
|
149
|
+
: `No ${definition.title.toLowerCase()} matches found.`,
|
|
150
|
+
limit,
|
|
151
|
+
query: input.query
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
export function buildSearchWorkbenchExecution(input, config) {
|
|
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
|
+
});
|
|
163
|
+
return buildWorkbenchExecutionEnvelope(input, {
|
|
164
|
+
primaryText: summary.summaryText,
|
|
165
|
+
output: {
|
|
166
|
+
summary: summary.summaryText,
|
|
167
|
+
matches: summary.matches,
|
|
168
|
+
matchCount: summary.matches.length
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
export function buildMovementPlacesExecution(input) {
|
|
173
|
+
const places = input.context.services.movement.listPlaces?.() ?? [];
|
|
174
|
+
return buildWorkbenchExecutionEnvelope(input, {
|
|
175
|
+
primaryText: places.length > 0
|
|
176
|
+
? places
|
|
177
|
+
.slice(0, 24)
|
|
178
|
+
.map((place) => typeof place.label === "string"
|
|
179
|
+
? place.label
|
|
180
|
+
: typeof place.name === "string"
|
|
181
|
+
? place.name
|
|
182
|
+
: typeof place.id === "string"
|
|
183
|
+
? place.id
|
|
184
|
+
: "Place")
|
|
185
|
+
.join("\n")
|
|
186
|
+
: "No known places are stored yet.",
|
|
187
|
+
output: {
|
|
188
|
+
summary: places.length > 0
|
|
189
|
+
? `${places.length} place${places.length === 1 ? "" : "s"} available.`
|
|
190
|
+
: "No known places are stored yet.",
|
|
191
|
+
places
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
export function buildSleepWorkbenchExecution(input) {
|
|
196
|
+
const payload = input.context.services.health.getSleepViewData?.() ?? null;
|
|
197
|
+
return buildWorkbenchExecutionEnvelope(input, {
|
|
198
|
+
primaryText: payload && typeof payload === "object"
|
|
199
|
+
? "Sleep history and derived patterns are available."
|
|
200
|
+
: "No sleep data is available.",
|
|
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
|
+
}
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
export function buildSportsWorkbenchExecution(input) {
|
|
212
|
+
const payload = input.context.services.health.getFitnessViewData?.() ?? null;
|
|
213
|
+
return buildWorkbenchExecutionEnvelope(input, {
|
|
214
|
+
primaryText: payload && typeof payload === "object"
|
|
215
|
+
? "Workout history and composition are available."
|
|
216
|
+
: "No sports data is available.",
|
|
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
|
+
}
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
export function mapWorkbenchTools(tools) {
|
|
356
|
+
return tools.map((tool) => tool);
|
|
357
|
+
}
|
|
358
|
+
export function executeCommonWorkbenchTool(context, definition, toolKey, args) {
|
|
359
|
+
if (toolKey === "forge.search_entities") {
|
|
360
|
+
const query = typeof args.query === "string" ? args.query.trim() : "";
|
|
361
|
+
const entityTypes = Array.isArray(args.entityTypes)
|
|
362
|
+
? args.entityTypes.filter((entry) => typeof entry === "string" && entry.length > 0)
|
|
363
|
+
: [];
|
|
364
|
+
const limit = typeof args.limit === "number" && Number.isFinite(args.limit)
|
|
365
|
+
? args.limit
|
|
366
|
+
: 12;
|
|
367
|
+
return searchWorkbenchEntities(context, definition, {
|
|
368
|
+
query,
|
|
369
|
+
entityTypes,
|
|
370
|
+
limit
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
if (toolKey === "forge.update_task_status") {
|
|
374
|
+
const taskId = typeof args.taskId === "string" ? args.taskId : "";
|
|
375
|
+
const status = typeof args.status === "string" ? args.status : "";
|
|
376
|
+
if (!context.services.tasks.update) {
|
|
377
|
+
throw new Error("Task update service is not available.");
|
|
378
|
+
}
|
|
379
|
+
return context.services.tasks.update(taskId, { status });
|
|
380
|
+
}
|
|
381
|
+
if (toolKey === "forge.create_note") {
|
|
382
|
+
if (!context.services.notes.create) {
|
|
383
|
+
throw new Error("Note creation service is not available.");
|
|
384
|
+
}
|
|
385
|
+
return context.services.notes.create({
|
|
386
|
+
kind: "evidence",
|
|
387
|
+
title: typeof args.title === "string" ? args.title : "Workbench note",
|
|
388
|
+
contentMarkdown: typeof args.markdown === "string" ? args.markdown : "",
|
|
389
|
+
summary: typeof args.summary === "string" ? args.summary : "",
|
|
390
|
+
links: [],
|
|
391
|
+
tags: [],
|
|
392
|
+
sourcePath: "workbench",
|
|
393
|
+
author: "Workbench"
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
throw new Error(`Unsupported Workbench tool: ${toolKey}`);
|
|
397
|
+
}
|
|
@@ -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
package/server/index.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { spawn } from "node:child_process";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
5
|
+
|
|
6
|
+
const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
7
|
+
const repoRoot = path.resolve(packageRoot, "..");
|
|
8
|
+
const builtRuntimeEntry = path.join(packageRoot, "dist", "server", "server", "src", "index.js");
|
|
9
|
+
const devRuntimeEntry = path.join(repoRoot, "server", "src", "index.ts");
|
|
10
|
+
const devDataRootWrapper = path.join(repoRoot, "scripts", "with-openclaw-plugin-data-root.mjs");
|
|
11
|
+
const tsxCliEntry = path.join(repoRoot, "node_modules", "tsx", "dist", "cli.mjs");
|
|
12
|
+
const devModeFlag = (process.env.FORGE_OPENCLAW_DEV ?? "").trim().toLowerCase();
|
|
13
|
+
const useDevRuntime = devModeFlag === "1" || devModeFlag === "true" || devModeFlag === "yes";
|
|
14
|
+
|
|
15
|
+
if (!useDevRuntime) {
|
|
16
|
+
await import(pathToFileURL(builtRuntimeEntry).href);
|
|
17
|
+
} else {
|
|
18
|
+
if (!existsSync(devRuntimeEntry) || !existsSync(devDataRootWrapper) || !existsSync(tsxCliEntry)) {
|
|
19
|
+
throw new Error(
|
|
20
|
+
"FORGE_OPENCLAW_DEV is enabled, but the Forge repo dev runtime was not found. " +
|
|
21
|
+
"Run this from the Forge repository checkout or disable FORGE_OPENCLAW_DEV."
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
console.log("[forge-openclaw-plugin] starting source-backed dev runtime on port", process.env.PORT ?? "4317");
|
|
26
|
+
|
|
27
|
+
const child = spawn(
|
|
28
|
+
process.execPath,
|
|
29
|
+
[devDataRootWrapper, process.execPath, tsxCliEntry, "watch", devRuntimeEntry],
|
|
30
|
+
{
|
|
31
|
+
cwd: repoRoot,
|
|
32
|
+
stdio: "inherit",
|
|
33
|
+
env: {
|
|
34
|
+
...process.env,
|
|
35
|
+
FORGE_DEV_WEB_ORIGIN:
|
|
36
|
+
process.env.FORGE_DEV_WEB_ORIGIN ?? "http://127.0.0.1:3027/forge/",
|
|
37
|
+
HOST: process.env.HOST ?? "0.0.0.0",
|
|
38
|
+
PORT: process.env.PORT ?? "4317"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
const forwardSignal = (signal) => {
|
|
44
|
+
if (!child.killed) {
|
|
45
|
+
child.kill(signal);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
process.on("SIGINT", forwardSignal);
|
|
50
|
+
process.on("SIGTERM", forwardSignal);
|
|
51
|
+
|
|
52
|
+
await new Promise((resolve, reject) => {
|
|
53
|
+
child.once("error", reject);
|
|
54
|
+
child.once("exit", (code, signal) => {
|
|
55
|
+
if (signal) {
|
|
56
|
+
process.exitCode = signal === "SIGINT" || signal === "SIGTERM" ? 0 : 1;
|
|
57
|
+
resolve();
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (code === 0) {
|
|
61
|
+
resolve();
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
reject(new Error(`Forge OpenClaw dev runtime exited with code ${code ?? "unknown"}.`));
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
@@ -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);
|