forge-openclaw-plugin 0.2.24 → 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 (208) hide show
  1. package/README.md +13 -0
  2. package/dist/assets/{board-_C6oMy5w.js → board-ta0rUHOf.js} +3 -3
  3. package/dist/assets/{board-_C6oMy5w.js.map → board-ta0rUHOf.js.map} +1 -1
  4. package/dist/assets/index-Ro0ZF_az.css +1 -0
  5. package/dist/assets/index-ytlpSj23.js +79 -0
  6. package/dist/assets/index-ytlpSj23.js.map +1 -0
  7. package/dist/assets/{motion-D4sZgCHd.js → motion-fBKPB6yw.js} +3 -3
  8. package/dist/assets/motion-fBKPB6yw.js.map +1 -0
  9. package/dist/assets/{table-BWzTaky1.js → table-C-IGTQni.js} +2 -2
  10. package/dist/assets/{table-BWzTaky1.js.map → table-C-IGTQni.js.map} +1 -1
  11. package/dist/assets/{ui-BzK4azQb.js → ui-DInOpaYF.js} +2 -2
  12. package/dist/assets/{ui-BzK4azQb.js.map → ui-DInOpaYF.js.map} +1 -1
  13. package/dist/assets/vendor-lE3tZJcC.js +876 -0
  14. package/dist/assets/vendor-lE3tZJcC.js.map +1 -0
  15. package/dist/index.html +7 -8
  16. package/dist/openclaw/local-runtime.d.ts +3 -1
  17. package/dist/openclaw/local-runtime.js +51 -15
  18. package/dist/openclaw/parity.d.ts +1 -1
  19. package/dist/openclaw/parity.js +29 -0
  20. package/dist/openclaw/plugin-entry-shared.d.ts +1 -0
  21. package/dist/openclaw/plugin-entry-shared.js +31 -6
  22. package/dist/openclaw/plugin-sdk-types.d.ts +29 -0
  23. package/dist/openclaw/routes.js +236 -0
  24. package/dist/openclaw/session-bootstrap.d.ts +78 -0
  25. package/dist/openclaw/session-bootstrap.js +240 -0
  26. package/dist/openclaw/tools.js +279 -6
  27. package/dist/server/server/migrations/001_core.sql +411 -0
  28. package/dist/server/server/migrations/002_psyche.sql +392 -0
  29. package/dist/server/server/migrations/003_habits.sql +30 -0
  30. package/dist/server/server/migrations/004_habit_links.sql +8 -0
  31. package/dist/server/server/migrations/005_habit_psyche_links.sql +24 -0
  32. package/dist/server/server/migrations/006_work_adjustments.sql +14 -0
  33. package/dist/server/server/migrations/007_weekly_review_closures.sql +17 -0
  34. package/dist/server/server/migrations/008_calendar_execution.sql +147 -0
  35. package/dist/server/server/migrations/009_true_calendar_events.sql +195 -0
  36. package/dist/server/server/migrations/010_calendar_selection_state.sql +6 -0
  37. package/dist/server/server/migrations/011_calendar_timezone_backfill.sql +11 -0
  38. package/dist/server/server/migrations/012_work_block_ranges.sql +7 -0
  39. package/dist/server/server/migrations/013_microsoft_local_auth_settings.sql +8 -0
  40. package/dist/server/server/migrations/014_note_tags_and_ephemeral.sql +8 -0
  41. package/dist/server/server/migrations/015_multi_user_and_strategies.sql +244 -0
  42. package/dist/server/server/migrations/016_health_companion.sql +158 -0
  43. package/dist/server/server/migrations/016_strategy_contracts_and_user_graph.sql +22 -0
  44. package/dist/server/server/migrations/017_preferences.sql +131 -0
  45. package/dist/server/server/migrations/018_preference_catalogs.sql +31 -0
  46. package/dist/server/server/migrations/019_wiki_memory.sql +255 -0
  47. package/dist/server/server/migrations/020_wiki_page_hierarchy.sql +11 -0
  48. package/dist/server/server/migrations/021_hide_evidence_from_wiki_index.sql +3 -0
  49. package/dist/server/server/migrations/022_wiki_ingest_background.sql +85 -0
  50. package/dist/server/server/migrations/023_diagnostic_logs.sql +28 -0
  51. package/dist/server/server/migrations/024_questionnaires.sql +96 -0
  52. package/dist/server/server/migrations/025_ai_model_connections.sql +26 -0
  53. package/dist/server/server/migrations/026_custom_theme_settings.sql +2 -0
  54. package/dist/server/server/migrations/027_ai_processors.sql +31 -0
  55. package/dist/server/server/migrations/028_movement_domain.sql +136 -0
  56. package/dist/server/server/migrations/029_watch_micro_capture.sql +23 -0
  57. package/dist/server/server/migrations/030_surface_layouts.sql +5 -0
  58. package/dist/server/server/migrations/031_ai_processor_runtime_upgrades.sql +10 -0
  59. package/dist/server/server/migrations/032_ai_connectors.sql +44 -0
  60. package/dist/server/server/migrations/033_movement_trip_point_sync.sql +36 -0
  61. package/dist/server/server/migrations/034_movement_segment_sync.sql +49 -0
  62. package/dist/server/server/migrations/035_google_local_auth_settings.sql +2 -0
  63. package/dist/server/server/migrations/036_google_local_auth_client_secret.sql +2 -0
  64. package/dist/server/{app.js → server/src/app.js} +992 -25
  65. package/dist/server/server/src/connectors/box-registry.js +188 -0
  66. package/dist/server/{db.js → server/src/db.js} +6 -0
  67. package/dist/server/server/src/debug.js +19 -0
  68. package/dist/server/server/src/discovery-advertiser.js +114 -0
  69. package/dist/server/{health.js → server/src/health.js} +39 -11
  70. package/dist/server/{index.js → server/src/index.js} +4 -0
  71. package/dist/server/{managers → server/src/managers}/platform/llm-manager.js +40 -4
  72. package/dist/server/{managers → server/src/managers}/platform/openai-responses-provider.js +129 -19
  73. package/dist/server/server/src/movement.js +2935 -0
  74. package/dist/server/{openapi.js → server/src/openapi.js} +628 -5
  75. package/dist/server/{psyche-types.js → server/src/psyche-types.js} +15 -1
  76. package/dist/server/server/src/questionnaire-flow.js +552 -0
  77. package/dist/server/server/src/questionnaire-seeds.js +853 -0
  78. package/dist/server/server/src/questionnaire-types.js +340 -0
  79. package/dist/server/server/src/repositories/ai-connectors.js +1207 -0
  80. package/dist/server/server/src/repositories/ai-processors.js +547 -0
  81. package/dist/server/{repositories → server/src/repositories}/calendar.js +1 -1
  82. package/dist/server/{repositories → server/src/repositories}/entity-ownership.js +9 -1
  83. package/dist/server/{repositories → server/src/repositories}/habits.js +69 -5
  84. package/dist/server/server/src/repositories/model-settings.js +216 -0
  85. package/dist/server/{repositories → server/src/repositories}/notes.js +57 -15
  86. package/dist/server/{repositories → server/src/repositories}/preferences.js +124 -0
  87. package/dist/server/server/src/repositories/questionnaires.js +1338 -0
  88. package/dist/server/{repositories → server/src/repositories}/settings.js +156 -12
  89. package/dist/server/server/src/repositories/surface-layouts.js +76 -0
  90. package/dist/server/{repositories → server/src/repositories}/wiki-memory.js +5 -1
  91. package/dist/server/{services → server/src/services}/calendar-runtime.js +775 -58
  92. package/dist/server/{services → server/src/services}/entity-crud.js +81 -2
  93. package/dist/server/server/src/services/google-calendar-oauth-config.js +176 -0
  94. package/dist/server/server/src/services/openai-codex-oauth.js +153 -0
  95. package/dist/server/server/src/services/psyche-observation-calendar.js +46 -0
  96. package/dist/server/{types.js → server/src/types.js} +621 -14
  97. package/dist/server/server/src/watch-mobile.js +562 -0
  98. package/dist/server/{web.js → server/src/web.js} +30 -4
  99. package/dist/server/src/components/customization/utility-widgets.js +330 -0
  100. package/dist/server/src/components/workbench-boxes/health/health-boxes.js +92 -0
  101. package/dist/server/src/components/workbench-boxes/kanban/kanban-boxes.js +128 -0
  102. package/dist/server/src/components/workbench-boxes/movement/movement-boxes.js +37 -0
  103. package/dist/server/src/components/workbench-boxes/notes/notes-boxes.js +114 -0
  104. package/dist/server/src/components/workbench-boxes/projects/projects-boxes.js +57 -0
  105. package/dist/server/src/components/workbench-boxes/shared/define-workbench-box.js +4 -0
  106. package/dist/server/src/components/workbench-boxes/shared/generic-node-view.js +13 -0
  107. package/dist/server/src/components/workbench-boxes/today/today-boxes.js +63 -0
  108. package/dist/server/src/lib/api-error.js +37 -0
  109. package/dist/server/src/lib/api.js +1859 -0
  110. package/dist/server/src/lib/calendar-name-deduper.js +144 -0
  111. package/dist/server/src/lib/diagnostics.js +67 -0
  112. package/dist/server/src/lib/psyche-types.js +1 -0
  113. package/dist/server/src/lib/questionnaire-types.js +1 -0
  114. package/dist/server/src/lib/runtime-paths.js +24 -0
  115. package/dist/server/src/lib/schemas.js +234 -0
  116. package/dist/server/src/lib/snapshot-normalizer.js +374 -0
  117. package/dist/server/src/lib/theme-system.js +319 -0
  118. package/dist/server/src/lib/types.js +1 -0
  119. package/dist/server/src/lib/utils.js +22 -0
  120. package/dist/server/src/lib/workbench/boxes.js +16 -0
  121. package/dist/server/src/lib/workbench/nodes.js +15 -0
  122. package/dist/server/src/lib/workbench/registry.js +73 -0
  123. package/dist/server/src/lib/workbench/runtime.js +181 -0
  124. package/openclaw.plugin.json +1 -1
  125. package/package.json +6 -1
  126. package/server/index.js +68 -0
  127. package/server/migrations/024_questionnaires.sql +96 -0
  128. package/server/migrations/025_ai_model_connections.sql +26 -0
  129. package/server/migrations/026_custom_theme_settings.sql +2 -0
  130. package/server/migrations/027_ai_processors.sql +31 -0
  131. package/server/migrations/028_movement_domain.sql +136 -0
  132. package/server/migrations/029_watch_micro_capture.sql +23 -0
  133. package/server/migrations/030_surface_layouts.sql +5 -0
  134. package/server/migrations/031_ai_processor_runtime_upgrades.sql +10 -0
  135. package/server/migrations/032_ai_connectors.sql +44 -0
  136. package/server/migrations/033_movement_trip_point_sync.sql +36 -0
  137. package/server/migrations/034_movement_segment_sync.sql +49 -0
  138. package/server/migrations/035_google_local_auth_settings.sql +2 -0
  139. package/server/migrations/036_google_local_auth_client_secret.sql +2 -0
  140. package/skills/forge-openclaw/SKILL.md +15 -1
  141. package/skills/forge-openclaw/entity_conversation_playbooks.md +523 -87
  142. package/skills/forge-openclaw/psyche_entity_playbooks.md +331 -221
  143. package/dist/assets/index-DTCwBWAs.js +0 -65
  144. package/dist/assets/index-DTCwBWAs.js.map +0 -1
  145. package/dist/assets/index-DttXlAgi.css +0 -1
  146. package/dist/assets/motion-D4sZgCHd.js.map +0 -1
  147. package/dist/assets/vendor-De38P6YR.js +0 -729
  148. package/dist/assets/vendor-De38P6YR.js.map +0 -1
  149. package/dist/assets/viz-C6hfyqzu.js +0 -34
  150. package/dist/assets/viz-C6hfyqzu.js.map +0 -1
  151. package/skills/forge-openclaw/cron_jobs.md +0 -395
  152. /package/dist/server/{demo-data.js → server/src/demo-data.js} +0 -0
  153. /package/dist/server/{e2e-server.js → server/src/e2e-server.js} +0 -0
  154. /package/dist/server/{errors.js → server/src/errors.js} +0 -0
  155. /package/dist/server/{managers → server/src/managers}/base.js +0 -0
  156. /package/dist/server/{managers → server/src/managers}/contracts.js +0 -0
  157. /package/dist/server/{managers → server/src/managers}/platform/api-gateway-manager.js +0 -0
  158. /package/dist/server/{managers → server/src/managers}/platform/audit-manager.js +0 -0
  159. /package/dist/server/{managers → server/src/managers}/platform/authentication-manager.js +0 -0
  160. /package/dist/server/{managers → server/src/managers}/platform/authorization-manager.js +0 -0
  161. /package/dist/server/{managers → server/src/managers}/platform/background-job-manager.js +0 -0
  162. /package/dist/server/{managers → server/src/managers}/platform/configuration-manager.js +0 -0
  163. /package/dist/server/{managers → server/src/managers}/platform/database-manager.js +0 -0
  164. /package/dist/server/{managers → server/src/managers}/platform/event-bus-manager.js +0 -0
  165. /package/dist/server/{managers → server/src/managers}/platform/external-service-manager.js +0 -0
  166. /package/dist/server/{managers → server/src/managers}/platform/health-manager.js +0 -0
  167. /package/dist/server/{managers → server/src/managers}/platform/migration-manager.js +0 -0
  168. /package/dist/server/{managers → server/src/managers}/platform/search-index-manager.js +0 -0
  169. /package/dist/server/{managers → server/src/managers}/platform/secrets-manager.js +0 -0
  170. /package/dist/server/{managers → server/src/managers}/platform/session-manager.js +0 -0
  171. /package/dist/server/{managers → server/src/managers}/platform/storage-manager.js +0 -0
  172. /package/dist/server/{managers → server/src/managers}/platform/token-manager.js +0 -0
  173. /package/dist/server/{managers → server/src/managers}/platform/transaction-manager.js +0 -0
  174. /package/dist/server/{managers → server/src/managers}/platform/trusted-network.js +0 -0
  175. /package/dist/server/{managers → server/src/managers}/runtime.js +0 -0
  176. /package/dist/server/{managers → server/src/managers}/type-guards.js +0 -0
  177. /package/dist/server/{preferences-seeds.js → server/src/preferences-seeds.js} +0 -0
  178. /package/dist/server/{preferences-types.js → server/src/preferences-types.js} +0 -0
  179. /package/dist/server/{repositories → server/src/repositories}/activity-events.js +0 -0
  180. /package/dist/server/{repositories → server/src/repositories}/collaboration.js +0 -0
  181. /package/dist/server/{repositories → server/src/repositories}/deleted-entities.js +0 -0
  182. /package/dist/server/{repositories → server/src/repositories}/diagnostic-logs.js +0 -0
  183. /package/dist/server/{repositories → server/src/repositories}/domains.js +0 -0
  184. /package/dist/server/{repositories → server/src/repositories}/event-log.js +0 -0
  185. /package/dist/server/{repositories → server/src/repositories}/goals.js +0 -0
  186. /package/dist/server/{repositories → server/src/repositories}/projects.js +0 -0
  187. /package/dist/server/{repositories → server/src/repositories}/psyche.js +0 -0
  188. /package/dist/server/{repositories → server/src/repositories}/rewards.js +0 -0
  189. /package/dist/server/{repositories → server/src/repositories}/strategies.js +0 -0
  190. /package/dist/server/{repositories → server/src/repositories}/tags.js +0 -0
  191. /package/dist/server/{repositories → server/src/repositories}/task-runs.js +0 -0
  192. /package/dist/server/{repositories → server/src/repositories}/tasks.js +0 -0
  193. /package/dist/server/{repositories → server/src/repositories}/users.js +0 -0
  194. /package/dist/server/{repositories → server/src/repositories}/weekly-reviews.js +0 -0
  195. /package/dist/server/{repositories → server/src/repositories}/work-adjustments.js +0 -0
  196. /package/dist/server/{seed-demo.js → server/src/seed-demo.js} +0 -0
  197. /package/dist/server/{services → server/src/services}/context.js +0 -0
  198. /package/dist/server/{services → server/src/services}/dashboard.js +0 -0
  199. /package/dist/server/{services → server/src/services}/gamification.js +0 -0
  200. /package/dist/server/{services → server/src/services}/insights.js +0 -0
  201. /package/dist/server/{services → server/src/services}/projects.js +0 -0
  202. /package/dist/server/{services → server/src/services}/psyche.js +0 -0
  203. /package/dist/server/{services → server/src/services}/relations.js +0 -0
  204. /package/dist/server/{services → server/src/services}/reviews.js +0 -0
  205. /package/dist/server/{services → server/src/services}/run-recovery.js +0 -0
  206. /package/dist/server/{services → server/src/services}/tagging.js +0 -0
  207. /package/dist/server/{services → server/src/services}/task-run-watchdog.js +0 -0
  208. /package/dist/server/{services → server/src/services}/work-time.js +0 -0
