forge-openclaw-plugin 0.2.25 → 0.2.26
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/dist/assets/{board-VmF4FAfr.js → board-ta0rUHOf.js} +3 -3
- package/dist/assets/{board-VmF4FAfr.js.map → board-ta0rUHOf.js.map} +1 -1
- package/dist/assets/index-Ro0ZF_az.css +1 -0
- package/dist/assets/index-ytlpSj23.js +79 -0
- package/dist/assets/index-ytlpSj23.js.map +1 -0
- package/dist/assets/{motion-DvkU14p-.js → motion-fBKPB6yw.js} +2 -2
- package/dist/assets/{motion-DvkU14p-.js.map → motion-fBKPB6yw.js.map} +1 -1
- package/dist/assets/{table-DgiPof9E.js → table-C-IGTQni.js} +2 -2
- package/dist/assets/{table-DgiPof9E.js.map → table-C-IGTQni.js.map} +1 -1
- package/dist/assets/{ui-nYfoC0Gq.js → ui-DInOpaYF.js} +2 -2
- package/dist/assets/{ui-nYfoC0Gq.js.map → ui-DInOpaYF.js.map} +1 -1
- package/dist/assets/vendor-lE3tZJcC.js +876 -0
- package/dist/assets/vendor-lE3tZJcC.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 +51 -15
- package/dist/openclaw/plugin-entry-shared.js +24 -2
- package/dist/openclaw/plugin-sdk-types.d.ts +17 -0
- 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/{app.js → server/src/app.js} +242 -111
- package/dist/server/server/src/connectors/box-registry.js +188 -0
- package/dist/server/{db.js → server/src/db.js} +4 -0
- package/dist/server/server/src/debug.js +19 -0
- package/dist/server/{openapi.js → server/src/openapi.js} +2 -2
- package/dist/server/{repositories → server/src/repositories}/ai-connectors.js +286 -23
- package/dist/server/{repositories → server/src/repositories}/calendar.js +1 -1
- package/dist/server/{repositories → server/src/repositories}/settings.js +51 -3
- package/dist/server/{services → server/src/services}/calendar-runtime.js +775 -58
- package/dist/server/server/src/services/google-calendar-oauth-config.js +176 -0
- package/dist/server/{types.js → server/src/types.js} +137 -19
- package/dist/server/{web.js → server/src/web.js} +21 -2
- package/dist/server/src/components/customization/utility-widgets.js +330 -0
- package/dist/server/src/components/workbench-boxes/health/health-boxes.js +92 -0
- package/dist/server/src/components/workbench-boxes/kanban/kanban-boxes.js +128 -0
- package/dist/server/src/components/workbench-boxes/movement/movement-boxes.js +37 -0
- package/dist/server/src/components/workbench-boxes/notes/notes-boxes.js +114 -0
- package/dist/server/src/components/workbench-boxes/projects/projects-boxes.js +57 -0
- package/dist/server/src/components/workbench-boxes/shared/define-workbench-box.js +4 -0
- package/dist/server/src/components/workbench-boxes/shared/generic-node-view.js +13 -0
- package/dist/server/src/components/workbench-boxes/today/today-boxes.js +63 -0
- package/dist/server/src/lib/api-error.js +37 -0
- package/dist/server/src/lib/api.js +1859 -0
- package/dist/server/src/lib/calendar-name-deduper.js +144 -0
- package/dist/server/src/lib/diagnostics.js +67 -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 +234 -0
- package/dist/server/src/lib/snapshot-normalizer.js +374 -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/nodes.js +15 -0
- package/dist/server/src/lib/workbench/registry.js +73 -0
- package/dist/server/src/lib/workbench/runtime.js +181 -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/skills/forge-openclaw/SKILL.md +3 -0
- package/skills/forge-openclaw/entity_conversation_playbooks.md +213 -24
- package/skills/forge-openclaw/psyche_entity_playbooks.md +82 -3
- 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/{demo-data.js → server/src/demo-data.js} +0 -0
- /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/{health.js → server/src/health.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/llm-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/secrets-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}/runtime.js +0 -0
- /package/dist/server/{managers → server/src/managers}/type-guards.js +0 -0
- /package/dist/server/{movement.js → server/src/movement.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/{psyche-types.js → server/src/psyche-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}/activity-events.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}/habits.js +0 -0
- /package/dist/server/{repositories → server/src/repositories}/model-settings.js +0 -0
- /package/dist/server/{repositories → server/src/repositories}/notes.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}/tasks.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}/entity-crud.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-observation-calendar.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,22 @@
|
|
|
1
|
+
import { clsx } from "clsx";
|
|
2
|
+
import { twMerge } from "tailwind-merge";
|
|
3
|
+
export function cn(...inputs) {
|
|
4
|
+
return twMerge(clsx(inputs));
|
|
5
|
+
}
|
|
6
|
+
export function formatDateTime(value) {
|
|
7
|
+
return new Intl.DateTimeFormat(undefined, {
|
|
8
|
+
month: "short",
|
|
9
|
+
day: "numeric",
|
|
10
|
+
hour: "numeric",
|
|
11
|
+
minute: "2-digit"
|
|
12
|
+
}).format(new Date(value));
|
|
13
|
+
}
|
|
14
|
+
export function formatDate(value) {
|
|
15
|
+
if (!value) {
|
|
16
|
+
return "No date";
|
|
17
|
+
}
|
|
18
|
+
return new Intl.DateTimeFormat(undefined, {
|
|
19
|
+
month: "short",
|
|
20
|
+
day: "numeric"
|
|
21
|
+
}).format(new Date(`${value}T00:00:00.000Z`));
|
|
22
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { getWorkbenchNodeCatalog, getWorkbenchNodeDefinition, listWorkbenchNodeDefinitions } from "./registry.js";
|
|
2
|
+
export function listWorkbenchBoxDefinitions() {
|
|
3
|
+
return listWorkbenchNodeDefinitions();
|
|
4
|
+
}
|
|
5
|
+
export function getWorkbenchBoxDefinition(boxId) {
|
|
6
|
+
return getWorkbenchNodeDefinition(boxId);
|
|
7
|
+
}
|
|
8
|
+
export function getWorkbenchBoxDefinitionForSurfaceWidget(surfaceId, widgetId) {
|
|
9
|
+
return getWorkbenchBoxDefinition(`surface:${surfaceId}:${widgetId}`);
|
|
10
|
+
}
|
|
11
|
+
export function getWorkbenchBoxDefinitionForRouteMain(surfaceId) {
|
|
12
|
+
return getWorkbenchBoxDefinition(`surface:${surfaceId}:main`);
|
|
13
|
+
}
|
|
14
|
+
export function listWorkbenchBoxCatalogEntries() {
|
|
15
|
+
return getWorkbenchNodeCatalog();
|
|
16
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function defineWorkbenchComponent(component, workbench) {
|
|
2
|
+
return Object.assign(component, {
|
|
3
|
+
workbench: {
|
|
4
|
+
...workbench,
|
|
5
|
+
WebView: component
|
|
6
|
+
}
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
export function isWorkbenchRegisteredComponent(value) {
|
|
10
|
+
const candidate = value;
|
|
11
|
+
return Boolean(candidate &&
|
|
12
|
+
typeof value === "function" &&
|
|
13
|
+
candidate.workbench &&
|
|
14
|
+
typeof candidate.workbench.id === "string");
|
|
15
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { MiniCalendarWidget, QuickCaptureWidget, SpotifyWidget, TimeWidget, WeatherWidget } from "../../components/customization/utility-widgets.js";
|
|
2
|
+
import { KanbanBoardBox, KanbanFiltersBox, KanbanSummaryBox } from "../../components/workbench-boxes/kanban/kanban-boxes.js";
|
|
3
|
+
import { SleepBrowserBox, SleepPatternsBox, SleepSummaryBox, SportsBrowserBox, SportsCompositionBox, SportsSummaryBox } from "../../components/workbench-boxes/health/health-boxes.js";
|
|
4
|
+
import { MovementDataBrowserBox, MovementPlacesBox, MovementSelectionBox, MovementSummaryBox, MovementTimelineBox } from "../../components/workbench-boxes/movement/movement-boxes.js";
|
|
5
|
+
import { NoteComposerBox, NoteFiltersBox, NotesLibraryBox } from "../../components/workbench-boxes/notes/notes-boxes.js";
|
|
6
|
+
import { ProjectsHeroBox, ProjectsSearchResultsBox, ProjectsSummaryBox } from "../../components/workbench-boxes/projects/projects-boxes.js";
|
|
7
|
+
import { TodayCalendarBox, TodayFocusBox, TodayHeroBox, TodayMetricsBox, TodayRunwayBox } from "../../components/workbench-boxes/today/today-boxes.js";
|
|
8
|
+
export const WORKBENCH_COMPONENT_AUTOLOAD = [
|
|
9
|
+
TimeWidget,
|
|
10
|
+
MiniCalendarWidget,
|
|
11
|
+
SpotifyWidget,
|
|
12
|
+
WeatherWidget,
|
|
13
|
+
QuickCaptureWidget,
|
|
14
|
+
KanbanSummaryBox,
|
|
15
|
+
KanbanFiltersBox,
|
|
16
|
+
KanbanBoardBox,
|
|
17
|
+
NoteFiltersBox,
|
|
18
|
+
NoteComposerBox,
|
|
19
|
+
NotesLibraryBox,
|
|
20
|
+
MovementSummaryBox,
|
|
21
|
+
MovementSelectionBox,
|
|
22
|
+
MovementTimelineBox,
|
|
23
|
+
MovementPlacesBox,
|
|
24
|
+
MovementDataBrowserBox,
|
|
25
|
+
SleepSummaryBox,
|
|
26
|
+
SleepPatternsBox,
|
|
27
|
+
SleepBrowserBox,
|
|
28
|
+
SportsSummaryBox,
|
|
29
|
+
SportsCompositionBox,
|
|
30
|
+
SportsBrowserBox,
|
|
31
|
+
ProjectsHeroBox,
|
|
32
|
+
ProjectsSearchResultsBox,
|
|
33
|
+
ProjectsSummaryBox,
|
|
34
|
+
TodayHeroBox,
|
|
35
|
+
TodayMetricsBox,
|
|
36
|
+
TodayRunwayBox,
|
|
37
|
+
TodayCalendarBox,
|
|
38
|
+
TodayFocusBox
|
|
39
|
+
];
|
|
40
|
+
const REGISTRY = new Map(WORKBENCH_COMPONENT_AUTOLOAD
|
|
41
|
+
.filter((component) => component.workbench)
|
|
42
|
+
.map((component) => [component.workbench.id, component.workbench]));
|
|
43
|
+
export function listWorkbenchNodeDefinitions() {
|
|
44
|
+
return Array.from(REGISTRY.values());
|
|
45
|
+
}
|
|
46
|
+
export function getWorkbenchNodeDefinition(nodeId) {
|
|
47
|
+
return REGISTRY.get(nodeId) ?? null;
|
|
48
|
+
}
|
|
49
|
+
export function getWorkbenchNodeCatalog() {
|
|
50
|
+
return listWorkbenchNodeDefinitions().map((definition) => ({
|
|
51
|
+
id: definition.id,
|
|
52
|
+
boxId: definition.id,
|
|
53
|
+
surfaceId: definition.surfaceId,
|
|
54
|
+
routePath: definition.routePath,
|
|
55
|
+
title: definition.title,
|
|
56
|
+
label: definition.title,
|
|
57
|
+
icon: definition.icon ?? null,
|
|
58
|
+
description: definition.description,
|
|
59
|
+
category: definition.category,
|
|
60
|
+
tags: definition.tags,
|
|
61
|
+
capabilityModes: [
|
|
62
|
+
"content",
|
|
63
|
+
...(definition.tools.length > 0 ? ["tool"] : [])
|
|
64
|
+
],
|
|
65
|
+
inputs: definition.inputs,
|
|
66
|
+
params: definition.params,
|
|
67
|
+
output: definition.output,
|
|
68
|
+
tools: definition.tools,
|
|
69
|
+
outputs: definition.output,
|
|
70
|
+
toolAdapters: definition.tools,
|
|
71
|
+
snapshotResolverKey: undefined
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
function asRecord(value) {
|
|
2
|
+
return value && typeof value === "object" && !Array.isArray(value)
|
|
3
|
+
? value
|
|
4
|
+
: null;
|
|
5
|
+
}
|
|
6
|
+
export function buildWorkbenchOutputMap(text, json, keys) {
|
|
7
|
+
const outputMap = {
|
|
8
|
+
primary: {
|
|
9
|
+
text,
|
|
10
|
+
json
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
for (const key of keys) {
|
|
14
|
+
if (!json || !(key in json)) {
|
|
15
|
+
outputMap[key] = {
|
|
16
|
+
text,
|
|
17
|
+
json
|
|
18
|
+
};
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
const value = json[key];
|
|
22
|
+
outputMap[key] = {
|
|
23
|
+
text: typeof value === "string"
|
|
24
|
+
? value
|
|
25
|
+
: Array.isArray(value) || asRecord(value)
|
|
26
|
+
? JSON.stringify(value, null, 2)
|
|
27
|
+
: String(value ?? ""),
|
|
28
|
+
json: asRecord(value)
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
return outputMap;
|
|
32
|
+
}
|
|
33
|
+
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
|
+
};
|
|
43
|
+
return {
|
|
44
|
+
primaryText: value.primaryText,
|
|
45
|
+
payload,
|
|
46
|
+
logs: value.logs ?? [],
|
|
47
|
+
outputMap: buildWorkbenchOutputMap(value.primaryText, payload, Object.keys(value.output ?? {}))
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
export function buildStaticWorkbenchExecution(input, output, primaryText, logs) {
|
|
51
|
+
return buildWorkbenchExecutionEnvelope(input, {
|
|
52
|
+
primaryText: primaryText ??
|
|
53
|
+
`${input.definition.title}\n${input.definition.description}\nRoute: ${input.definition.routePath ?? "n/a"}`,
|
|
54
|
+
output,
|
|
55
|
+
logs
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
export function searchWorkbenchEntities(context, definition, input) {
|
|
59
|
+
const limit = Math.max(1, Math.min(50, Math.round(input.limit ?? 12)));
|
|
60
|
+
const result = context.services.entities.search({
|
|
61
|
+
searches: [
|
|
62
|
+
{
|
|
63
|
+
query: input.query,
|
|
64
|
+
entityTypes: input.entityTypes,
|
|
65
|
+
limit
|
|
66
|
+
}
|
|
67
|
+
]
|
|
68
|
+
}).results[0];
|
|
69
|
+
const matches = result?.ok ? result.matches ?? [] : [];
|
|
70
|
+
const summaryLines = matches
|
|
71
|
+
.slice(0, limit)
|
|
72
|
+
.map((match) => {
|
|
73
|
+
const title = typeof match.title === "string"
|
|
74
|
+
? match.title
|
|
75
|
+
: typeof match.name === "string"
|
|
76
|
+
? match.name
|
|
77
|
+
: typeof match.id === "string"
|
|
78
|
+
? match.id
|
|
79
|
+
: "Untitled";
|
|
80
|
+
const entityType = typeof match.entityType === "string" ? match.entityType : "entity";
|
|
81
|
+
return `${entityType}: ${title}`;
|
|
82
|
+
});
|
|
83
|
+
return {
|
|
84
|
+
title: definition.title,
|
|
85
|
+
matches,
|
|
86
|
+
summaryText: summaryLines.length > 0
|
|
87
|
+
? summaryLines.join("\n")
|
|
88
|
+
: `No ${definition.title.toLowerCase()} matches found.`,
|
|
89
|
+
limit
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
export function buildSearchWorkbenchExecution(input, config) {
|
|
93
|
+
const summary = searchWorkbenchEntities(input.context, input.definition, config);
|
|
94
|
+
return buildWorkbenchExecutionEnvelope(input, {
|
|
95
|
+
primaryText: summary.summaryText,
|
|
96
|
+
output: {
|
|
97
|
+
matches: summary.matches,
|
|
98
|
+
limit: summary.limit,
|
|
99
|
+
entityTypes: config.entityTypes
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
export function buildMovementPlacesExecution(input) {
|
|
104
|
+
const places = input.context.services.movement.listPlaces?.() ?? [];
|
|
105
|
+
return buildWorkbenchExecutionEnvelope(input, {
|
|
106
|
+
primaryText: places.length > 0
|
|
107
|
+
? places
|
|
108
|
+
.slice(0, 24)
|
|
109
|
+
.map((place) => typeof place.label === "string"
|
|
110
|
+
? place.label
|
|
111
|
+
: typeof place.name === "string"
|
|
112
|
+
? place.name
|
|
113
|
+
: typeof place.id === "string"
|
|
114
|
+
? place.id
|
|
115
|
+
: "Place")
|
|
116
|
+
.join("\n")
|
|
117
|
+
: "No known places are stored yet.",
|
|
118
|
+
output: {
|
|
119
|
+
places
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
export function buildSleepWorkbenchExecution(input) {
|
|
124
|
+
const payload = input.context.services.health.getSleepViewData?.() ?? null;
|
|
125
|
+
return buildWorkbenchExecutionEnvelope(input, {
|
|
126
|
+
primaryText: payload && typeof payload === "object"
|
|
127
|
+
? "Sleep history and derived patterns are available."
|
|
128
|
+
: "No sleep data is available.",
|
|
129
|
+
output: asRecord(payload)
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
export function buildSportsWorkbenchExecution(input) {
|
|
133
|
+
const payload = input.context.services.health.getFitnessViewData?.() ?? null;
|
|
134
|
+
return buildWorkbenchExecutionEnvelope(input, {
|
|
135
|
+
primaryText: payload && typeof payload === "object"
|
|
136
|
+
? "Workout history and composition are available."
|
|
137
|
+
: "No sports data is available.",
|
|
138
|
+
output: asRecord(payload)
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
export function mapWorkbenchTools(tools) {
|
|
142
|
+
return tools.map(({ argsSchema: _argsSchema, ...tool }) => tool);
|
|
143
|
+
}
|
|
144
|
+
export function executeCommonWorkbenchTool(context, definition, toolKey, args) {
|
|
145
|
+
if (toolKey === "forge.search_entities") {
|
|
146
|
+
const query = typeof args.query === "string" ? args.query.trim() : "";
|
|
147
|
+
const entityTypes = Array.isArray(args.entityTypes)
|
|
148
|
+
? args.entityTypes.filter((entry) => typeof entry === "string" && entry.length > 0)
|
|
149
|
+
: [];
|
|
150
|
+
const limit = typeof args.limit === "number" && Number.isFinite(args.limit)
|
|
151
|
+
? args.limit
|
|
152
|
+
: 12;
|
|
153
|
+
return searchWorkbenchEntities(context, definition, {
|
|
154
|
+
query,
|
|
155
|
+
entityTypes,
|
|
156
|
+
limit
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
if (toolKey === "forge.update_task_status") {
|
|
160
|
+
const taskId = typeof args.taskId === "string" ? args.taskId : "";
|
|
161
|
+
const status = typeof args.status === "string" ? args.status : "";
|
|
162
|
+
if (!context.services.tasks.update) {
|
|
163
|
+
throw new Error("Task update service is not available.");
|
|
164
|
+
}
|
|
165
|
+
return context.services.tasks.update(taskId, { status });
|
|
166
|
+
}
|
|
167
|
+
if (toolKey === "forge.create_note") {
|
|
168
|
+
if (!context.services.notes.create) {
|
|
169
|
+
throw new Error("Note creation service is not available.");
|
|
170
|
+
}
|
|
171
|
+
return context.services.notes.create({
|
|
172
|
+
kind: "evidence",
|
|
173
|
+
title: typeof args.title === "string" ? args.title : "Workbench note",
|
|
174
|
+
contentMarkdown: typeof args.markdown === "string" ? args.markdown : "",
|
|
175
|
+
summary: typeof args.summary === "string" ? args.summary : "",
|
|
176
|
+
sourcePath: "workbench",
|
|
177
|
+
author: "Workbench"
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
throw new Error(`Unsupported Workbench tool: ${toolKey}`);
|
|
181
|
+
}
|
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
|
+
|
|
@@ -56,6 +56,8 @@ Entity conversation rule:
|
|
|
56
56
|
- Prefer a progression of:
|
|
57
57
|
concrete example or intent -> working name -> purpose or meaning -> placement in Forge -> operational details -> linked context.
|
|
58
58
|
- For emotionally meaningful non-Psyche records such as goals, habits, and notes, reflect the meaning before you ask for structure.
|
|
59
|
+
- When the user is vague, ask for one small concrete example, stake, or desired outcome before you ask them to name the record.
|
|
60
|
+
- When the user is clear, say what the record seems to be becoming and ask only for the last missing detail.
|
|
59
61
|
- When updating an entity, start with what is changing, what should stay true, and what prompted the update now.
|
|
60
62
|
- When enough is clear, briefly summarize what you heard in the user's own language before asking for the last missing structural detail.
|
|
61
63
|
- The quick intake prompts later in this file are fallback checkpoints, not a script to read aloud.
|
|
@@ -76,6 +78,7 @@ Psyche interview rule:
|
|
|
76
78
|
- Start from a recent concrete example before naming an abstract pattern, belief, or mode.
|
|
77
79
|
- Sound professionally warm and therapist-like: grounded, accurate, reflective, and intentional, not clinical, vague, or lecture-like.
|
|
78
80
|
- After the first real answer, choose one follow-up lane at a time: situation, sequence, meaning, protection, cost, longing/value, or tentative name.
|
|
81
|
+
- For Psyche updates, start with what feels newly true, newly visible, or newly inaccurate, then ask what should stay true before changing the formulation.
|
|
79
82
|
- If the user says they want help understanding a Psyche issue before saving it, ask one orienting question first instead of jumping straight into a full interpretation, diagnosis-like label, save suggestion, replacement belief, or suggested title.
|
|
80
83
|
- In that first exploratory turn, keep the reflection to one or two short sentences, avoid numbered lists or schema dumps, and wait for the user's answer before offering a fuller formulation.
|
|
81
84
|
- In that first exploratory turn, stay in plain prose, end with one question, and do not mention Forge fields or save formatting yet unless the user interrupts to save immediately.
|