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.
Files changed (189) hide show
  1. package/dist/assets/{board-VmF4FAfr.js → board-ta0rUHOf.js} +3 -3
  2. package/dist/assets/{board-VmF4FAfr.js.map → board-ta0rUHOf.js.map} +1 -1
  3. package/dist/assets/index-Ro0ZF_az.css +1 -0
  4. package/dist/assets/index-ytlpSj23.js +79 -0
  5. package/dist/assets/index-ytlpSj23.js.map +1 -0
  6. package/dist/assets/{motion-DvkU14p-.js → motion-fBKPB6yw.js} +2 -2
  7. package/dist/assets/{motion-DvkU14p-.js.map → motion-fBKPB6yw.js.map} +1 -1
  8. package/dist/assets/{table-DgiPof9E.js → table-C-IGTQni.js} +2 -2
  9. package/dist/assets/{table-DgiPof9E.js.map → table-C-IGTQni.js.map} +1 -1
  10. package/dist/assets/{ui-nYfoC0Gq.js → ui-DInOpaYF.js} +2 -2
  11. package/dist/assets/{ui-nYfoC0Gq.js.map → ui-DInOpaYF.js.map} +1 -1
  12. package/dist/assets/vendor-lE3tZJcC.js +876 -0
  13. package/dist/assets/vendor-lE3tZJcC.js.map +1 -0
  14. package/dist/index.html +7 -8
  15. package/dist/openclaw/local-runtime.d.ts +3 -1
  16. package/dist/openclaw/local-runtime.js +51 -15
  17. package/dist/openclaw/plugin-entry-shared.js +24 -2
  18. package/dist/openclaw/plugin-sdk-types.d.ts +17 -0
  19. package/dist/openclaw/tools.js +0 -3
  20. package/dist/server/server/migrations/001_core.sql +411 -0
  21. package/dist/server/server/migrations/002_psyche.sql +392 -0
  22. package/dist/server/server/migrations/003_habits.sql +30 -0
  23. package/dist/server/server/migrations/004_habit_links.sql +8 -0
  24. package/dist/server/server/migrations/005_habit_psyche_links.sql +24 -0
  25. package/dist/server/server/migrations/006_work_adjustments.sql +14 -0
  26. package/dist/server/server/migrations/007_weekly_review_closures.sql +17 -0
  27. package/dist/server/server/migrations/008_calendar_execution.sql +147 -0
  28. package/dist/server/server/migrations/009_true_calendar_events.sql +195 -0
  29. package/dist/server/server/migrations/010_calendar_selection_state.sql +6 -0
  30. package/dist/server/server/migrations/011_calendar_timezone_backfill.sql +11 -0
  31. package/dist/server/server/migrations/012_work_block_ranges.sql +7 -0
  32. package/dist/server/server/migrations/013_microsoft_local_auth_settings.sql +8 -0
  33. package/dist/server/server/migrations/014_note_tags_and_ephemeral.sql +8 -0
  34. package/dist/server/server/migrations/015_multi_user_and_strategies.sql +244 -0
  35. package/dist/server/server/migrations/016_health_companion.sql +158 -0
  36. package/dist/server/server/migrations/016_strategy_contracts_and_user_graph.sql +22 -0
  37. package/dist/server/server/migrations/017_preferences.sql +131 -0
  38. package/dist/server/server/migrations/018_preference_catalogs.sql +31 -0
  39. package/dist/server/server/migrations/019_wiki_memory.sql +255 -0
  40. package/dist/server/server/migrations/020_wiki_page_hierarchy.sql +11 -0
  41. package/dist/server/server/migrations/021_hide_evidence_from_wiki_index.sql +3 -0
  42. package/dist/server/server/migrations/022_wiki_ingest_background.sql +85 -0
  43. package/dist/server/server/migrations/023_diagnostic_logs.sql +28 -0
  44. package/dist/server/server/migrations/024_questionnaires.sql +96 -0
  45. package/dist/server/server/migrations/025_ai_model_connections.sql +26 -0
  46. package/dist/server/server/migrations/026_custom_theme_settings.sql +2 -0
  47. package/dist/server/server/migrations/027_ai_processors.sql +31 -0
  48. package/dist/server/server/migrations/028_movement_domain.sql +136 -0
  49. package/dist/server/server/migrations/029_watch_micro_capture.sql +23 -0
  50. package/dist/server/server/migrations/030_surface_layouts.sql +5 -0
  51. package/dist/server/server/migrations/031_ai_processor_runtime_upgrades.sql +10 -0
  52. package/dist/server/server/migrations/032_ai_connectors.sql +44 -0
  53. package/dist/server/server/migrations/033_movement_trip_point_sync.sql +36 -0
  54. package/dist/server/server/migrations/034_movement_segment_sync.sql +49 -0
  55. package/dist/server/server/migrations/035_google_local_auth_settings.sql +2 -0
  56. package/dist/server/server/migrations/036_google_local_auth_client_secret.sql +2 -0
  57. package/dist/server/{app.js → server/src/app.js} +242 -111
  58. package/dist/server/server/src/connectors/box-registry.js +188 -0
  59. package/dist/server/{db.js → server/src/db.js} +4 -0
  60. package/dist/server/server/src/debug.js +19 -0
  61. package/dist/server/{openapi.js → server/src/openapi.js} +2 -2
  62. package/dist/server/{repositories → server/src/repositories}/ai-connectors.js +286 -23
  63. package/dist/server/{repositories → server/src/repositories}/calendar.js +1 -1
  64. package/dist/server/{repositories → server/src/repositories}/settings.js +51 -3
  65. package/dist/server/{services → server/src/services}/calendar-runtime.js +775 -58
  66. package/dist/server/server/src/services/google-calendar-oauth-config.js +176 -0
  67. package/dist/server/{types.js → server/src/types.js} +137 -19
  68. package/dist/server/{web.js → server/src/web.js} +21 -2
  69. package/dist/server/src/components/customization/utility-widgets.js +330 -0
  70. package/dist/server/src/components/workbench-boxes/health/health-boxes.js +92 -0
  71. package/dist/server/src/components/workbench-boxes/kanban/kanban-boxes.js +128 -0
  72. package/dist/server/src/components/workbench-boxes/movement/movement-boxes.js +37 -0
  73. package/dist/server/src/components/workbench-boxes/notes/notes-boxes.js +114 -0
  74. package/dist/server/src/components/workbench-boxes/projects/projects-boxes.js +57 -0
  75. package/dist/server/src/components/workbench-boxes/shared/define-workbench-box.js +4 -0
  76. package/dist/server/src/components/workbench-boxes/shared/generic-node-view.js +13 -0
  77. package/dist/server/src/components/workbench-boxes/today/today-boxes.js +63 -0
  78. package/dist/server/src/lib/api-error.js +37 -0
  79. package/dist/server/src/lib/api.js +1859 -0
  80. package/dist/server/src/lib/calendar-name-deduper.js +144 -0
  81. package/dist/server/src/lib/diagnostics.js +67 -0
  82. package/dist/server/src/lib/psyche-types.js +1 -0
  83. package/dist/server/src/lib/questionnaire-types.js +1 -0
  84. package/dist/server/src/lib/runtime-paths.js +24 -0
  85. package/dist/server/src/lib/schemas.js +234 -0
  86. package/dist/server/src/lib/snapshot-normalizer.js +374 -0
  87. package/dist/server/src/lib/theme-system.js +319 -0
  88. package/dist/server/src/lib/types.js +1 -0
  89. package/dist/server/src/lib/utils.js +22 -0
  90. package/dist/server/src/lib/workbench/boxes.js +16 -0
  91. package/dist/server/src/lib/workbench/nodes.js +15 -0
  92. package/dist/server/src/lib/workbench/registry.js +73 -0
  93. package/dist/server/src/lib/workbench/runtime.js +181 -0
  94. package/openclaw.plugin.json +1 -1
  95. package/package.json +1 -1
  96. package/server/index.js +68 -0
  97. package/server/migrations/035_google_local_auth_settings.sql +2 -0
  98. package/server/migrations/036_google_local_auth_client_secret.sql +2 -0
  99. package/skills/forge-openclaw/SKILL.md +3 -0
  100. package/skills/forge-openclaw/entity_conversation_playbooks.md +213 -24
  101. package/skills/forge-openclaw/psyche_entity_playbooks.md +82 -3
  102. package/dist/assets/index-CFCKDIMH.js +0 -67
  103. package/dist/assets/index-CFCKDIMH.js.map +0 -1
  104. package/dist/assets/index-ZPY6U1TU.css +0 -1
  105. package/dist/assets/vendor-D9PTEPSB.js +0 -824
  106. package/dist/assets/vendor-D9PTEPSB.js.map +0 -1
  107. package/dist/assets/viz-Cqb6s--o.js +0 -34
  108. package/dist/assets/viz-Cqb6s--o.js.map +0 -1
  109. package/dist/server/connectors/box-registry.js +0 -257
  110. /package/dist/server/{demo-data.js → server/src/demo-data.js} +0 -0
  111. /package/dist/server/{discovery-advertiser.js → server/src/discovery-advertiser.js} +0 -0
  112. /package/dist/server/{e2e-server.js → server/src/e2e-server.js} +0 -0
  113. /package/dist/server/{errors.js → server/src/errors.js} +0 -0
  114. /package/dist/server/{health.js → server/src/health.js} +0 -0
  115. /package/dist/server/{index.js → server/src/index.js} +0 -0
  116. /package/dist/server/{managers → server/src/managers}/base.js +0 -0
  117. /package/dist/server/{managers → server/src/managers}/contracts.js +0 -0
  118. /package/dist/server/{managers → server/src/managers}/platform/api-gateway-manager.js +0 -0
  119. /package/dist/server/{managers → server/src/managers}/platform/audit-manager.js +0 -0
  120. /package/dist/server/{managers → server/src/managers}/platform/authentication-manager.js +0 -0
  121. /package/dist/server/{managers → server/src/managers}/platform/authorization-manager.js +0 -0
  122. /package/dist/server/{managers → server/src/managers}/platform/background-job-manager.js +0 -0
  123. /package/dist/server/{managers → server/src/managers}/platform/configuration-manager.js +0 -0
  124. /package/dist/server/{managers → server/src/managers}/platform/database-manager.js +0 -0
  125. /package/dist/server/{managers → server/src/managers}/platform/event-bus-manager.js +0 -0
  126. /package/dist/server/{managers → server/src/managers}/platform/external-service-manager.js +0 -0
  127. /package/dist/server/{managers → server/src/managers}/platform/health-manager.js +0 -0
  128. /package/dist/server/{managers → server/src/managers}/platform/llm-manager.js +0 -0
  129. /package/dist/server/{managers → server/src/managers}/platform/migration-manager.js +0 -0
  130. /package/dist/server/{managers → server/src/managers}/platform/openai-responses-provider.js +0 -0
  131. /package/dist/server/{managers → server/src/managers}/platform/search-index-manager.js +0 -0
  132. /package/dist/server/{managers → server/src/managers}/platform/secrets-manager.js +0 -0
  133. /package/dist/server/{managers → server/src/managers}/platform/session-manager.js +0 -0
  134. /package/dist/server/{managers → server/src/managers}/platform/storage-manager.js +0 -0
  135. /package/dist/server/{managers → server/src/managers}/platform/token-manager.js +0 -0
  136. /package/dist/server/{managers → server/src/managers}/platform/transaction-manager.js +0 -0
  137. /package/dist/server/{managers → server/src/managers}/platform/trusted-network.js +0 -0
  138. /package/dist/server/{managers → server/src/managers}/runtime.js +0 -0
  139. /package/dist/server/{managers → server/src/managers}/type-guards.js +0 -0
  140. /package/dist/server/{movement.js → server/src/movement.js} +0 -0
  141. /package/dist/server/{preferences-seeds.js → server/src/preferences-seeds.js} +0 -0
  142. /package/dist/server/{preferences-types.js → server/src/preferences-types.js} +0 -0
  143. /package/dist/server/{psyche-types.js → server/src/psyche-types.js} +0 -0
  144. /package/dist/server/{questionnaire-flow.js → server/src/questionnaire-flow.js} +0 -0
  145. /package/dist/server/{questionnaire-seeds.js → server/src/questionnaire-seeds.js} +0 -0
  146. /package/dist/server/{questionnaire-types.js → server/src/questionnaire-types.js} +0 -0
  147. /package/dist/server/{repositories → server/src/repositories}/activity-events.js +0 -0
  148. /package/dist/server/{repositories → server/src/repositories}/ai-processors.js +0 -0
  149. /package/dist/server/{repositories → server/src/repositories}/collaboration.js +0 -0
  150. /package/dist/server/{repositories → server/src/repositories}/deleted-entities.js +0 -0
  151. /package/dist/server/{repositories → server/src/repositories}/diagnostic-logs.js +0 -0
  152. /package/dist/server/{repositories → server/src/repositories}/domains.js +0 -0
  153. /package/dist/server/{repositories → server/src/repositories}/entity-ownership.js +0 -0
  154. /package/dist/server/{repositories → server/src/repositories}/event-log.js +0 -0
  155. /package/dist/server/{repositories → server/src/repositories}/goals.js +0 -0
  156. /package/dist/server/{repositories → server/src/repositories}/habits.js +0 -0
  157. /package/dist/server/{repositories → server/src/repositories}/model-settings.js +0 -0
  158. /package/dist/server/{repositories → server/src/repositories}/notes.js +0 -0
  159. /package/dist/server/{repositories → server/src/repositories}/preferences.js +0 -0
  160. /package/dist/server/{repositories → server/src/repositories}/projects.js +0 -0
  161. /package/dist/server/{repositories → server/src/repositories}/psyche.js +0 -0
  162. /package/dist/server/{repositories → server/src/repositories}/questionnaires.js +0 -0
  163. /package/dist/server/{repositories → server/src/repositories}/rewards.js +0 -0
  164. /package/dist/server/{repositories → server/src/repositories}/strategies.js +0 -0
  165. /package/dist/server/{repositories → server/src/repositories}/surface-layouts.js +0 -0
  166. /package/dist/server/{repositories → server/src/repositories}/tags.js +0 -0
  167. /package/dist/server/{repositories → server/src/repositories}/task-runs.js +0 -0
  168. /package/dist/server/{repositories → server/src/repositories}/tasks.js +0 -0
  169. /package/dist/server/{repositories → server/src/repositories}/users.js +0 -0
  170. /package/dist/server/{repositories → server/src/repositories}/weekly-reviews.js +0 -0
  171. /package/dist/server/{repositories → server/src/repositories}/wiki-memory.js +0 -0
  172. /package/dist/server/{repositories → server/src/repositories}/work-adjustments.js +0 -0
  173. /package/dist/server/{seed-demo.js → server/src/seed-demo.js} +0 -0
  174. /package/dist/server/{services → server/src/services}/context.js +0 -0
  175. /package/dist/server/{services → server/src/services}/dashboard.js +0 -0
  176. /package/dist/server/{services → server/src/services}/entity-crud.js +0 -0
  177. /package/dist/server/{services → server/src/services}/gamification.js +0 -0
  178. /package/dist/server/{services → server/src/services}/insights.js +0 -0
  179. /package/dist/server/{services → server/src/services}/openai-codex-oauth.js +0 -0
  180. /package/dist/server/{services → server/src/services}/projects.js +0 -0
  181. /package/dist/server/{services → server/src/services}/psyche-observation-calendar.js +0 -0
  182. /package/dist/server/{services → server/src/services}/psyche.js +0 -0
  183. /package/dist/server/{services → server/src/services}/relations.js +0 -0
  184. /package/dist/server/{services → server/src/services}/reviews.js +0 -0
  185. /package/dist/server/{services → server/src/services}/run-recovery.js +0 -0
  186. /package/dist/server/{services → server/src/services}/tagging.js +0 -0
  187. /package/dist/server/{services → server/src/services}/task-run-watchdog.js +0 -0
  188. /package/dist/server/{services → server/src/services}/work-time.js +0 -0
  189. /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
+ }
@@ -2,7 +2,7 @@
2
2
  "id": "forge-openclaw-plugin",
3
3
  "name": "Forge",
4
4
  "description": "Curated OpenClaw adapter for the Forge collaboration API, UI entrypoint, and localhost auto-start runtime.",
5
- "version": "0.2.25",
5
+ "version": "0.2.26",
6
6
  "skills": [
7
7
  "./skills"
8
8
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forge-openclaw-plugin",
3
- "version": "0.2.25",
3
+ "version": "0.2.26",
4
4
  "description": "Curated OpenClaw adapter for the Forge collaboration API, UI entrypoint, and localhost auto-start runtime.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -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,2 @@
1
+ ALTER TABLE app_settings
2
+ ADD COLUMN google_client_id TEXT NOT NULL DEFAULT '';
@@ -0,0 +1,2 @@
1
+ ALTER TABLE app_settings
2
+ ADD COLUMN google_client_secret TEXT NOT NULL DEFAULT '';
@@ -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.