@@ -0,0 +1,144 @@
1
+ function normalizeNameKey(value) {
2
+ return value.trim().replace(/\s+/g, " ").toLocaleLowerCase();
3
+ }
4
+ function cleanLabel(value) {
5
+ const trimmed = value?.trim();
6
+ return trimmed ? trimmed : null;
7
+ }
8
+ function readBaseCalendarName(value) {
9
+ return cleanLabel(value) ?? "Unnamed calendar";
10
+ }
11
+ function shortCalendarProviderLabel(provider) {
12
+ switch (provider) {
13
+ case "google":
14
+ return "Google";
15
+ case "apple":
16
+ return "Apple";
17
+ case "microsoft":
18
+ return "Microsoft";
19
+ case "caldav":
20
+ default:
21
+ return "CalDAV";
22
+ }
23
+ }
24
+ function readUrlQualifier(value) {
25
+ const trimmed = cleanLabel(value);
26
+ if (!trimmed) {
27
+ return null;
28
+ }
29
+ try {
30
+ const url = new URL(trimmed);
31
+ const segments = url.pathname
32
+ .split("/")
33
+ .map((segment) => segment.trim())
34
+ .filter(Boolean);
35
+ const lastSegment = segments.at(-1);
36
+ if (lastSegment) {
37
+ return `${url.host}/${decodeURIComponent(lastSegment)}`;
38
+ }
39
+ return url.host;
40
+ }
41
+ catch {
42
+ return trimmed;
43
+ }
44
+ }
45
+ function joinQualifier(parts) {
46
+ const cleaned = parts
47
+ .map(cleanLabel)
48
+ .filter((part) => Boolean(part));
49
+ return cleaned.length > 0 ? cleaned.join(" · ") : null;
50
+ }
51
+ function selectUniqueQualifier(group) {
52
+ const selectors = [
53
+ (entry) => entry.providerLabel,
54
+ (entry) => joinQualifier([entry.providerLabel, entry.accountLabel]),
55
+ (entry) => joinQualifier([entry.providerLabel, entry.connectionLabel]),
56
+ (entry) => entry.connectionLabel,
57
+ (entry) => entry.accountLabel,
58
+ (entry) => readUrlQualifier(entry.url),
59
+ (entry) => entry.url
60
+ ];
61
+ for (const select of selectors) {
62
+ const qualifiers = group.map(select);
63
+ if (qualifiers.some((qualifier) => !cleanLabel(qualifier))) {
64
+ continue;
65
+ }
66
+ const normalized = qualifiers.map((qualifier) => normalizeNameKey(qualifier));
67
+ if (new Set(normalized).size === group.length) {
68
+ return qualifiers;
69
+ }
70
+ }
71
+ return group.map((entry, index) => joinQualifier([entry.providerLabel, `${index + 1}`]) ?? `${index + 1}`);
72
+ }
73
+ function buildDedupedNameMap(entries) {
74
+ const deduped = new Map();
75
+ const groups = new Map();
76
+ for (const entry of entries) {
77
+ const key = normalizeNameKey(entry.baseName);
78
+ const bucket = groups.get(key) ?? [];
79
+ bucket.push(entry);
80
+ groups.set(key, bucket);
81
+ }
82
+ for (const group of groups.values()) {
83
+ if (group.length === 1) {
84
+ deduped.set(group[0].id, group[0].baseName);
85
+ continue;
86
+ }
87
+ const qualifiers = selectUniqueQualifier(group);
88
+ group.forEach((entry, index) => {
89
+ deduped.set(entry.id, `${entry.baseName} (${qualifiers[index]})`);
90
+ });
91
+ }
92
+ return deduped;
93
+ }
94
+ export function dedupeCalendarDiscoveryPayload(payload) {
95
+ const dedupedNames = buildDedupedNameMap(payload.calendars.map((calendar) => ({
96
+ id: calendar.url,
97
+ baseName: readBaseCalendarName(calendar.displayName),
98
+ providerLabel: shortCalendarProviderLabel(payload.provider),
99
+ connectionLabel: null,
100
+ accountLabel: payload.accountLabel,
101
+ url: calendar.url
102
+ })));
103
+ return {
104
+ ...payload,
105
+ calendars: payload.calendars.map((calendar) => ({
106
+ ...calendar,
107
+ dedupedName: dedupedNames.get(calendar.url) ??
108
+ readBaseCalendarName(calendar.displayName)
109
+ }))
110
+ };
111
+ }
112
+ export function dedupeCalendarResourcesWithConnections(calendars, connections) {
113
+ const connectionsById = new Map(connections.map((connection) => [connection.id, connection]));
114
+ const dedupedNames = buildDedupedNameMap(calendars.map((calendar) => {
115
+ const connection = connectionsById.get(calendar.connectionId);
116
+ return {
117
+ id: calendar.id,
118
+ baseName: readBaseCalendarName(calendar.title),
119
+ providerLabel: connection
120
+ ? shortCalendarProviderLabel(connection.provider)
121
+ : null,
122
+ connectionLabel: connection?.label ?? null,
123
+ accountLabel: connection?.accountLabel ?? null,
124
+ url: calendar.remoteId
125
+ };
126
+ }));
127
+ return calendars.map((calendar) => ({
128
+ ...calendar,
129
+ dedupedName: dedupedNames.get(calendar.id) ?? readBaseCalendarName(calendar.title)
130
+ }));
131
+ }
132
+ export function dedupeCalendarOverviewPayload(payload) {
133
+ return {
134
+ ...payload,
135
+ calendars: dedupeCalendarResourcesWithConnections(payload.calendars, payload.connections)
136
+ };
137
+ }
138
+ export function readCalendarDisplayName(calendar) {
139
+ if ("title" in calendar) {
140
+ return (cleanLabel(calendar.dedupedName) ?? readBaseCalendarName(calendar.title));
141
+ }
142
+ return (cleanLabel(calendar.dedupedName) ??
143
+ readBaseCalendarName(calendar.displayName));
144
+ }
@@ -0,0 +1,67 @@
1
+ import { resolveForgePath } from "./runtime-paths.js";
2
+ function sanitizeValue(value, depth = 0) {
3
+ if (value === null ||
4
+ typeof value === "boolean" ||
5
+ typeof value === "number" ||
6
+ typeof value === "string") {
7
+ return value;
8
+ }
9
+ if (typeof value === "bigint") {
10
+ return value.toString();
11
+ }
12
+ if (value instanceof Error) {
13
+ return {
14
+ name: value.name,
15
+ message: value.message,
16
+ stack: value.stack ?? null
17
+ };
18
+ }
19
+ if (Array.isArray(value)) {
20
+ if (depth >= 3) {
21
+ return `[Array(${value.length})]`;
22
+ }
23
+ return value.slice(0, 20).map((entry) => sanitizeValue(entry, depth + 1));
24
+ }
25
+ if (value && typeof value === "object") {
26
+ if (depth >= 3) {
27
+ return "[Object]";
28
+ }
29
+ return Object.fromEntries(Object.entries(value)
30
+ .slice(0, 30)
31
+ .map(([key, entry]) => [key, sanitizeValue(entry, depth + 1)]));
32
+ }
33
+ return String(value);
34
+ }
35
+ function sanitizeDetails(details) {
36
+ if (!details) {
37
+ return {};
38
+ }
39
+ return Object.fromEntries(Object.entries(details).map(([key, value]) => [key, sanitizeValue(value)]));
40
+ }
41
+ export async function publishUiDiagnosticLog(input) {
42
+ try {
43
+ await fetch(resolveForgePath("/api/v1/diagnostics/logs"), {
44
+ method: "POST",
45
+ credentials: "same-origin",
46
+ keepalive: true,
47
+ headers: {
48
+ "content-type": "application/json",
49
+ "x-forge-source": "ui"
50
+ },
51
+ body: JSON.stringify({
52
+ ...input,
53
+ source: input.source ?? "ui",
54
+ details: sanitizeDetails(input.details)
55
+ })
56
+ });
57
+ }
58
+ catch {
59
+ // Diagnostics should never break the user flow.
60
+ }
61
+ }
62
+ export function createUiDiagnosticLogger(defaults) {
63
+ return (input) => publishUiDiagnosticLog({
64
+ ...defaults,
65
+ ...input
66
+ });
67
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,24 @@
1
+ export function normalizeAssetBasePath(basePath) {
2
+ if (!basePath || basePath === "/") {
3
+ return "/";
4
+ }
5
+ const withLeadingSlash = basePath.startsWith("/") ? basePath : `/${basePath}`;
6
+ return withLeadingSlash.endsWith("/") ? withLeadingSlash : `${withLeadingSlash}/`;
7
+ }
8
+ export function normalizeRouterBasename(basePath) {
9
+ const normalized = normalizeAssetBasePath(basePath);
10
+ if (normalized === "/") {
11
+ return "/";
12
+ }
13
+ return normalized.endsWith("/") ? normalized.slice(0, -1) : normalized;
14
+ }
15
+ function getBaseUrl() {
16
+ return new URL(normalizeAssetBasePath(import.meta.env.BASE_URL || "/"), window.location.origin);
17
+ }
18
+ export function resolveForgePath(pathname) {
19
+ if (pathname.startsWith("/api/")) {
20
+ return pathname;
21
+ }
22
+ const normalized = pathname.startsWith("/") ? pathname.slice(1) : pathname;
23
+ return new URL(normalized, getBaseUrl()).pathname;
24
+ }
@@ -0,0 +1,234 @@
1
+ import { z } from "zod";
2
+ import { forgeCustomThemeSchema, forgeThemePreferenceSchema } from "@/lib/theme-system";
3
+ export const appLocaleSchema = z.enum(["en", "fr"]);
4
+ export const inlineCreateNoteSchema = z.object({
5
+ contentMarkdown: z.string().trim().min(1, "Note content is required"),
6
+ author: z.string().trim()
7
+ });
8
+ export const goalMutationSchema = z.object({
9
+ title: z.string().trim().min(1, "Title is required"),
10
+ description: z.string().trim(),
11
+ horizon: z.enum(["quarter", "year", "lifetime"]),
12
+ status: z.enum(["active", "paused", "completed"]),
13
+ userId: z.string().trim().nullable().optional(),
14
+ targetPoints: z.coerce.number().int().min(25).max(10000),
15
+ themeColor: z
16
+ .string()
17
+ .trim()
18
+ .regex(/^#[0-9a-fA-F]{6}$/, "Theme color must be a valid hex value"),
19
+ tagIds: z.array(z.string()),
20
+ notes: z.array(inlineCreateNoteSchema)
21
+ });
22
+ export const projectMutationSchema = z.object({
23
+ goalId: z.string().trim().min(1, "Life goal is required"),
24
+ title: z.string().trim().min(1, "Title is required"),
25
+ description: z.string().trim(),
26
+ status: z.enum(["active", "paused", "completed"]),
27
+ userId: z.string().trim().nullable().optional(),
28
+ targetPoints: z.coerce.number().int().min(25).max(10000),
29
+ themeColor: z
30
+ .string()
31
+ .trim()
32
+ .regex(/^#[0-9a-fA-F]{6}$/, "Theme color must be a valid hex value"),
33
+ notes: z.array(inlineCreateNoteSchema)
34
+ });
35
+ export const settingsMutationSchema = z.object({
36
+ profile: z.object({
37
+ operatorName: z.string().trim().min(1, "Name is required"),
38
+ operatorEmail: z.string().trim().min(1, "Email is required"),
39
+ operatorTitle: z.string().trim().min(1, "Title is required")
40
+ }),
41
+ notifications: z.object({
42
+ goalDriftAlerts: z.boolean(),
43
+ dailyQuestReminders: z.boolean(),
44
+ achievementCelebrations: z.boolean()
45
+ }),
46
+ execution: z.object({
47
+ maxActiveTasks: z.coerce.number().int().min(1).max(8),
48
+ timeAccountingMode: z.enum(["split", "parallel", "primary_only"])
49
+ }),
50
+ themePreference: forgeThemePreferenceSchema,
51
+ customTheme: forgeCustomThemeSchema.nullable().optional(),
52
+ localePreference: appLocaleSchema,
53
+ calendarProviders: z
54
+ .object({
55
+ google: z
56
+ .object({
57
+ clientId: z.string().trim().optional(),
58
+ clientSecret: z.string().trim().optional(),
59
+ storedClientId: z.string().optional(),
60
+ storedClientSecret: z.string().optional(),
61
+ appBaseUrl: z.string().optional(),
62
+ redirectUri: z.string().optional(),
63
+ allowedOrigins: z.array(z.string()).optional(),
64
+ usesPkce: z.literal(true).optional(),
65
+ requiresServerClientSecret: z.literal(false).optional(),
66
+ oauthClientType: z.literal("desktop_app").optional(),
67
+ authMode: z.literal("localhost_pkce").optional(),
68
+ isConfigured: z.boolean().optional(),
69
+ isReadyForPairing: z.boolean().optional(),
70
+ isLocalOnly: z.literal(true).optional(),
71
+ runtimeOrigin: z.string().optional(),
72
+ setupMessage: z.string().optional()
73
+ })
74
+ .optional(),
75
+ microsoft: z
76
+ .object({
77
+ clientId: z.string().trim(),
78
+ tenantId: z.string().trim(),
79
+ redirectUri: z.string().trim()
80
+ })
81
+ .optional()
82
+ })
83
+ .optional()
84
+ .superRefine((value, context) => {
85
+ const google = value?.google;
86
+ if (!google) {
87
+ return;
88
+ }
89
+ const hasClientIdField = google.clientId !== undefined;
90
+ const hasClientSecretField = google.clientSecret !== undefined;
91
+ const hasClientIdValue = (google.clientId?.length ?? 0) > 0;
92
+ const hasClientSecretValue = (google.clientSecret?.length ?? 0) > 0;
93
+ if (hasClientIdField !== hasClientSecretField) {
94
+ context.addIssue({
95
+ code: z.ZodIssueCode.custom,
96
+ path: ["google", hasClientIdField ? "clientSecret" : "clientId"],
97
+ message: "Provide both the Google client ID and client secret together, or clear both together."
98
+ });
99
+ return;
100
+ }
101
+ if (hasClientIdValue !== hasClientSecretValue) {
102
+ context.addIssue({
103
+ code: z.ZodIssueCode.custom,
104
+ path: ["google", hasClientIdValue ? "clientSecret" : "clientId"],
105
+ message: "Provide both the Google client ID and client secret together, or clear both together."
106
+ });
107
+ }
108
+ }),
109
+ modelSettings: z
110
+ .object({
111
+ forgeAgent: z
112
+ .object({
113
+ basicChat: z
114
+ .object({
115
+ connectionId: z.string().trim().nullable().optional(),
116
+ model: z.string().trim().optional()
117
+ })
118
+ .optional(),
119
+ wiki: z
120
+ .object({
121
+ connectionId: z.string().trim().nullable().optional(),
122
+ model: z.string().trim().optional()
123
+ })
124
+ .optional()
125
+ })
126
+ .optional()
127
+ })
128
+ .optional()
129
+ });
130
+ export const createAgentTokenSchema = z.object({
131
+ label: z.string().trim().min(1, "Label is required"),
132
+ agentLabel: z.string().trim().min(1, "Agent name is required"),
133
+ agentType: z.string().trim().min(1, "Agent type is required"),
134
+ description: z.string().trim(),
135
+ trustLevel: z.enum(["standard", "trusted", "autonomous"]),
136
+ autonomyMode: z.enum(["approval_required", "scoped_write", "autonomous"]),
137
+ approvalMode: z.enum(["approval_by_default", "high_impact_only", "none"]),
138
+ scopes: z.array(z.string().trim().min(1)).min(1)
139
+ });
140
+ export const createInsightSchema = z.object({
141
+ originType: z.enum(["system", "user", "agent"]),
142
+ originAgentId: z.string().trim(),
143
+ originLabel: z.string().trim(),
144
+ entityType: z.string().trim(),
145
+ entityId: z.string().trim(),
146
+ timeframeLabel: z.string().trim(),
147
+ title: z.string().trim().min(1, "Title is required"),
148
+ summary: z.string().trim().min(1, "Summary is required"),
149
+ recommendation: z.string().trim().min(1, "Recommendation is required"),
150
+ rationale: z.string().trim(),
151
+ confidence: z.coerce.number().min(0).max(1),
152
+ ctaLabel: z.string().trim().min(1, "CTA label is required")
153
+ });
154
+ export const quickTaskSchema = z.object({
155
+ title: z.string().trim().min(1, "Title is required"),
156
+ description: z.string().trim(),
157
+ owner: z.string().trim().min(1, "Owner is required"),
158
+ userId: z.string().trim().nullable().optional(),
159
+ goalId: z.string().trim(),
160
+ projectId: z.string().trim().min(1, "Project is required"),
161
+ priority: z.enum(["low", "medium", "high", "critical"]),
162
+ status: z.enum(["backlog", "focus", "in_progress", "blocked", "done"]),
163
+ effort: z.enum(["light", "deep", "marathon"]),
164
+ energy: z.enum(["low", "steady", "high"]),
165
+ dueDate: z.string().trim(),
166
+ points: z.coerce.number().int().min(5).max(500),
167
+ tagIds: z.array(z.string()),
168
+ notes: z.array(inlineCreateNoteSchema)
169
+ });
170
+ export const habitMutationSchema = z
171
+ .object({
172
+ title: z.string().trim().min(1, "Title is required"),
173
+ description: z.string().trim(),
174
+ status: z.enum(["active", "paused", "archived"]),
175
+ userId: z.string().trim().nullable().optional(),
176
+ polarity: z.enum(["positive", "negative"]),
177
+ frequency: z.enum(["daily", "weekly"]),
178
+ targetCount: z.coerce.number().int().min(1).max(14),
179
+ weekDays: z.array(z.number().int().min(0).max(6)).max(7),
180
+ linkedGoalIds: z.array(z.string().trim().min(1)),
181
+ linkedProjectIds: z.array(z.string().trim().min(1)),
182
+ linkedTaskIds: z.array(z.string().trim().min(1)),
183
+ linkedValueIds: z.array(z.string().trim().min(1)),
184
+ linkedPatternIds: z.array(z.string().trim().min(1)),
185
+ linkedBehaviorIds: z.array(z.string().trim().min(1)),
186
+ linkedBeliefIds: z.array(z.string().trim().min(1)),
187
+ linkedModeIds: z.array(z.string().trim().min(1)),
188
+ linkedReportIds: z.array(z.string().trim().min(1)),
189
+ linkedBehaviorId: z.string().trim(),
190
+ rewardXp: z.coerce.number().int().min(1).max(100),
191
+ penaltyXp: z.coerce.number().int().min(1).max(100),
192
+ generatedHealthEventTemplate: z.object({
193
+ enabled: z.boolean(),
194
+ workoutType: z.string().trim(),
195
+ title: z.string().trim(),
196
+ durationMinutes: z.coerce.number().int().min(1).max(24 * 60),
197
+ xpReward: z.coerce.number().int().min(0).max(500),
198
+ tags: z.array(z.string().trim()),
199
+ links: z.array(z.object({
200
+ entityType: z.string().trim().min(1),
201
+ entityId: z.string().trim().min(1),
202
+ relationshipType: z.string().trim().default("context")
203
+ })),
204
+ notesTemplate: z.string().trim()
205
+ })
206
+ })
207
+ .superRefine((value, context) => {
208
+ if (value.frequency === "weekly" && value.weekDays.length === 0) {
209
+ context.addIssue({
210
+ code: z.ZodIssueCode.custom,
211
+ path: ["weekDays"],
212
+ message: "Pick at least one weekday"
213
+ });
214
+ }
215
+ });
216
+ export const workAdjustmentMutationSchema = z.object({
217
+ entityType: z.enum(["task", "project"]),
218
+ entityId: z.string().trim().min(1, "A target is required"),
219
+ deltaMinutes: z.coerce
220
+ .number()
221
+ .int()
222
+ .refine((value) => value !== 0, "Minutes must not be zero"),
223
+ note: z.string().trim()
224
+ });
225
+ export const tagMutationSchema = z.object({
226
+ name: z.string().trim().min(1, "Name is required"),
227
+ kind: z.enum(["value", "category", "execution"]),
228
+ userId: z.string().trim().nullable().optional(),
229
+ color: z
230
+ .string()
231
+ .trim()
232
+ .regex(/^#[0-9a-fA-F]{6}$/, "Color must be a valid hex value"),
233
+ description: z.string().trim()
234
+ });