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.
- package/README.md +13 -0
- package/dist/assets/{board-_C6oMy5w.js → board-ta0rUHOf.js} +3 -3
- package/dist/assets/{board-_C6oMy5w.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-D4sZgCHd.js → motion-fBKPB6yw.js} +3 -3
- package/dist/assets/motion-fBKPB6yw.js.map +1 -0
- package/dist/assets/{table-BWzTaky1.js → table-C-IGTQni.js} +2 -2
- package/dist/assets/{table-BWzTaky1.js.map → table-C-IGTQni.js.map} +1 -1
- package/dist/assets/{ui-BzK4azQb.js → ui-DInOpaYF.js} +2 -2
- package/dist/assets/{ui-BzK4azQb.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/parity.d.ts +1 -1
- package/dist/openclaw/parity.js +29 -0
- package/dist/openclaw/plugin-entry-shared.d.ts +1 -0
- package/dist/openclaw/plugin-entry-shared.js +31 -6
- package/dist/openclaw/plugin-sdk-types.d.ts +29 -0
- package/dist/openclaw/routes.js +236 -0
- package/dist/openclaw/session-bootstrap.d.ts +78 -0
- package/dist/openclaw/session-bootstrap.js +240 -0
- package/dist/openclaw/tools.js +279 -6
- 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} +992 -25
- package/dist/server/server/src/connectors/box-registry.js +188 -0
- package/dist/server/{db.js → server/src/db.js} +6 -0
- package/dist/server/server/src/debug.js +19 -0
- package/dist/server/server/src/discovery-advertiser.js +114 -0
- package/dist/server/{health.js → server/src/health.js} +39 -11
- package/dist/server/{index.js → server/src/index.js} +4 -0
- package/dist/server/{managers → server/src/managers}/platform/llm-manager.js +40 -4
- package/dist/server/{managers → server/src/managers}/platform/openai-responses-provider.js +129 -19
- package/dist/server/server/src/movement.js +2935 -0
- package/dist/server/{openapi.js → server/src/openapi.js} +628 -5
- package/dist/server/{psyche-types.js → server/src/psyche-types.js} +15 -1
- package/dist/server/server/src/questionnaire-flow.js +552 -0
- package/dist/server/server/src/questionnaire-seeds.js +853 -0
- package/dist/server/server/src/questionnaire-types.js +340 -0
- package/dist/server/server/src/repositories/ai-connectors.js +1207 -0
- package/dist/server/server/src/repositories/ai-processors.js +547 -0
- package/dist/server/{repositories → server/src/repositories}/calendar.js +1 -1
- package/dist/server/{repositories → server/src/repositories}/entity-ownership.js +9 -1
- package/dist/server/{repositories → server/src/repositories}/habits.js +69 -5
- package/dist/server/server/src/repositories/model-settings.js +216 -0
- package/dist/server/{repositories → server/src/repositories}/notes.js +57 -15
- package/dist/server/{repositories → server/src/repositories}/preferences.js +124 -0
- package/dist/server/server/src/repositories/questionnaires.js +1338 -0
- package/dist/server/{repositories → server/src/repositories}/settings.js +156 -12
- package/dist/server/server/src/repositories/surface-layouts.js +76 -0
- package/dist/server/{repositories → server/src/repositories}/wiki-memory.js +5 -1
- package/dist/server/{services → server/src/services}/calendar-runtime.js +775 -58
- package/dist/server/{services → server/src/services}/entity-crud.js +81 -2
- package/dist/server/server/src/services/google-calendar-oauth-config.js +176 -0
- package/dist/server/server/src/services/openai-codex-oauth.js +153 -0
- package/dist/server/server/src/services/psyche-observation-calendar.js +46 -0
- package/dist/server/{types.js → server/src/types.js} +621 -14
- package/dist/server/server/src/watch-mobile.js +562 -0
- package/dist/server/{web.js → server/src/web.js} +30 -4
- 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 +6 -1
- package/server/index.js +68 -0
- package/server/migrations/024_questionnaires.sql +96 -0
- package/server/migrations/025_ai_model_connections.sql +26 -0
- package/server/migrations/026_custom_theme_settings.sql +2 -0
- package/server/migrations/027_ai_processors.sql +31 -0
- package/server/migrations/028_movement_domain.sql +136 -0
- package/server/migrations/029_watch_micro_capture.sql +23 -0
- package/server/migrations/030_surface_layouts.sql +5 -0
- package/server/migrations/031_ai_processor_runtime_upgrades.sql +10 -0
- package/server/migrations/032_ai_connectors.sql +44 -0
- package/server/migrations/033_movement_trip_point_sync.sql +36 -0
- package/server/migrations/034_movement_segment_sync.sql +49 -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 +15 -1
- package/skills/forge-openclaw/entity_conversation_playbooks.md +523 -87
- package/skills/forge-openclaw/psyche_entity_playbooks.md +331 -221
- package/dist/assets/index-DTCwBWAs.js +0 -65
- package/dist/assets/index-DTCwBWAs.js.map +0 -1
- package/dist/assets/index-DttXlAgi.css +0 -1
- package/dist/assets/motion-D4sZgCHd.js.map +0 -1
- package/dist/assets/vendor-De38P6YR.js +0 -729
- package/dist/assets/vendor-De38P6YR.js.map +0 -1
- package/dist/assets/viz-C6hfyqzu.js +0 -34
- package/dist/assets/viz-C6hfyqzu.js.map +0 -1
- package/skills/forge-openclaw/cron_jobs.md +0 -395
- /package/dist/server/{demo-data.js → server/src/demo-data.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/{managers → server/src/managers}/base.js +0 -0
- /package/dist/server/{managers → server/src/managers}/contracts.js +0 -0
- /package/dist/server/{managers → server/src/managers}/platform/api-gateway-manager.js +0 -0
- /package/dist/server/{managers → server/src/managers}/platform/audit-manager.js +0 -0
- /package/dist/server/{managers → server/src/managers}/platform/authentication-manager.js +0 -0
- /package/dist/server/{managers → server/src/managers}/platform/authorization-manager.js +0 -0
- /package/dist/server/{managers → server/src/managers}/platform/background-job-manager.js +0 -0
- /package/dist/server/{managers → server/src/managers}/platform/configuration-manager.js +0 -0
- /package/dist/server/{managers → server/src/managers}/platform/database-manager.js +0 -0
- /package/dist/server/{managers → server/src/managers}/platform/event-bus-manager.js +0 -0
- /package/dist/server/{managers → server/src/managers}/platform/external-service-manager.js +0 -0
- /package/dist/server/{managers → server/src/managers}/platform/health-manager.js +0 -0
- /package/dist/server/{managers → server/src/managers}/platform/migration-manager.js +0 -0
- /package/dist/server/{managers → server/src/managers}/platform/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/{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/{repositories → server/src/repositories}/activity-events.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}/event-log.js +0 -0
- /package/dist/server/{repositories → server/src/repositories}/goals.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}/rewards.js +0 -0
- /package/dist/server/{repositories → server/src/repositories}/strategies.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}/work-adjustments.js +0 -0
- /package/dist/server/{seed-demo.js → server/src/seed-demo.js} +0 -0
- /package/dist/server/{services → server/src/services}/context.js +0 -0
- /package/dist/server/{services → server/src/services}/dashboard.js +0 -0
- /package/dist/server/{services → server/src/services}/gamification.js +0 -0
- /package/dist/server/{services → server/src/services}/insights.js +0 -0
- /package/dist/server/{services → server/src/services}/projects.js +0 -0
- /package/dist/server/{services → server/src/services}/psyche.js +0 -0
- /package/dist/server/{services → server/src/services}/relations.js +0 -0
- /package/dist/server/{services → server/src/services}/reviews.js +0 -0
- /package/dist/server/{services → server/src/services}/run-recovery.js +0 -0
- /package/dist/server/{services → server/src/services}/tagging.js +0 -0
- /package/dist/server/{services → server/src/services}/task-run-watchdog.js +0 -0
- /package/dist/server/{services → server/src/services}/work-time.js +0 -0
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
2
2
|
import { getDatabase, runInTransaction } from "../db.js";
|
|
3
|
+
import { logForgeDebug } from "../debug.js";
|
|
3
4
|
import { recordActivityEvent } from "./activity-events.js";
|
|
4
5
|
import { recordEventLog } from "./event-log.js";
|
|
5
|
-
import {
|
|
6
|
+
import { resolveGoogleCalendarOauthPublicConfig } from "../services/google-calendar-oauth-config.js";
|
|
7
|
+
import { buildConnectionAgentIdentity, FORGE_DEFAULT_AGENT_ID, listAiModelConnections, syncForgeManagedWikiProfile } from "./model-settings.js";
|
|
8
|
+
import { createAgentTokenSchema, agentIdentitySchema, customThemeSchema, settingsPayloadSchema, updateSettingsSchema } from "../types.js";
|
|
6
9
|
function boolFromInt(value) {
|
|
7
10
|
return value === 1;
|
|
8
11
|
}
|
|
@@ -24,9 +27,31 @@ function normalizeMicrosoftRedirectUri(value) {
|
|
|
24
27
|
const trimmed = value?.trim();
|
|
25
28
|
return trimmed && trimmed.length > 0 ? trimmed : defaultMicrosoftRedirectUri();
|
|
26
29
|
}
|
|
30
|
+
function logCalendarSettingsDebug(message, details) {
|
|
31
|
+
const serialized = Object.entries(details)
|
|
32
|
+
.map(([key, value]) => `${key}=${JSON.stringify(value)}`)
|
|
33
|
+
.join(" ");
|
|
34
|
+
logForgeDebug(`[forge-calendar-settings] ${message} ${serialized}`);
|
|
35
|
+
}
|
|
36
|
+
function normalizeModelConnectionId(value) {
|
|
37
|
+
const trimmed = value?.trim();
|
|
38
|
+
return trimmed && trimmed.length > 0 ? trimmed : "";
|
|
39
|
+
}
|
|
27
40
|
function buildTokenSecret() {
|
|
28
41
|
return `fg_live_${randomBytes(18).toString("hex")}`;
|
|
29
42
|
}
|
|
43
|
+
function parseCustomThemeJson(raw) {
|
|
44
|
+
const trimmed = raw?.trim();
|
|
45
|
+
if (!trimmed) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
return customThemeSchema.parse(JSON.parse(trimmed));
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
30
55
|
function mapAgent(row) {
|
|
31
56
|
return agentIdentitySchema.parse({
|
|
32
57
|
id: row.id,
|
|
@@ -118,9 +143,10 @@ function readSettingsRow() {
|
|
|
118
143
|
ensureSettingsRow();
|
|
119
144
|
return getDatabase()
|
|
120
145
|
.prepare(`SELECT
|
|
121
|
-
operator_name, operator_email, operator_title, theme_preference, locale_preference,
|
|
146
|
+
operator_name, operator_email, operator_title, theme_preference, custom_theme_json, locale_preference,
|
|
122
147
|
goal_drift_alerts, daily_quest_reminders, achievement_celebrations, max_active_tasks, time_accounting_mode,
|
|
123
|
-
integrity_score, last_audit_at, psyche_auth_required, microsoft_client_id, microsoft_tenant_id, microsoft_redirect_uri,
|
|
148
|
+
integrity_score, last_audit_at, psyche_auth_required, google_client_id, google_client_secret, microsoft_client_id, microsoft_tenant_id, microsoft_redirect_uri,
|
|
149
|
+
forge_basic_chat_connection_id, forge_basic_chat_model, forge_wiki_connection_id, forge_wiki_model, created_at, updated_at
|
|
124
150
|
FROM app_settings
|
|
125
151
|
WHERE id = 1`)
|
|
126
152
|
.get();
|
|
@@ -167,7 +193,23 @@ export function listAgentIdentities() {
|
|
|
167
193
|
GROUP BY agent_identities.id
|
|
168
194
|
ORDER BY agent_identities.created_at DESC`)
|
|
169
195
|
.all();
|
|
170
|
-
|
|
196
|
+
const manualAgents = rows.map(mapAgent);
|
|
197
|
+
const modelAgents = listAiModelConnections().map(buildConnectionAgentIdentity);
|
|
198
|
+
const settings = readSettingsRow();
|
|
199
|
+
const forgeAgent = agentIdentitySchema.parse({
|
|
200
|
+
id: FORGE_DEFAULT_AGENT_ID,
|
|
201
|
+
label: "Forge Agent",
|
|
202
|
+
agentType: "forge_default",
|
|
203
|
+
trustLevel: "trusted",
|
|
204
|
+
autonomyMode: "approval_required",
|
|
205
|
+
approvalMode: "approval_by_default",
|
|
206
|
+
description: "Built-in Forge operator agent. Owns Forge-native task flows, prompts, and orchestration.",
|
|
207
|
+
tokenCount: 0,
|
|
208
|
+
activeTokenCount: 0,
|
|
209
|
+
createdAt: settings.created_at,
|
|
210
|
+
updatedAt: settings.updated_at
|
|
211
|
+
});
|
|
212
|
+
return [forgeAgent, ...modelAgents, ...manualAgents];
|
|
171
213
|
}
|
|
172
214
|
export function isPsycheAuthRequired() {
|
|
173
215
|
ensureSettingsRow();
|
|
@@ -178,9 +220,27 @@ export function isPsycheAuthRequired() {
|
|
|
178
220
|
}
|
|
179
221
|
export function getSettings() {
|
|
180
222
|
const row = readSettingsRow();
|
|
223
|
+
const connections = listAiModelConnections();
|
|
224
|
+
const googleConfig = resolveGoogleCalendarOauthPublicConfig(process.env, {
|
|
225
|
+
clientId: row.google_client_id,
|
|
226
|
+
clientSecret: row.google_client_secret
|
|
227
|
+
});
|
|
228
|
+
logCalendarSettingsDebug("get_settings", {
|
|
229
|
+
storedGoogleClientId: row.google_client_id,
|
|
230
|
+
storedGoogleClientSecret: row.google_client_secret.length > 0,
|
|
231
|
+
resolvedGoogleClientId: googleConfig.clientId,
|
|
232
|
+
resolvedGoogleClientSecret: googleConfig.clientSecret.length > 0,
|
|
233
|
+
googleIsConfigured: googleConfig.isConfigured,
|
|
234
|
+
googleRedirectUri: googleConfig.redirectUri
|
|
235
|
+
});
|
|
181
236
|
const microsoftClientId = row.microsoft_client_id?.trim() ?? "";
|
|
182
237
|
const microsoftTenantId = normalizeMicrosoftTenantId(row.microsoft_tenant_id);
|
|
183
238
|
const microsoftRedirectUri = normalizeMicrosoftRedirectUri(row.microsoft_redirect_uri);
|
|
239
|
+
const basicChatConnectionId = normalizeModelConnectionId(row.forge_basic_chat_connection_id);
|
|
240
|
+
const wikiConnectionId = normalizeModelConnectionId(row.forge_wiki_connection_id);
|
|
241
|
+
const basicChatConnection = connections.find((entry) => entry.id === basicChatConnectionId) ?? null;
|
|
242
|
+
const wikiConnection = connections.find((entry) => entry.id === wikiConnectionId) ?? null;
|
|
243
|
+
const customTheme = parseCustomThemeJson(row.custom_theme_json);
|
|
184
244
|
return settingsPayloadSchema.parse({
|
|
185
245
|
profile: {
|
|
186
246
|
operatorName: row.operator_name,
|
|
@@ -197,6 +257,7 @@ export function getSettings() {
|
|
|
197
257
|
timeAccountingMode: row.time_accounting_mode
|
|
198
258
|
},
|
|
199
259
|
themePreference: row.theme_preference,
|
|
260
|
+
customTheme,
|
|
200
261
|
localePreference: row.locale_preference,
|
|
201
262
|
security: {
|
|
202
263
|
integrityScore: row.integrity_score,
|
|
@@ -207,6 +268,7 @@ export function getSettings() {
|
|
|
207
268
|
psycheAuthRequired: boolFromInt(row.psyche_auth_required)
|
|
208
269
|
},
|
|
209
270
|
calendarProviders: {
|
|
271
|
+
google: googleConfig,
|
|
210
272
|
microsoft: {
|
|
211
273
|
clientId: microsoftClientId,
|
|
212
274
|
tenantId: microsoftTenantId,
|
|
@@ -221,15 +283,55 @@ export function getSettings() {
|
|
|
221
283
|
: "Save the Microsoft client ID and the Forge callback redirect URI here before you try to sign in."
|
|
222
284
|
}
|
|
223
285
|
},
|
|
286
|
+
modelSettings: {
|
|
287
|
+
forgeAgent: {
|
|
288
|
+
basicChat: {
|
|
289
|
+
connectionId: basicChatConnection?.id ?? null,
|
|
290
|
+
connectionLabel: basicChatConnection?.label ?? null,
|
|
291
|
+
provider: basicChatConnection?.provider ?? null,
|
|
292
|
+
baseUrl: basicChatConnection?.baseUrl ?? null,
|
|
293
|
+
model: row.forge_basic_chat_model?.trim() || basicChatConnection?.model || "gpt-5.4-mini"
|
|
294
|
+
},
|
|
295
|
+
wiki: {
|
|
296
|
+
connectionId: wikiConnection?.id ?? null,
|
|
297
|
+
connectionLabel: wikiConnection?.label ?? null,
|
|
298
|
+
provider: wikiConnection?.provider ?? null,
|
|
299
|
+
baseUrl: wikiConnection?.baseUrl ?? null,
|
|
300
|
+
model: row.forge_wiki_model?.trim() || wikiConnection?.model || "gpt-5.4-mini"
|
|
301
|
+
}
|
|
302
|
+
},
|
|
303
|
+
connections,
|
|
304
|
+
oauth: {
|
|
305
|
+
openAiCodex: {
|
|
306
|
+
authorizeUrl: "https://auth.openai.com/oauth/authorize",
|
|
307
|
+
callbackUrl: "http://127.0.0.1:1455/auth/callback",
|
|
308
|
+
setupMessage: "Forge mirrors OpenClaw's local OpenAI Codex PKCE flow. The browser returns to localhost:1455, and Forge can also accept a pasted redirect URL when the callback cannot bind."
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
},
|
|
224
312
|
agents: listAgentIdentities(),
|
|
225
313
|
agentTokens: listAgentTokens()
|
|
226
314
|
});
|
|
227
315
|
}
|
|
228
|
-
export function updateSettings(input,
|
|
316
|
+
export function updateSettings(input, options = {}) {
|
|
229
317
|
const parsed = updateSettingsSchema.parse(input);
|
|
230
318
|
return runInTransaction(() => {
|
|
231
319
|
const current = getSettings();
|
|
232
320
|
const now = new Date().toISOString();
|
|
321
|
+
const nextGoogleClientId = parsed.calendarProviders?.google?.clientId?.trim() ??
|
|
322
|
+
current.calendarProviders.google.storedClientId;
|
|
323
|
+
const nextGoogleClientSecret = parsed.calendarProviders?.google?.clientSecret?.trim() ??
|
|
324
|
+
current.calendarProviders.google.storedClientSecret;
|
|
325
|
+
logCalendarSettingsDebug("update_settings_requested", {
|
|
326
|
+
requestedGoogleClientId: parsed.calendarProviders?.google?.clientId ?? null,
|
|
327
|
+
requestedGoogleClientSecret: parsed.calendarProviders?.google?.clientSecret !== undefined
|
|
328
|
+
? parsed.calendarProviders.google.clientSecret.length > 0
|
|
329
|
+
: null,
|
|
330
|
+
currentGoogleClientId: current.calendarProviders.google.storedClientId,
|
|
331
|
+
currentGoogleClientSecret: current.calendarProviders.google.storedClientSecret.length > 0,
|
|
332
|
+
nextGoogleClientId,
|
|
333
|
+
nextGoogleClientSecret: nextGoogleClientSecret.length > 0
|
|
334
|
+
});
|
|
233
335
|
const next = {
|
|
234
336
|
profile: {
|
|
235
337
|
operatorName: parsed.profile?.operatorName ?? current.profile.operatorName,
|
|
@@ -246,9 +348,14 @@ export function updateSettings(input, activity) {
|
|
|
246
348
|
timeAccountingMode: parsed.execution?.timeAccountingMode ?? current.execution.timeAccountingMode
|
|
247
349
|
},
|
|
248
350
|
themePreference: parsed.themePreference ?? current.themePreference,
|
|
351
|
+
customTheme: parsed.customTheme === undefined ? (current.customTheme ?? null) : parsed.customTheme,
|
|
249
352
|
localePreference: parsed.localePreference ?? current.localePreference,
|
|
250
353
|
psycheAuthRequired: parsed.security?.psycheAuthRequired ?? current.security.psycheAuthRequired,
|
|
251
354
|
calendarProviders: {
|
|
355
|
+
google: resolveGoogleCalendarOauthPublicConfig(process.env, {
|
|
356
|
+
clientId: nextGoogleClientId,
|
|
357
|
+
clientSecret: nextGoogleClientSecret
|
|
358
|
+
}),
|
|
252
359
|
microsoft: {
|
|
253
360
|
clientId: parsed.calendarProviders?.microsoft?.clientId?.trim() ??
|
|
254
361
|
current.calendarProviders.microsoft.clientId,
|
|
@@ -257,33 +364,70 @@ export function updateSettings(input, activity) {
|
|
|
257
364
|
redirectUri: normalizeMicrosoftRedirectUri(parsed.calendarProviders?.microsoft?.redirectUri ??
|
|
258
365
|
current.calendarProviders.microsoft.redirectUri)
|
|
259
366
|
}
|
|
367
|
+
},
|
|
368
|
+
modelSettings: {
|
|
369
|
+
forgeAgent: {
|
|
370
|
+
basicChat: {
|
|
371
|
+
connectionId: parsed.modelSettings?.forgeAgent?.basicChat?.connectionId !==
|
|
372
|
+
undefined
|
|
373
|
+
? normalizeModelConnectionId(parsed.modelSettings.forgeAgent.basicChat.connectionId)
|
|
374
|
+
: current.modelSettings.forgeAgent.basicChat.connectionId ?? "",
|
|
375
|
+
model: parsed.modelSettings?.forgeAgent?.basicChat?.model?.trim() ||
|
|
376
|
+
current.modelSettings.forgeAgent.basicChat.model
|
|
377
|
+
},
|
|
378
|
+
wiki: {
|
|
379
|
+
connectionId: parsed.modelSettings?.forgeAgent?.wiki?.connectionId !== undefined
|
|
380
|
+
? normalizeModelConnectionId(parsed.modelSettings.forgeAgent.wiki.connectionId)
|
|
381
|
+
: current.modelSettings.forgeAgent.wiki.connectionId ?? "",
|
|
382
|
+
model: parsed.modelSettings?.forgeAgent?.wiki?.model?.trim() ||
|
|
383
|
+
current.modelSettings.forgeAgent.wiki.model
|
|
384
|
+
}
|
|
385
|
+
}
|
|
260
386
|
}
|
|
261
387
|
};
|
|
262
388
|
getDatabase()
|
|
263
389
|
.prepare(`UPDATE app_settings
|
|
264
|
-
SET operator_name = ?, operator_email = ?, operator_title = ?, theme_preference = ?, locale_preference = ?,
|
|
390
|
+
SET operator_name = ?, operator_email = ?, operator_title = ?, theme_preference = ?, custom_theme_json = ?, locale_preference = ?,
|
|
265
391
|
goal_drift_alerts = ?, daily_quest_reminders = ?, achievement_celebrations = ?, max_active_tasks = ?, time_accounting_mode = ?,
|
|
266
|
-
psyche_auth_required = ?,
|
|
392
|
+
psyche_auth_required = ?, google_client_id = ?, google_client_secret = ?, microsoft_client_id = ?, microsoft_tenant_id = ?, microsoft_redirect_uri = ?,
|
|
393
|
+
forge_basic_chat_connection_id = ?, forge_basic_chat_model = ?, forge_wiki_connection_id = ?, forge_wiki_model = ?, updated_at = ?
|
|
267
394
|
WHERE id = 1`)
|
|
268
|
-
.run(next.profile.operatorName, next.profile.operatorEmail, next.profile.operatorTitle, next.themePreference, next.localePreference, toInt(next.notifications.goalDriftAlerts), toInt(next.notifications.dailyQuestReminders), toInt(next.notifications.achievementCelebrations), next.execution.maxActiveTasks, next.execution.timeAccountingMode, toInt(next.psycheAuthRequired), next.calendarProviders.microsoft.clientId, next.calendarProviders.microsoft.tenantId, next.calendarProviders.microsoft.redirectUri, now);
|
|
269
|
-
|
|
395
|
+
.run(next.profile.operatorName, next.profile.operatorEmail, next.profile.operatorTitle, next.themePreference, next.customTheme ? JSON.stringify(next.customTheme) : "", next.localePreference, toInt(next.notifications.goalDriftAlerts), toInt(next.notifications.dailyQuestReminders), toInt(next.notifications.achievementCelebrations), next.execution.maxActiveTasks, next.execution.timeAccountingMode, toInt(next.psycheAuthRequired), nextGoogleClientId, nextGoogleClientSecret, next.calendarProviders.microsoft.clientId, next.calendarProviders.microsoft.tenantId, next.calendarProviders.microsoft.redirectUri, next.modelSettings.forgeAgent.basicChat.connectionId, next.modelSettings.forgeAgent.basicChat.model, next.modelSettings.forgeAgent.wiki.connectionId, next.modelSettings.forgeAgent.wiki.model, now);
|
|
396
|
+
logCalendarSettingsDebug("update_settings_committed", {
|
|
397
|
+
persistedGoogleClientId: nextGoogleClientId,
|
|
398
|
+
persistedGoogleClientSecret: nextGoogleClientSecret.length > 0,
|
|
399
|
+
persistedMicrosoftClientId: next.calendarProviders.microsoft.clientId,
|
|
400
|
+
updatedAt: now
|
|
401
|
+
});
|
|
402
|
+
if (options.secrets) {
|
|
403
|
+
syncForgeManagedWikiProfile(options.secrets);
|
|
404
|
+
}
|
|
405
|
+
if (options.activity) {
|
|
270
406
|
recordActivityEvent({
|
|
271
407
|
entityType: "system",
|
|
272
408
|
entityId: "app_settings",
|
|
273
409
|
eventType: "settings_updated",
|
|
274
410
|
title: "Forge settings updated",
|
|
275
411
|
description: `Theme is now ${next.themePreference}. Language is ${next.localePreference}.`,
|
|
276
|
-
actor: activity.actor ?? null,
|
|
277
|
-
source: activity.source,
|
|
412
|
+
actor: options.activity.actor ?? null,
|
|
413
|
+
source: options.activity.source,
|
|
278
414
|
metadata: {
|
|
279
415
|
themePreference: next.themePreference,
|
|
416
|
+
customThemeLabel: next.customTheme?.label ?? null,
|
|
280
417
|
localePreference: next.localePreference,
|
|
281
418
|
goalDriftAlerts: next.notifications.goalDriftAlerts,
|
|
282
419
|
dailyQuestReminders: next.notifications.dailyQuestReminders,
|
|
283
420
|
maxActiveTasks: next.execution.maxActiveTasks,
|
|
284
421
|
timeAccountingMode: next.execution.timeAccountingMode,
|
|
422
|
+
googleConfigured: next.calendarProviders.google.isConfigured,
|
|
423
|
+
googleAppBaseUrl: next.calendarProviders.google.appBaseUrl,
|
|
424
|
+
googleRedirectUri: next.calendarProviders.google.redirectUri,
|
|
285
425
|
microsoftConfigured: next.calendarProviders.microsoft.clientId.trim().length > 0,
|
|
286
|
-
microsoftTenantId: next.calendarProviders.microsoft.tenantId
|
|
426
|
+
microsoftTenantId: next.calendarProviders.microsoft.tenantId,
|
|
427
|
+
forgeBasicChatModel: next.modelSettings.forgeAgent.basicChat.model,
|
|
428
|
+
forgeWikiModel: next.modelSettings.forgeAgent.wiki.model,
|
|
429
|
+
forgeBasicChatConnectionId: next.modelSettings.forgeAgent.basicChat.connectionId || null,
|
|
430
|
+
forgeWikiConnectionId: next.modelSettings.forgeAgent.wiki.connectionId || null
|
|
287
431
|
}
|
|
288
432
|
});
|
|
289
433
|
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { getDatabase } from "../db.js";
|
|
2
|
+
import { surfaceLayoutPayloadSchema } from "../types.js";
|
|
3
|
+
function parseLayout(row) {
|
|
4
|
+
const parsed = JSON.parse(row.payload_json);
|
|
5
|
+
const legacy = "layouts" in parsed ? parsed : null;
|
|
6
|
+
const legacyOrder = Array.isArray(legacy?.layouts?.lg)
|
|
7
|
+
? [...legacy.layouts.lg]
|
|
8
|
+
.sort((left, right) => {
|
|
9
|
+
const leftY = typeof left.y === "number" ? left.y : 0;
|
|
10
|
+
const rightY = typeof right.y === "number" ? right.y : 0;
|
|
11
|
+
if (leftY !== rightY) {
|
|
12
|
+
return leftY - rightY;
|
|
13
|
+
}
|
|
14
|
+
const leftX = typeof left.x === "number" ? left.x : 0;
|
|
15
|
+
const rightX = typeof right.x === "number" ? right.x : 0;
|
|
16
|
+
return leftX - rightX;
|
|
17
|
+
})
|
|
18
|
+
.map((item) => item.i)
|
|
19
|
+
.filter((item) => typeof item === "string" && item.trim().length > 0)
|
|
20
|
+
: [];
|
|
21
|
+
const widgets = Object.fromEntries(Object.entries(parsed.widgets ?? {}).map(([widgetId, rawValue]) => {
|
|
22
|
+
const value = rawValue && typeof rawValue === "object"
|
|
23
|
+
? rawValue
|
|
24
|
+
: {};
|
|
25
|
+
const legacyLg = legacy?.layouts?.lg?.find((entry) => entry.i === widgetId);
|
|
26
|
+
return [
|
|
27
|
+
widgetId,
|
|
28
|
+
{
|
|
29
|
+
hidden: value.hidden === true,
|
|
30
|
+
fullWidth: value.fullWidth === true ||
|
|
31
|
+
(typeof legacyLg?.w === "number" && legacyLg.w >= 10),
|
|
32
|
+
titleVisible: value.titleVisible !== false,
|
|
33
|
+
descriptionVisible: value.descriptionVisible !== false
|
|
34
|
+
}
|
|
35
|
+
];
|
|
36
|
+
}));
|
|
37
|
+
return surfaceLayoutPayloadSchema.parse({
|
|
38
|
+
...parsed,
|
|
39
|
+
surfaceId: row.surface_id,
|
|
40
|
+
order: Array.isArray(parsed.order) && parsed.order.length > 0
|
|
41
|
+
? parsed.order
|
|
42
|
+
: legacyOrder,
|
|
43
|
+
widgets,
|
|
44
|
+
updatedAt: row.updated_at
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
export function getSurfaceLayout(surfaceId) {
|
|
48
|
+
const row = getDatabase()
|
|
49
|
+
.prepare(`SELECT surface_id, payload_json, updated_at
|
|
50
|
+
FROM surface_layouts
|
|
51
|
+
WHERE surface_id = ?`)
|
|
52
|
+
.get(surfaceId);
|
|
53
|
+
return row ? parseLayout(row) : null;
|
|
54
|
+
}
|
|
55
|
+
export function saveSurfaceLayout(surfaceId, payload) {
|
|
56
|
+
const now = new Date().toISOString();
|
|
57
|
+
const next = surfaceLayoutPayloadSchema.parse({
|
|
58
|
+
surfaceId,
|
|
59
|
+
updatedAt: now,
|
|
60
|
+
...payload
|
|
61
|
+
});
|
|
62
|
+
getDatabase()
|
|
63
|
+
.prepare(`INSERT INTO surface_layouts (surface_id, payload_json, updated_at)
|
|
64
|
+
VALUES (?, ?, ?)
|
|
65
|
+
ON CONFLICT(surface_id) DO UPDATE SET
|
|
66
|
+
payload_json = excluded.payload_json,
|
|
67
|
+
updated_at = excluded.updated_at`)
|
|
68
|
+
.run(surfaceId, JSON.stringify(next), now);
|
|
69
|
+
return getSurfaceLayout(surfaceId);
|
|
70
|
+
}
|
|
71
|
+
export function resetSurfaceLayout(surfaceId) {
|
|
72
|
+
getDatabase()
|
|
73
|
+
.prepare(`DELETE FROM surface_layouts WHERE surface_id = ?`)
|
|
74
|
+
.run(surfaceId);
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
@@ -274,6 +274,7 @@ export const upsertWikiLlmProfileSchema = z.object({
|
|
|
274
274
|
baseUrl: z.string().trim().default("https://api.openai.com/v1"),
|
|
275
275
|
model: z.string().trim().min(1),
|
|
276
276
|
apiKey: z.string().trim().optional(),
|
|
277
|
+
secretId: z.string().trim().nullable().optional(),
|
|
277
278
|
systemPrompt: z.string().trim().default(""),
|
|
278
279
|
reasoningEffort: wikiLlmReasoningEffortSchema.optional(),
|
|
279
280
|
verbosity: wikiLlmVerbositySchema.optional(),
|
|
@@ -737,6 +738,7 @@ function getNoteStoragePath(note, space) {
|
|
|
737
738
|
}
|
|
738
739
|
function buildNoteFrontmatter(note) {
|
|
739
740
|
return {
|
|
741
|
+
...note.frontmatter,
|
|
740
742
|
id: note.id,
|
|
741
743
|
kind: note.kind,
|
|
742
744
|
title: note.title,
|
|
@@ -2058,7 +2060,9 @@ export function upsertWikiLlmProfile(input, secrets) {
|
|
|
2058
2060
|
const now = nowIso();
|
|
2059
2061
|
const id = parsed.id?.trim() ||
|
|
2060
2062
|
`wiki_llm_${randomUUID().replaceAll("-", "").slice(0, 10)}`;
|
|
2061
|
-
let secretId =
|
|
2063
|
+
let secretId = parsed.secretId ??
|
|
2064
|
+
listWikiLlmProfiles().find((entry) => entry.id === id)?.secretId ??
|
|
2065
|
+
null;
|
|
2062
2066
|
if (parsed.apiKey?.trim()) {
|
|
2063
2067
|
secretId =
|
|
2064
2068
|
secretId ??
|