forge-openclaw-plugin 0.2.60 → 0.2.65
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 +121 -51
- package/dist/assets/{board-B1V3M__K.js → board-DUwMfZvN.js} +1 -1
- package/dist/assets/index-B9VOpR7r.css +1 -0
- package/dist/assets/index-DoHjjze2.js +90 -0
- package/dist/assets/{motion-CltSTItx.js → motion-Crg3QyXD.js} +1 -1
- package/dist/assets/{table-B-VrSFx8.js → table-CTlDeYRs.js} +1 -1
- package/dist/assets/{ui-DUqM4jkt.js → ui-CJPaElbj.js} +1 -1
- package/dist/assets/{vendor-C0otBhgu.js → vendor-BdrT2htV.js} +217 -207
- package/dist/companion-iroh/darwin-arm64/forge-companion-iroh +0 -0
- package/dist/companion-iroh/darwin-x64/forge-companion-iroh +0 -0
- package/dist/companion-iroh/linux-x64/forge-companion-iroh +0 -0
- package/dist/companion-iroh-src/Cargo.lock +4559 -0
- package/dist/companion-iroh-src/Cargo.toml +37 -0
- package/dist/companion-iroh-src/src/lib.rs +279 -0
- package/dist/companion-iroh-src/src/main.rs +478 -0
- package/dist/companion-iroh-src/src/protocol.rs +129 -0
- package/dist/gamification-previews/dark-fantasy-item-trophy-tasks-anvil-marathon.webp +0 -0
- package/dist/gamification-previews/dark-fantasy-item-trophy-xp-levels-the-first-heat.webp +0 -0
- package/dist/gamification-previews/dark-fantasy-item-unlock-streaks-molten-crown-fire.webp +0 -0
- package/dist/gamification-previews/dark-fantasy-mascot.webp +0 -0
- package/dist/gamification-previews/dramatic-smithie-item-trophy-tasks-anvil-marathon.webp +0 -0
- package/dist/gamification-previews/dramatic-smithie-item-trophy-xp-levels-the-first-heat.webp +0 -0
- package/dist/gamification-previews/dramatic-smithie-item-unlock-streaks-molten-crown-fire.webp +0 -0
- package/dist/gamification-previews/dramatic-smithie-mascot.webp +0 -0
- package/dist/gamification-previews/mind-locksmith-item-trophy-tasks-anvil-marathon.webp +0 -0
- package/dist/gamification-previews/mind-locksmith-item-trophy-xp-levels-the-first-heat.webp +0 -0
- package/dist/gamification-previews/mind-locksmith-item-unlock-streaks-molten-crown-fire.webp +0 -0
- package/dist/gamification-previews/mind-locksmith-mascot.webp +0 -0
- package/dist/index.html +7 -7
- package/dist/openclaw/parity.js +27 -0
- package/dist/openclaw/plugin-entry-shared.js +2 -2
- package/dist/openclaw/plugin-sdk-types.d.ts +2 -1
- package/dist/openclaw/routes.d.ts +4 -0
- package/dist/openclaw/routes.js +112 -3
- package/dist/openclaw/tools.js +32 -4
- package/dist/server/server/migrations/059_data_backup_retention.sql +2 -0
- package/dist/server/server/src/app.js +288 -61
- package/dist/server/server/src/data-management-types.js +2 -0
- package/dist/server/server/src/discovery-advertiser.js +13 -0
- package/dist/server/server/src/health.js +58 -3
- package/dist/server/server/src/movement.js +16 -1
- package/dist/server/server/src/openapi.js +410 -9
- package/dist/server/server/src/repositories/rewards.js +60 -0
- package/dist/server/server/src/services/companion-iroh.js +425 -0
- package/dist/server/server/src/services/data-management.js +32 -2
- package/dist/server/server/src/services/doctor.js +762 -0
- package/dist/server/server/src/services/gamification.js +75 -3
- package/dist/server/server/src/services/life-force.js +166 -25
- package/dist/server/server/src/web.js +88 -12
- package/dist/server/src/lib/api.js +9 -0
- package/dist/server/src/lib/gamification-catalog.js +1 -1
- package/openclaw.plugin.json +85 -3
- package/package.json +10 -6
- package/server/migrations/059_data_backup_retention.sql +2 -0
- package/skills/forge-openclaw/SKILL.md +80 -19
- package/skills/forge-openclaw/entity_conversation_playbooks.md +283 -25
- package/skills/forge-openclaw/psyche_entity_playbooks.md +82 -0
- package/dist/assets/index-BwKAPo98.css +0 -1
- package/dist/assets/index-Dy7c-dRY.js +0 -90
|
@@ -28,6 +28,13 @@ const HTTP_METHODS = new Set([
|
|
|
28
28
|
"options",
|
|
29
29
|
"head"
|
|
30
30
|
]);
|
|
31
|
+
const CALENDAR_PROVIDER_VALUES = [
|
|
32
|
+
"google",
|
|
33
|
+
"apple",
|
|
34
|
+
"microsoft",
|
|
35
|
+
"caldav",
|
|
36
|
+
"macos_local"
|
|
37
|
+
];
|
|
31
38
|
const API_TAGS = [
|
|
32
39
|
{
|
|
33
40
|
name: "Meta",
|
|
@@ -710,7 +717,7 @@ export function buildOpenApiDocument() {
|
|
|
710
717
|
],
|
|
711
718
|
properties: {
|
|
712
719
|
id: { type: "string" },
|
|
713
|
-
provider: { type: "string", enum:
|
|
720
|
+
provider: { type: "string", enum: CALENDAR_PROVIDER_VALUES },
|
|
714
721
|
label: { type: "string" },
|
|
715
722
|
accountLabel: { type: "string" },
|
|
716
723
|
status: {
|
|
@@ -725,6 +732,134 @@ export function buildOpenApiDocument() {
|
|
|
725
732
|
updatedAt: { type: "string", format: "date-time" }
|
|
726
733
|
}
|
|
727
734
|
};
|
|
735
|
+
const calendarConnectionMutationInput = {
|
|
736
|
+
type: "object",
|
|
737
|
+
additionalProperties: true,
|
|
738
|
+
required: ["provider", "label"],
|
|
739
|
+
properties: {
|
|
740
|
+
provider: { type: "string", enum: CALENDAR_PROVIDER_VALUES },
|
|
741
|
+
label: { type: "string" },
|
|
742
|
+
username: { type: "string" },
|
|
743
|
+
password: { type: "string" },
|
|
744
|
+
serverUrl: { type: "string" },
|
|
745
|
+
authSessionId: { type: "string" },
|
|
746
|
+
sourceId: { type: "string" },
|
|
747
|
+
selectedCalendarUrls: arrayOf({ type: "string" }),
|
|
748
|
+
forgeCalendarUrl: nullable({ type: "string" }),
|
|
749
|
+
createForgeCalendar: { type: "boolean" },
|
|
750
|
+
replaceConnectionIds: arrayOf({ type: "string" })
|
|
751
|
+
}
|
|
752
|
+
};
|
|
753
|
+
const calendarConnectionPatchInput = {
|
|
754
|
+
type: "object",
|
|
755
|
+
additionalProperties: false,
|
|
756
|
+
properties: {
|
|
757
|
+
label: { type: "string" },
|
|
758
|
+
selectedCalendarUrls: arrayOf({ type: "string" })
|
|
759
|
+
}
|
|
760
|
+
};
|
|
761
|
+
const calendarDiscoveryInput = {
|
|
762
|
+
type: "object",
|
|
763
|
+
additionalProperties: true,
|
|
764
|
+
required: ["provider"],
|
|
765
|
+
properties: {
|
|
766
|
+
provider: { type: "string", enum: ["apple", "caldav"] },
|
|
767
|
+
serverUrl: { type: "string" },
|
|
768
|
+
username: { type: "string" },
|
|
769
|
+
password: { type: "string" }
|
|
770
|
+
}
|
|
771
|
+
};
|
|
772
|
+
const calendarDiscoveryCalendar = {
|
|
773
|
+
type: "object",
|
|
774
|
+
additionalProperties: true,
|
|
775
|
+
required: [
|
|
776
|
+
"url",
|
|
777
|
+
"displayName",
|
|
778
|
+
"description",
|
|
779
|
+
"color",
|
|
780
|
+
"timezone",
|
|
781
|
+
"isPrimary",
|
|
782
|
+
"canWrite",
|
|
783
|
+
"selectedByDefault",
|
|
784
|
+
"isForgeCandidate"
|
|
785
|
+
],
|
|
786
|
+
properties: {
|
|
787
|
+
url: { type: "string" },
|
|
788
|
+
displayName: { type: "string" },
|
|
789
|
+
dedupedName: { type: "string" },
|
|
790
|
+
description: { type: "string" },
|
|
791
|
+
color: { type: "string" },
|
|
792
|
+
timezone: { type: "string" },
|
|
793
|
+
isPrimary: { type: "boolean" },
|
|
794
|
+
canWrite: { type: "boolean" },
|
|
795
|
+
selectedByDefault: { type: "boolean" },
|
|
796
|
+
isForgeCandidate: { type: "boolean" },
|
|
797
|
+
sourceId: nullable({ type: "string" }),
|
|
798
|
+
sourceTitle: nullable({ type: "string" }),
|
|
799
|
+
sourceType: nullable({ type: "string" }),
|
|
800
|
+
calendarType: nullable({ type: "string" }),
|
|
801
|
+
hostCalendarId: nullable({ type: "string" }),
|
|
802
|
+
canonicalKey: nullable({ type: "string" })
|
|
803
|
+
}
|
|
804
|
+
};
|
|
805
|
+
const calendarDiscoveryPayload = {
|
|
806
|
+
type: "object",
|
|
807
|
+
additionalProperties: true,
|
|
808
|
+
required: [
|
|
809
|
+
"provider",
|
|
810
|
+
"accountLabel",
|
|
811
|
+
"serverUrl",
|
|
812
|
+
"principalUrl",
|
|
813
|
+
"homeUrl",
|
|
814
|
+
"calendars"
|
|
815
|
+
],
|
|
816
|
+
properties: {
|
|
817
|
+
provider: { type: "string", enum: CALENDAR_PROVIDER_VALUES },
|
|
818
|
+
accountLabel: { type: "string" },
|
|
819
|
+
serverUrl: { type: "string" },
|
|
820
|
+
principalUrl: nullable({ type: "string" }),
|
|
821
|
+
homeUrl: nullable({ type: "string" }),
|
|
822
|
+
calendars: arrayOf(calendarDiscoveryCalendar)
|
|
823
|
+
}
|
|
824
|
+
};
|
|
825
|
+
const macOSLocalCalendarDiscoveryPayload = {
|
|
826
|
+
type: "object",
|
|
827
|
+
additionalProperties: true,
|
|
828
|
+
required: ["status", "requestedAt", "sources"],
|
|
829
|
+
properties: {
|
|
830
|
+
status: {
|
|
831
|
+
type: "string",
|
|
832
|
+
enum: [
|
|
833
|
+
"not_determined",
|
|
834
|
+
"denied",
|
|
835
|
+
"restricted",
|
|
836
|
+
"full_access",
|
|
837
|
+
"unavailable"
|
|
838
|
+
]
|
|
839
|
+
},
|
|
840
|
+
requestedAt: { type: "string", format: "date-time" },
|
|
841
|
+
sources: arrayOf({
|
|
842
|
+
type: "object",
|
|
843
|
+
additionalProperties: true,
|
|
844
|
+
required: [
|
|
845
|
+
"sourceId",
|
|
846
|
+
"sourceTitle",
|
|
847
|
+
"sourceType",
|
|
848
|
+
"accountLabel",
|
|
849
|
+
"accountIdentityKey",
|
|
850
|
+
"calendars"
|
|
851
|
+
],
|
|
852
|
+
properties: {
|
|
853
|
+
sourceId: { type: "string" },
|
|
854
|
+
sourceTitle: { type: "string" },
|
|
855
|
+
sourceType: { type: "string" },
|
|
856
|
+
accountLabel: { type: "string" },
|
|
857
|
+
accountIdentityKey: { type: "string" },
|
|
858
|
+
calendars: arrayOf(calendarDiscoveryCalendar)
|
|
859
|
+
}
|
|
860
|
+
})
|
|
861
|
+
}
|
|
862
|
+
};
|
|
728
863
|
const calendarResource = {
|
|
729
864
|
type: "object",
|
|
730
865
|
additionalProperties: false,
|
|
@@ -781,7 +916,7 @@ export function buildOpenApiDocument() {
|
|
|
781
916
|
],
|
|
782
917
|
properties: {
|
|
783
918
|
id: { type: "string" },
|
|
784
|
-
provider: { type: "string", enum:
|
|
919
|
+
provider: { type: "string", enum: CALENDAR_PROVIDER_VALUES },
|
|
785
920
|
connectionId: nullable({ type: "string" }),
|
|
786
921
|
calendarId: nullable({ type: "string" }),
|
|
787
922
|
remoteCalendarId: nullable({ type: "string" }),
|
|
@@ -3218,6 +3353,95 @@ export function buildOpenApiDocument() {
|
|
|
3218
3353
|
agentTokens: arrayOf({ $ref: "#/components/schemas/AgentTokenSummary" })
|
|
3219
3354
|
}
|
|
3220
3355
|
};
|
|
3356
|
+
const doctorFixProposal = {
|
|
3357
|
+
type: "object",
|
|
3358
|
+
additionalProperties: false,
|
|
3359
|
+
required: ["id", "kind", "title", "description", "requiresConfirmation"],
|
|
3360
|
+
properties: {
|
|
3361
|
+
id: { type: "string" },
|
|
3362
|
+
kind: { type: "string", enum: ["manual", "safe_auto_fix"] },
|
|
3363
|
+
title: { type: "string" },
|
|
3364
|
+
description: { type: "string" },
|
|
3365
|
+
requiresConfirmation: { type: "boolean" }
|
|
3366
|
+
}
|
|
3367
|
+
};
|
|
3368
|
+
const doctorCheck = {
|
|
3369
|
+
type: "object",
|
|
3370
|
+
additionalProperties: false,
|
|
3371
|
+
required: [
|
|
3372
|
+
"id",
|
|
3373
|
+
"group",
|
|
3374
|
+
"title",
|
|
3375
|
+
"status",
|
|
3376
|
+
"severity",
|
|
3377
|
+
"summary",
|
|
3378
|
+
"evidence",
|
|
3379
|
+
"affectedCount"
|
|
3380
|
+
],
|
|
3381
|
+
properties: {
|
|
3382
|
+
id: { type: "string" },
|
|
3383
|
+
group: { type: "string" },
|
|
3384
|
+
title: { type: "string" },
|
|
3385
|
+
status: { type: "string", enum: ["pass", "warn", "fail", "skipped"] },
|
|
3386
|
+
severity: { type: "string", enum: ["info", "warning", "error"] },
|
|
3387
|
+
summary: { type: "string" },
|
|
3388
|
+
evidence: arrayOf({ type: "string" }),
|
|
3389
|
+
affectedCount: { type: "integer" },
|
|
3390
|
+
fix: { $ref: "#/components/schemas/DoctorFixProposal" }
|
|
3391
|
+
}
|
|
3392
|
+
};
|
|
3393
|
+
const forgeDoctorReport = {
|
|
3394
|
+
type: "object",
|
|
3395
|
+
additionalProperties: true,
|
|
3396
|
+
required: [
|
|
3397
|
+
"ok",
|
|
3398
|
+
"now",
|
|
3399
|
+
"integrity",
|
|
3400
|
+
"runtime",
|
|
3401
|
+
"health",
|
|
3402
|
+
"settingsFile",
|
|
3403
|
+
"settingsSummary",
|
|
3404
|
+
"checks",
|
|
3405
|
+
"issues",
|
|
3406
|
+
"fixProposals",
|
|
3407
|
+
"warnings"
|
|
3408
|
+
],
|
|
3409
|
+
properties: {
|
|
3410
|
+
ok: { type: "boolean" },
|
|
3411
|
+
now: { type: "string", format: "date-time" },
|
|
3412
|
+
integrity: {
|
|
3413
|
+
type: "object",
|
|
3414
|
+
additionalProperties: true,
|
|
3415
|
+
required: ["score", "status", "headline", "lastCheckedAt"],
|
|
3416
|
+
properties: {
|
|
3417
|
+
score: { type: "integer" },
|
|
3418
|
+
status: { type: "string", enum: ["healthy", "warning", "critical"] },
|
|
3419
|
+
headline: { type: "string" },
|
|
3420
|
+
lastCheckedAt: { type: "string", format: "date-time" }
|
|
3421
|
+
}
|
|
3422
|
+
},
|
|
3423
|
+
runtime: { type: "object", additionalProperties: true },
|
|
3424
|
+
health: { type: "object", additionalProperties: true },
|
|
3425
|
+
settingsFile: { type: "object", additionalProperties: true },
|
|
3426
|
+
settingsSummary: { type: "object", additionalProperties: true },
|
|
3427
|
+
checks: arrayOf({ $ref: "#/components/schemas/DoctorCheck" }),
|
|
3428
|
+
issues: arrayOf({ $ref: "#/components/schemas/DoctorCheck" }),
|
|
3429
|
+
fixProposals: arrayOf({
|
|
3430
|
+
$ref: "#/components/schemas/DoctorFixProposal"
|
|
3431
|
+
}),
|
|
3432
|
+
warnings: arrayOf({ type: "string" })
|
|
3433
|
+
}
|
|
3434
|
+
};
|
|
3435
|
+
const doctorFixResult = {
|
|
3436
|
+
type: "object",
|
|
3437
|
+
additionalProperties: false,
|
|
3438
|
+
required: ["fixId", "status", "summary"],
|
|
3439
|
+
properties: {
|
|
3440
|
+
fixId: { type: "string" },
|
|
3441
|
+
status: { type: "string", enum: ["applied", "skipped", "failed"] },
|
|
3442
|
+
summary: { type: "string" }
|
|
3443
|
+
}
|
|
3444
|
+
};
|
|
3221
3445
|
const agentOnboardingPayload = {
|
|
3222
3446
|
type: "object",
|
|
3223
3447
|
additionalProperties: false,
|
|
@@ -3527,7 +3751,9 @@ export function buildOpenApiDocument() {
|
|
|
3527
3751
|
additionalProperties: false,
|
|
3528
3752
|
required: [
|
|
3529
3753
|
"classification",
|
|
3754
|
+
"aliases",
|
|
3530
3755
|
"summary",
|
|
3756
|
+
"methodRoutes",
|
|
3531
3757
|
"readRoutes",
|
|
3532
3758
|
"writeRoutes",
|
|
3533
3759
|
"routeSelectionQuestions",
|
|
@@ -3538,7 +3764,12 @@ export function buildOpenApiDocument() {
|
|
|
3538
3764
|
type: "string",
|
|
3539
3765
|
enum: ["specialized_domain_surface"]
|
|
3540
3766
|
},
|
|
3767
|
+
aliases: arrayOf({ type: "string" }),
|
|
3541
3768
|
summary: { type: "string" },
|
|
3769
|
+
methodRoutes: {
|
|
3770
|
+
type: "object",
|
|
3771
|
+
additionalProperties: { type: "string" }
|
|
3772
|
+
},
|
|
3542
3773
|
readRoutes: {
|
|
3543
3774
|
type: "object",
|
|
3544
3775
|
additionalProperties: { type: "string" }
|
|
@@ -3859,7 +4090,8 @@ export function buildOpenApiDocument() {
|
|
|
3859
4090
|
"specializedRouteToolRule",
|
|
3860
4091
|
"createExample",
|
|
3861
4092
|
"updateExample",
|
|
3862
|
-
"specializedRouteToolExample"
|
|
4093
|
+
"specializedRouteToolExample",
|
|
4094
|
+
"specializedRouteToolExamples"
|
|
3863
4095
|
],
|
|
3864
4096
|
properties: {
|
|
3865
4097
|
preferredBatchRoutes: {
|
|
@@ -3885,7 +4117,11 @@ export function buildOpenApiDocument() {
|
|
|
3885
4117
|
specializedRouteToolRule: { type: "string" },
|
|
3886
4118
|
createExample: { type: "string" },
|
|
3887
4119
|
updateExample: { type: "string" },
|
|
3888
|
-
specializedRouteToolExample: { type: "string" }
|
|
4120
|
+
specializedRouteToolExample: { type: "string" },
|
|
4121
|
+
specializedRouteToolExamples: {
|
|
4122
|
+
type: "object",
|
|
4123
|
+
additionalProperties: { type: "string" }
|
|
4124
|
+
}
|
|
3889
4125
|
}
|
|
3890
4126
|
}
|
|
3891
4127
|
}
|
|
@@ -4674,6 +4910,11 @@ export function buildOpenApiDocument() {
|
|
|
4674
4910
|
Project: project,
|
|
4675
4911
|
CalendarSchedulingRules: calendarSchedulingRules,
|
|
4676
4912
|
CalendarConnection: calendarConnection,
|
|
4913
|
+
CalendarConnectionMutationInput: calendarConnectionMutationInput,
|
|
4914
|
+
CalendarConnectionPatchInput: calendarConnectionPatchInput,
|
|
4915
|
+
CalendarDiscoveryInput: calendarDiscoveryInput,
|
|
4916
|
+
CalendarDiscoveryPayload: calendarDiscoveryPayload,
|
|
4917
|
+
MacOSLocalCalendarDiscoveryPayload: macOSLocalCalendarDiscoveryPayload,
|
|
4677
4918
|
CalendarResource: calendarResource,
|
|
4678
4919
|
CalendarEventSource: calendarEventSource,
|
|
4679
4920
|
CalendarEventLink: calendarEventLink,
|
|
@@ -4703,6 +4944,10 @@ export function buildOpenApiDocument() {
|
|
|
4703
4944
|
InsightsPayload: insightsPayload,
|
|
4704
4945
|
WeeklyReviewPayload: weeklyReviewPayload,
|
|
4705
4946
|
SettingsPayload: settingsPayload,
|
|
4947
|
+
DoctorFixProposal: doctorFixProposal,
|
|
4948
|
+
DoctorCheck: doctorCheck,
|
|
4949
|
+
ForgeDoctorReport: forgeDoctorReport,
|
|
4950
|
+
DoctorFixResult: doctorFixResult,
|
|
4706
4951
|
ExecutionSettings: executionSettings,
|
|
4707
4952
|
TaskRunClaimInput: taskRunClaimInput,
|
|
4708
4953
|
TaskRunHeartbeatInput: taskRunHeartbeatInput,
|
|
@@ -4812,6 +5057,52 @@ export function buildOpenApiDocument() {
|
|
|
4812
5057
|
}
|
|
4813
5058
|
}
|
|
4814
5059
|
},
|
|
5060
|
+
"/api/v1/doctor": {
|
|
5061
|
+
get: {
|
|
5062
|
+
summary: "Run Forge Doctor diagnostics for runtime, settings, storage, entities, hierarchy, rewards, and fix proposals",
|
|
5063
|
+
responses: {
|
|
5064
|
+
"200": jsonResponse({
|
|
5065
|
+
type: "object",
|
|
5066
|
+
required: ["doctor"],
|
|
5067
|
+
properties: {
|
|
5068
|
+
doctor: { $ref: "#/components/schemas/ForgeDoctorReport" }
|
|
5069
|
+
}
|
|
5070
|
+
}, "Forge Doctor report")
|
|
5071
|
+
}
|
|
5072
|
+
}
|
|
5073
|
+
},
|
|
5074
|
+
"/api/v1/doctor/fixes": {
|
|
5075
|
+
post: {
|
|
5076
|
+
summary: "Apply explicitly requested safe Forge Doctor fixes",
|
|
5077
|
+
requestBody: {
|
|
5078
|
+
required: true,
|
|
5079
|
+
content: {
|
|
5080
|
+
"application/json": {
|
|
5081
|
+
schema: {
|
|
5082
|
+
type: "object",
|
|
5083
|
+
additionalProperties: false,
|
|
5084
|
+
properties: {
|
|
5085
|
+
fixIds: arrayOf({ type: "string" }),
|
|
5086
|
+
applyAllSafe: { type: "boolean" }
|
|
5087
|
+
}
|
|
5088
|
+
}
|
|
5089
|
+
}
|
|
5090
|
+
}
|
|
5091
|
+
},
|
|
5092
|
+
responses: {
|
|
5093
|
+
"200": jsonResponse({
|
|
5094
|
+
type: "object",
|
|
5095
|
+
required: ["results", "doctor"],
|
|
5096
|
+
properties: {
|
|
5097
|
+
results: arrayOf({
|
|
5098
|
+
$ref: "#/components/schemas/DoctorFixResult"
|
|
5099
|
+
}),
|
|
5100
|
+
doctor: { $ref: "#/components/schemas/ForgeDoctorReport" }
|
|
5101
|
+
}
|
|
5102
|
+
}, "Forge Doctor fix result")
|
|
5103
|
+
}
|
|
5104
|
+
}
|
|
5105
|
+
},
|
|
4815
5106
|
"/api/v1/health/sleep": {
|
|
4816
5107
|
get: {
|
|
4817
5108
|
summary: "Read the Forge sleep overview surface",
|
|
@@ -7555,6 +7846,50 @@ export function buildOpenApiDocument() {
|
|
|
7555
7846
|
}
|
|
7556
7847
|
}
|
|
7557
7848
|
},
|
|
7849
|
+
"/api/v1/calendar/macos-local/discovery": {
|
|
7850
|
+
get: {
|
|
7851
|
+
summary: "Discover calendars already configured on this Mac through EventKit",
|
|
7852
|
+
responses: {
|
|
7853
|
+
"200": jsonResponse({
|
|
7854
|
+
type: "object",
|
|
7855
|
+
required: ["discovery"],
|
|
7856
|
+
properties: {
|
|
7857
|
+
discovery: {
|
|
7858
|
+
$ref: "#/components/schemas/MacOSLocalCalendarDiscoveryPayload"
|
|
7859
|
+
}
|
|
7860
|
+
}
|
|
7861
|
+
}, "macOS local calendar discovery"),
|
|
7862
|
+
default: { $ref: "#/components/responses/Error" }
|
|
7863
|
+
}
|
|
7864
|
+
}
|
|
7865
|
+
},
|
|
7866
|
+
"/api/v1/calendar/discovery": {
|
|
7867
|
+
post: {
|
|
7868
|
+
summary: "Discover Apple or custom CalDAV calendars before creating a connection",
|
|
7869
|
+
requestBody: {
|
|
7870
|
+
required: true,
|
|
7871
|
+
content: {
|
|
7872
|
+
"application/json": {
|
|
7873
|
+
schema: {
|
|
7874
|
+
$ref: "#/components/schemas/CalendarDiscoveryInput"
|
|
7875
|
+
}
|
|
7876
|
+
}
|
|
7877
|
+
}
|
|
7878
|
+
},
|
|
7879
|
+
responses: {
|
|
7880
|
+
"200": jsonResponse({
|
|
7881
|
+
type: "object",
|
|
7882
|
+
required: ["discovery"],
|
|
7883
|
+
properties: {
|
|
7884
|
+
discovery: {
|
|
7885
|
+
$ref: "#/components/schemas/CalendarDiscoveryPayload"
|
|
7886
|
+
}
|
|
7887
|
+
}
|
|
7888
|
+
}, "Calendar discovery"),
|
|
7889
|
+
default: { $ref: "#/components/responses/Error" }
|
|
7890
|
+
}
|
|
7891
|
+
}
|
|
7892
|
+
},
|
|
7558
7893
|
"/api/v1/calendar/connections": {
|
|
7559
7894
|
get: {
|
|
7560
7895
|
summary: "List connected calendar providers",
|
|
@@ -7573,10 +7908,7 @@ export function buildOpenApiDocument() {
|
|
|
7573
7908
|
"connectionHelp"
|
|
7574
7909
|
],
|
|
7575
7910
|
properties: {
|
|
7576
|
-
provider: {
|
|
7577
|
-
type: "string",
|
|
7578
|
-
enum: ["google", "apple", "caldav"]
|
|
7579
|
-
},
|
|
7911
|
+
provider: { type: "string", enum: CALENDAR_PROVIDER_VALUES },
|
|
7580
7912
|
label: { type: "string" },
|
|
7581
7913
|
supportsDedicatedForgeCalendar: { type: "boolean" },
|
|
7582
7914
|
connectionHelp: { type: "string" }
|
|
@@ -7591,8 +7923,18 @@ export function buildOpenApiDocument() {
|
|
|
7591
7923
|
}
|
|
7592
7924
|
},
|
|
7593
7925
|
post: {
|
|
7594
|
-
summary: "Create a Google, Apple, or custom CalDAV calendar connection",
|
|
7926
|
+
summary: "Create a Google, Apple, Exchange Online, local Mac, or custom CalDAV calendar connection",
|
|
7595
7927
|
description: "Forge first discovers the writable calendars for the account, then stores the chosen mirrored calendars and either reuses the existing shared Forge write target or saves a new one when needed.",
|
|
7928
|
+
requestBody: {
|
|
7929
|
+
required: true,
|
|
7930
|
+
content: {
|
|
7931
|
+
"application/json": {
|
|
7932
|
+
schema: {
|
|
7933
|
+
$ref: "#/components/schemas/CalendarConnectionMutationInput"
|
|
7934
|
+
}
|
|
7935
|
+
}
|
|
7936
|
+
}
|
|
7937
|
+
},
|
|
7596
7938
|
responses: {
|
|
7597
7939
|
"201": jsonResponse({
|
|
7598
7940
|
type: "object",
|
|
@@ -7607,6 +7949,65 @@ export function buildOpenApiDocument() {
|
|
|
7607
7949
|
}
|
|
7608
7950
|
}
|
|
7609
7951
|
},
|
|
7952
|
+
"/api/v1/calendar/connections/{id}": {
|
|
7953
|
+
patch: {
|
|
7954
|
+
summary: "Update one calendar connection label or selected mirrored calendars",
|
|
7955
|
+
requestBody: {
|
|
7956
|
+
required: true,
|
|
7957
|
+
content: {
|
|
7958
|
+
"application/json": {
|
|
7959
|
+
schema: {
|
|
7960
|
+
$ref: "#/components/schemas/CalendarConnectionPatchInput"
|
|
7961
|
+
}
|
|
7962
|
+
}
|
|
7963
|
+
}
|
|
7964
|
+
},
|
|
7965
|
+
responses: {
|
|
7966
|
+
"200": jsonResponse({
|
|
7967
|
+
type: "object",
|
|
7968
|
+
required: ["connection"],
|
|
7969
|
+
properties: {
|
|
7970
|
+
connection: {
|
|
7971
|
+
$ref: "#/components/schemas/CalendarConnection"
|
|
7972
|
+
}
|
|
7973
|
+
}
|
|
7974
|
+
}, "Updated calendar connection"),
|
|
7975
|
+
default: { $ref: "#/components/responses/Error" }
|
|
7976
|
+
}
|
|
7977
|
+
},
|
|
7978
|
+
delete: {
|
|
7979
|
+
summary: "Delete one calendar connection and stop mirroring it",
|
|
7980
|
+
responses: {
|
|
7981
|
+
"200": jsonResponse({
|
|
7982
|
+
type: "object",
|
|
7983
|
+
required: ["connection"],
|
|
7984
|
+
properties: {
|
|
7985
|
+
connection: {
|
|
7986
|
+
$ref: "#/components/schemas/CalendarConnection"
|
|
7987
|
+
}
|
|
7988
|
+
}
|
|
7989
|
+
}, "Deleted calendar connection"),
|
|
7990
|
+
default: { $ref: "#/components/responses/Error" }
|
|
7991
|
+
}
|
|
7992
|
+
}
|
|
7993
|
+
},
|
|
7994
|
+
"/api/v1/calendar/connections/{id}/discovery": {
|
|
7995
|
+
get: {
|
|
7996
|
+
summary: "Rediscover available calendars for an existing calendar connection",
|
|
7997
|
+
responses: {
|
|
7998
|
+
"200": jsonResponse({
|
|
7999
|
+
type: "object",
|
|
8000
|
+
required: ["discovery"],
|
|
8001
|
+
properties: {
|
|
8002
|
+
discovery: {
|
|
8003
|
+
$ref: "#/components/schemas/CalendarDiscoveryPayload"
|
|
8004
|
+
}
|
|
8005
|
+
}
|
|
8006
|
+
}, "Calendar connection discovery"),
|
|
8007
|
+
default: { $ref: "#/components/responses/Error" }
|
|
8008
|
+
}
|
|
8009
|
+
}
|
|
8010
|
+
},
|
|
7610
8011
|
"/api/v1/calendar/connections/{id}/sync": {
|
|
7611
8012
|
post: {
|
|
7612
8013
|
summary: "Sync one connected calendar provider",
|
|
@@ -27,6 +27,14 @@ const DEFAULT_RULES = [
|
|
|
27
27
|
description: "Award a small XP bounty for each ten credited minutes of active work.",
|
|
28
28
|
config: { fixedXp: 4, intervalMinutes: 10 }
|
|
29
29
|
},
|
|
30
|
+
{
|
|
31
|
+
id: "reward_rule_entity_created",
|
|
32
|
+
family: "consistency",
|
|
33
|
+
code: "entity_created",
|
|
34
|
+
title: "Forge entity created",
|
|
35
|
+
description: "Award a small activity bounty when the user creates a real Forge entity.",
|
|
36
|
+
config: { fixedXp: 2 }
|
|
37
|
+
},
|
|
30
38
|
{
|
|
31
39
|
id: "reward_rule_task_run_completion",
|
|
32
40
|
family: "completion",
|
|
@@ -673,6 +681,58 @@ export function recordTaskRunProgressRewards(taskRunId, taskId, actor, source, c
|
|
|
673
681
|
}
|
|
674
682
|
return rewards;
|
|
675
683
|
}
|
|
684
|
+
export function recordEntityCreationReward(input) {
|
|
685
|
+
ensureDefaultRewardRules();
|
|
686
|
+
const reversibleGroup = `entity_created:${input.entityType}:${input.entityId}`;
|
|
687
|
+
const existing = getDatabase()
|
|
688
|
+
.prepare(`SELECT
|
|
689
|
+
id, rule_id, event_log_id, entity_type, entity_id, actor, source,
|
|
690
|
+
delta_xp, reason_title, reason_summary, reversible_group,
|
|
691
|
+
reversed_by_reward_id, metadata_json, created_at
|
|
692
|
+
FROM reward_ledger
|
|
693
|
+
WHERE reversible_group = ?
|
|
694
|
+
ORDER BY created_at ASC
|
|
695
|
+
LIMIT 1`)
|
|
696
|
+
.get(reversibleGroup);
|
|
697
|
+
if (existing) {
|
|
698
|
+
return mapLedger(existing);
|
|
699
|
+
}
|
|
700
|
+
const createdAtDate = Number.isNaN(Date.parse(input.createdAt))
|
|
701
|
+
? new Date()
|
|
702
|
+
: new Date(input.createdAt);
|
|
703
|
+
const rule = getRuleByCode("entity_created");
|
|
704
|
+
const readableType = input.entityType.replaceAll("_", " ");
|
|
705
|
+
const title = input.title?.trim() || readableType;
|
|
706
|
+
const eventLog = recordEventLog({
|
|
707
|
+
eventKind: "reward.entity_created",
|
|
708
|
+
entityType: input.entityType,
|
|
709
|
+
entityId: input.entityId,
|
|
710
|
+
actor: input.actor ?? null,
|
|
711
|
+
source: input.source ?? "system",
|
|
712
|
+
metadata: {
|
|
713
|
+
entityType: input.entityType,
|
|
714
|
+
entityId: input.entityId,
|
|
715
|
+
title,
|
|
716
|
+
createdAt: input.createdAt
|
|
717
|
+
}
|
|
718
|
+
}, createdAtDate);
|
|
719
|
+
return insertLedgerEvent({
|
|
720
|
+
ruleId: rule?.id ?? null,
|
|
721
|
+
eventLogId: eventLog.id,
|
|
722
|
+
entityType: input.entityType,
|
|
723
|
+
entityId: input.entityId,
|
|
724
|
+
actor: input.actor ?? null,
|
|
725
|
+
source: input.source ?? "system",
|
|
726
|
+
deltaXp: Number(rule?.config.fixedXp ?? 2),
|
|
727
|
+
reasonTitle: `Created ${readableType}: ${title}`,
|
|
728
|
+
reasonSummary: "Small Forge activity XP for creating something concrete.",
|
|
729
|
+
reversibleGroup,
|
|
730
|
+
metadata: {
|
|
731
|
+
entityType: input.entityType,
|
|
732
|
+
title
|
|
733
|
+
}
|
|
734
|
+
}, createdAtDate);
|
|
735
|
+
}
|
|
676
736
|
export function recordWorkAdjustmentReward(input) {
|
|
677
737
|
const { rule, intervalMinutes, intervalSeconds, fixedXp } = getTaskRunProgressRewardCadence();
|
|
678
738
|
const entityType = workAdjustmentEntityTypeSchema.parse(input.entityType);
|