forge-openclaw-plugin 0.2.18 → 0.2.19
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 +36 -4
- package/dist/assets/{board-2KevHCI0.js → board-8L3uX7_O.js} +2 -2
- package/dist/assets/{board-2KevHCI0.js.map → board-8L3uX7_O.js.map} +1 -1
- package/dist/assets/index-Cj1IBH_w.js +36 -0
- package/dist/assets/index-Cj1IBH_w.js.map +1 -0
- package/dist/assets/index-DQT6EbuS.css +1 -0
- package/dist/assets/{motion-q19HPmWs.js → motion-1GAqqi8M.js} +2 -2
- package/dist/assets/{motion-q19HPmWs.js.map → motion-1GAqqi8M.js.map} +1 -1
- package/dist/assets/{table-BDMHBY4a.js → table-DBGlgRjk.js} +2 -2
- package/dist/assets/{table-BDMHBY4a.js.map → table-DBGlgRjk.js.map} +1 -1
- package/dist/assets/{ui-CQ_AsFs8.js → ui-iTluWjC4.js} +2 -2
- package/dist/assets/{ui-CQ_AsFs8.js.map → ui-iTluWjC4.js.map} +1 -1
- package/dist/assets/{vendor-5HifrnRK.js → vendor-BvM2F9Dp.js} +139 -84
- package/dist/assets/vendor-BvM2F9Dp.js.map +1 -0
- package/dist/assets/{viz-CQzkRnTu.js → viz-CNeunkfu.js} +2 -2
- package/dist/assets/{viz-CQzkRnTu.js.map → viz-CNeunkfu.js.map} +1 -1
- package/dist/index.html +8 -8
- package/dist/openclaw/parity.js +1 -0
- package/dist/openclaw/routes.js +7 -0
- package/dist/openclaw/tools.js +183 -16
- package/dist/server/app.js +2509 -263
- package/dist/server/managers/platform/secrets-manager.js +44 -1
- package/dist/server/managers/runtime.js +3 -1
- package/dist/server/openapi.js +2037 -172
- package/dist/server/repositories/calendar.js +1101 -0
- package/dist/server/repositories/deleted-entities.js +10 -2
- package/dist/server/repositories/notes.js +161 -28
- package/dist/server/repositories/projects.js +45 -13
- package/dist/server/repositories/rewards.js +114 -6
- package/dist/server/repositories/settings.js +47 -5
- package/dist/server/repositories/task-runs.js +46 -10
- package/dist/server/repositories/tasks.js +25 -9
- package/dist/server/repositories/weekly-reviews.js +109 -0
- package/dist/server/repositories/work-adjustments.js +105 -0
- package/dist/server/services/calendar-runtime.js +1301 -0
- package/dist/server/services/entity-crud.js +94 -3
- package/dist/server/services/projects.js +32 -8
- package/dist/server/services/reviews.js +15 -1
- package/dist/server/services/work-time.js +27 -0
- package/dist/server/types.js +934 -49
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/server/migrations/006_work_adjustments.sql +14 -0
- package/server/migrations/007_weekly_review_closures.sql +17 -0
- package/server/migrations/008_calendar_execution.sql +147 -0
- package/server/migrations/009_true_calendar_events.sql +195 -0
- package/server/migrations/010_calendar_selection_state.sql +6 -0
- package/server/migrations/011_calendar_timezone_backfill.sql +11 -0
- package/server/migrations/012_work_block_ranges.sql +7 -0
- package/server/migrations/013_microsoft_local_auth_settings.sql +8 -0
- package/server/migrations/014_note_tags_and_ephemeral.sql +8 -0
- package/skills/forge-openclaw/SKILL.md +117 -11
- package/dist/assets/index-CDYW4WDH.js +0 -36
- package/dist/assets/index-CDYW4WDH.js.map +0 -1
- package/dist/assets/index-yroQr6YZ.css +0 -1
- package/dist/assets/vendor-5HifrnRK.js.map +0 -1
package/dist/index.html
CHANGED
|
@@ -13,15 +13,15 @@
|
|
|
13
13
|
/>
|
|
14
14
|
<link rel="icon" type="image/png" href="/forge/assets/favicon-BCHm9dUV.ico" />
|
|
15
15
|
<link rel="alternate icon" href="/forge/assets/favicon-BCHm9dUV.ico" />
|
|
16
|
-
<script type="module" crossorigin src="/forge/assets/index-
|
|
17
|
-
<link rel="modulepreload" crossorigin href="/forge/assets/vendor-
|
|
18
|
-
<link rel="modulepreload" crossorigin href="/forge/assets/motion-
|
|
19
|
-
<link rel="modulepreload" crossorigin href="/forge/assets/ui-
|
|
20
|
-
<link rel="modulepreload" crossorigin href="/forge/assets/table-
|
|
21
|
-
<link rel="modulepreload" crossorigin href="/forge/assets/viz-
|
|
22
|
-
<link rel="modulepreload" crossorigin href="/forge/assets/board-
|
|
16
|
+
<script type="module" crossorigin src="/forge/assets/index-Cj1IBH_w.js"></script>
|
|
17
|
+
<link rel="modulepreload" crossorigin href="/forge/assets/vendor-BvM2F9Dp.js">
|
|
18
|
+
<link rel="modulepreload" crossorigin href="/forge/assets/motion-1GAqqi8M.js">
|
|
19
|
+
<link rel="modulepreload" crossorigin href="/forge/assets/ui-iTluWjC4.js">
|
|
20
|
+
<link rel="modulepreload" crossorigin href="/forge/assets/table-DBGlgRjk.js">
|
|
21
|
+
<link rel="modulepreload" crossorigin href="/forge/assets/viz-CNeunkfu.js">
|
|
22
|
+
<link rel="modulepreload" crossorigin href="/forge/assets/board-8L3uX7_O.js">
|
|
23
23
|
<link rel="stylesheet" crossorigin href="/forge/assets/vendor-CRS-psbw.css">
|
|
24
|
-
<link rel="stylesheet" crossorigin href="/forge/assets/index-
|
|
24
|
+
<link rel="stylesheet" crossorigin href="/forge/assets/index-DQT6EbuS.css">
|
|
25
25
|
</head>
|
|
26
26
|
<body class="bg-canvas text-ink antialiased">
|
|
27
27
|
<div id="root"></div>
|
package/dist/openclaw/parity.js
CHANGED
|
@@ -12,6 +12,7 @@ export const FORGE_SUPPORTED_PLUGIN_API_ROUTES = [
|
|
|
12
12
|
{ method: "POST", path: "/api/v1/entities/delete", purpose: "entities" },
|
|
13
13
|
{ method: "POST", path: "/api/v1/entities/restore", purpose: "entities" },
|
|
14
14
|
{ method: "POST", path: "/api/v1/operator/log-work", purpose: "work" },
|
|
15
|
+
{ method: "POST", path: "/api/v1/work-adjustments", purpose: "work" },
|
|
15
16
|
{ method: "POST", path: "/api/v1/tasks/:id/runs", purpose: "work" },
|
|
16
17
|
{ method: "GET", path: "/api/v1/task-runs", purpose: "work" },
|
|
17
18
|
{ method: "POST", path: "/api/v1/task-runs/:id/heartbeat", purpose: "work" },
|
package/dist/openclaw/routes.js
CHANGED
|
@@ -140,6 +140,13 @@ export const FORGE_PLUGIN_ROUTE_GROUPS = [
|
|
|
140
140
|
requiresToken: true,
|
|
141
141
|
target: (_match, url) => passthroughSearch("/api/v1/operator/log-work", url)
|
|
142
142
|
}),
|
|
143
|
+
exact("/forge/v1/work-adjustments", {
|
|
144
|
+
method: "POST",
|
|
145
|
+
upstreamPath: "/api/v1/work-adjustments",
|
|
146
|
+
requestBody: "json",
|
|
147
|
+
requiresToken: true,
|
|
148
|
+
target: (_match, url) => passthroughSearch("/api/v1/work-adjustments", url)
|
|
149
|
+
}),
|
|
143
150
|
exact("/forge/v1/insights", {
|
|
144
151
|
method: "POST",
|
|
145
152
|
upstreamPath: "/api/v1/insights",
|
package/dist/openclaw/tools.js
CHANGED
|
@@ -31,6 +31,17 @@ const emptyObjectSchema = Type.Object({});
|
|
|
31
31
|
const optionalString = () => Type.Optional(Type.String());
|
|
32
32
|
const optionalNullableString = () => Type.Optional(Type.Union([Type.String(), Type.Null()]));
|
|
33
33
|
const optionalDeleteMode = () => Type.Optional(Type.Union([Type.Literal("soft"), Type.Literal("hard")]));
|
|
34
|
+
const noteInputSchema = () => Type.Object({
|
|
35
|
+
contentMarkdown: Type.String({ minLength: 1 }),
|
|
36
|
+
author: optionalNullableString(),
|
|
37
|
+
tags: Type.Optional(Type.Array(Type.String())),
|
|
38
|
+
destroyAt: optionalNullableString(),
|
|
39
|
+
links: Type.Optional(Type.Array(Type.Object({
|
|
40
|
+
entityType: Type.String({ minLength: 1 }),
|
|
41
|
+
entityId: Type.String({ minLength: 1 }),
|
|
42
|
+
anchorKey: optionalNullableString()
|
|
43
|
+
})))
|
|
44
|
+
});
|
|
34
45
|
async function resolveUiEntrypoint(config) {
|
|
35
46
|
let webAppUrl = config.webAppUrl;
|
|
36
47
|
try {
|
|
@@ -57,14 +68,27 @@ async function resolveUiEntrypoint(config) {
|
|
|
57
68
|
}
|
|
58
69
|
async function resolveCurrentWork(config) {
|
|
59
70
|
const payload = await runRead(config, "/api/v1/operator/context");
|
|
60
|
-
const context = typeof payload === "object" &&
|
|
71
|
+
const context = typeof payload === "object" &&
|
|
72
|
+
payload !== null &&
|
|
73
|
+
"context" in payload &&
|
|
74
|
+
typeof payload.context === "object" &&
|
|
75
|
+
payload.context !== null
|
|
61
76
|
? payload.context
|
|
62
77
|
: null;
|
|
63
|
-
const recentTaskRuns = Array.isArray(context?.recentTaskRuns)
|
|
64
|
-
|
|
65
|
-
|
|
78
|
+
const recentTaskRuns = Array.isArray(context?.recentTaskRuns)
|
|
79
|
+
? context.recentTaskRuns
|
|
80
|
+
: [];
|
|
81
|
+
const activeTaskRuns = recentTaskRuns.filter((run) => typeof run === "object" &&
|
|
82
|
+
run !== null &&
|
|
83
|
+
"status" in run &&
|
|
84
|
+
run.status === "active");
|
|
85
|
+
const focusTasks = Array.isArray(context?.focusTasks)
|
|
86
|
+
? context.focusTasks
|
|
87
|
+
: [];
|
|
66
88
|
return {
|
|
67
|
-
generatedAt: typeof context?.generatedAt === "string"
|
|
89
|
+
generatedAt: typeof context?.generatedAt === "string"
|
|
90
|
+
? context.generatedAt
|
|
91
|
+
: new Date().toISOString(),
|
|
68
92
|
activeTaskRuns,
|
|
69
93
|
focusTasks,
|
|
70
94
|
recommendedNextTask: context?.recommendedNextTask ?? null,
|
|
@@ -178,7 +202,7 @@ export function registerForgePluginTools(api, config) {
|
|
|
178
202
|
registerWriteTool(api, config, {
|
|
179
203
|
name: "forge_create_entities",
|
|
180
204
|
label: "Create Forge Entities",
|
|
181
|
-
description: "Create one or more Forge entities through the ordered batch workflow. Pass `operations` as an array. Each operation must include `entityType` and full `data`.
|
|
205
|
+
description: "Create one or more Forge entities through the ordered batch workflow. Pass `operations` as an array. Each operation must include `entityType` and full `data`. This is the preferred create path for planning, Psyche, and calendar records including calendar_event, work_block_template, and task_timebox.",
|
|
182
206
|
parameters: Type.Object({
|
|
183
207
|
atomic: Type.Optional(Type.Boolean()),
|
|
184
208
|
operations: Type.Array(Type.Object({
|
|
@@ -193,7 +217,7 @@ export function registerForgePluginTools(api, config) {
|
|
|
193
217
|
registerWriteTool(api, config, {
|
|
194
218
|
name: "forge_update_entities",
|
|
195
219
|
label: "Update Forge Entities",
|
|
196
|
-
description: "Update one or more Forge entities through the ordered batch workflow. Pass `operations` as an array. Each operation must include `entityType`, `id`, and `patch`.",
|
|
220
|
+
description: "Update one or more Forge entities through the ordered batch workflow. Pass `operations` as an array. Each operation must include `entityType`, `id`, and `patch`. This is the preferred update path for calendar_event, work_block_template, and task_timebox too; Forge runs calendar sync side effects downstream.",
|
|
197
221
|
parameters: Type.Object({
|
|
198
222
|
atomic: Type.Optional(Type.Boolean()),
|
|
199
223
|
operations: Type.Array(Type.Object({
|
|
@@ -209,7 +233,7 @@ export function registerForgePluginTools(api, config) {
|
|
|
209
233
|
registerWriteTool(api, config, {
|
|
210
234
|
name: "forge_delete_entities",
|
|
211
235
|
label: "Delete Forge Entities",
|
|
212
|
-
description: "Delete Forge entities in one batch request. Pass `operations` as an array with `entityType` and `id`. Delete defaults to soft mode unless hard is requested explicitly.",
|
|
236
|
+
description: "Delete Forge entities in one batch request. Pass `operations` as an array with `entityType` and `id`. Delete defaults to soft mode unless hard is requested explicitly. Calendar-domain deletes still run their downstream removal logic, including remote calendar projection cleanup for calendar_event.",
|
|
213
237
|
parameters: Type.Object({
|
|
214
238
|
atomic: Type.Optional(Type.Boolean()),
|
|
215
239
|
operations: Type.Array(Type.Object({
|
|
@@ -253,6 +277,19 @@ export function registerForgePluginTools(api, config) {
|
|
|
253
277
|
method: "POST",
|
|
254
278
|
path: "/api/v1/rewards/bonus"
|
|
255
279
|
});
|
|
280
|
+
registerWriteTool(api, config, {
|
|
281
|
+
name: "forge_adjust_work_minutes",
|
|
282
|
+
label: "Forge Adjust Work Minutes",
|
|
283
|
+
description: "Add or remove tracked work minutes on an existing task or project without creating a live task run. Forge applies symmetric XP changes when the total crosses reward buckets.",
|
|
284
|
+
parameters: Type.Object({
|
|
285
|
+
entityType: Type.Union([Type.Literal("task"), Type.Literal("project")]),
|
|
286
|
+
entityId: Type.String({ minLength: 1 }),
|
|
287
|
+
deltaMinutes: Type.Integer(),
|
|
288
|
+
note: optionalString()
|
|
289
|
+
}),
|
|
290
|
+
method: "POST",
|
|
291
|
+
path: "/api/v1/work-adjustments"
|
|
292
|
+
});
|
|
256
293
|
registerWriteTool(api, config, {
|
|
257
294
|
name: "forge_post_insight",
|
|
258
295
|
label: "Forge Post Insight",
|
|
@@ -290,7 +327,7 @@ export function registerForgePluginTools(api, config) {
|
|
|
290
327
|
registerWriteTool(api, config, {
|
|
291
328
|
name: "forge_log_work",
|
|
292
329
|
label: "Forge Log Work",
|
|
293
|
-
description: "Log retroactive work or mark an existing task as completed through the operator work-log flow. Use this when the user already did the work and wants truthful evidence plus XP.",
|
|
330
|
+
description: "Log retroactive work or mark an existing task as completed through the operator work-log flow. Use this when the user already did the work and wants truthful evidence plus XP. Prefer closeoutNote when the summary should survive as a real linked note.",
|
|
294
331
|
parameters: Type.Object({
|
|
295
332
|
taskId: optionalString(),
|
|
296
333
|
title: optionalString(),
|
|
@@ -305,7 +342,8 @@ export function registerForgePluginTools(api, config) {
|
|
|
305
342
|
effort: optionalString(),
|
|
306
343
|
energy: optionalString(),
|
|
307
344
|
points: Type.Optional(Type.Integer({ minimum: 5, maximum: 500 })),
|
|
308
|
-
tagIds: Type.Optional(Type.Array(Type.String()))
|
|
345
|
+
tagIds: Type.Optional(Type.Array(Type.String())),
|
|
346
|
+
closeoutNote: Type.Optional(noteInputSchema())
|
|
309
347
|
}),
|
|
310
348
|
method: "POST",
|
|
311
349
|
path: "/api/v1/operator/log-work"
|
|
@@ -319,6 +357,7 @@ export function registerForgePluginTools(api, config) {
|
|
|
319
357
|
actor: Type.String({ minLength: 1 }),
|
|
320
358
|
timerMode: Type.Optional(Type.Union([Type.Literal("planned"), Type.Literal("unlimited")])),
|
|
321
359
|
plannedDurationSeconds: Type.Optional(Type.Union([Type.Integer({ minimum: 60, maximum: 86400 }), Type.Null()])),
|
|
360
|
+
overrideReason: optionalNullableString(),
|
|
322
361
|
isCurrent: Type.Optional(Type.Boolean()),
|
|
323
362
|
leaseTtlSeconds: Type.Optional(Type.Integer({ minimum: 1, maximum: 14400 })),
|
|
324
363
|
note: Type.Optional(Type.String())
|
|
@@ -332,6 +371,7 @@ export function registerForgePluginTools(api, config) {
|
|
|
332
371
|
actor: typed.actor,
|
|
333
372
|
timerMode: typed.timerMode,
|
|
334
373
|
plannedDurationSeconds: typed.plannedDurationSeconds,
|
|
374
|
+
overrideReason: typed.overrideReason,
|
|
335
375
|
isCurrent: typed.isCurrent,
|
|
336
376
|
leaseTtlSeconds: typed.leaseTtlSeconds,
|
|
337
377
|
note: typed.note
|
|
@@ -384,11 +424,12 @@ export function registerForgePluginTools(api, config) {
|
|
|
384
424
|
api.registerTool({
|
|
385
425
|
name: "forge_complete_task_run",
|
|
386
426
|
label: "Forge Complete Task Run",
|
|
387
|
-
description: "Finish an active task run as completed work and let Forge award the appropriate completion rewards.",
|
|
427
|
+
description: "Finish an active task run as completed work and let Forge award the appropriate completion rewards. Prefer closeoutNote when the work summary should become a real linked note.",
|
|
388
428
|
parameters: Type.Object({
|
|
389
429
|
taskRunId: Type.String({ minLength: 1 }),
|
|
390
430
|
actor: optionalString(),
|
|
391
|
-
note: Type.Optional(Type.String())
|
|
431
|
+
note: Type.Optional(Type.String()),
|
|
432
|
+
closeoutNote: Type.Optional(noteInputSchema())
|
|
392
433
|
}),
|
|
393
434
|
async execute(_toolCallId, params) {
|
|
394
435
|
const typed = params;
|
|
@@ -397,7 +438,8 @@ export function registerForgePluginTools(api, config) {
|
|
|
397
438
|
path: `/api/v1/task-runs/${typed.taskRunId}/complete`,
|
|
398
439
|
body: {
|
|
399
440
|
actor: typed.actor,
|
|
400
|
-
note: typed.note
|
|
441
|
+
note: typed.note,
|
|
442
|
+
closeoutNote: typed.closeoutNote
|
|
401
443
|
}
|
|
402
444
|
}));
|
|
403
445
|
}
|
|
@@ -405,11 +447,12 @@ export function registerForgePluginTools(api, config) {
|
|
|
405
447
|
api.registerTool({
|
|
406
448
|
name: "forge_release_task_run",
|
|
407
449
|
label: "Forge Release Task Run",
|
|
408
|
-
description: "Stop an active task run without completing it. Use this to truthfully stop current work.",
|
|
450
|
+
description: "Stop an active task run without completing it. Use this to truthfully stop current work. Prefer closeoutNote when blockers or handoff context should become a real linked note.",
|
|
409
451
|
parameters: Type.Object({
|
|
410
452
|
taskRunId: Type.String({ minLength: 1 }),
|
|
411
453
|
actor: optionalString(),
|
|
412
|
-
note: Type.Optional(Type.String())
|
|
454
|
+
note: Type.Optional(Type.String()),
|
|
455
|
+
closeoutNote: Type.Optional(noteInputSchema())
|
|
413
456
|
}),
|
|
414
457
|
async execute(_toolCallId, params) {
|
|
415
458
|
const typed = params;
|
|
@@ -418,9 +461,133 @@ export function registerForgePluginTools(api, config) {
|
|
|
418
461
|
path: `/api/v1/task-runs/${typed.taskRunId}/release`,
|
|
419
462
|
body: {
|
|
420
463
|
actor: typed.actor,
|
|
421
|
-
note: typed.note
|
|
464
|
+
note: typed.note,
|
|
465
|
+
closeoutNote: typed.closeoutNote
|
|
422
466
|
}
|
|
423
467
|
}));
|
|
424
468
|
}
|
|
425
469
|
});
|
|
470
|
+
registerReadTool(api, config, {
|
|
471
|
+
name: "forge_get_calendar_overview",
|
|
472
|
+
label: "Forge Calendar Overview",
|
|
473
|
+
description: "Read the calendar domain in one response: provider metadata, connected calendars, Forge-native events, mirrored events, recurring work blocks, and task timeboxes.",
|
|
474
|
+
parameters: Type.Object({
|
|
475
|
+
from: optionalString(),
|
|
476
|
+
to: optionalString()
|
|
477
|
+
}),
|
|
478
|
+
path: (params) => {
|
|
479
|
+
const search = new URLSearchParams();
|
|
480
|
+
if (typeof params.from === "string" && params.from.trim().length > 0) {
|
|
481
|
+
search.set("from", params.from);
|
|
482
|
+
}
|
|
483
|
+
if (typeof params.to === "string" && params.to.trim().length > 0) {
|
|
484
|
+
search.set("to", params.to);
|
|
485
|
+
}
|
|
486
|
+
const suffix = search.size > 0 ? `?${search.toString()}` : "";
|
|
487
|
+
return `/api/v1/calendar/overview${suffix}`;
|
|
488
|
+
}
|
|
489
|
+
});
|
|
490
|
+
registerWriteTool(api, config, {
|
|
491
|
+
name: "forge_connect_calendar_provider",
|
|
492
|
+
label: "Forge Connect Calendar Provider",
|
|
493
|
+
description: "Create a Google, Apple, Exchange Online, or custom CalDAV calendar connection. Use this only for explicit provider-connection requests after discovery choices are known.",
|
|
494
|
+
parameters: Type.Object({
|
|
495
|
+
provider: Type.Union([
|
|
496
|
+
Type.Literal("google"),
|
|
497
|
+
Type.Literal("apple"),
|
|
498
|
+
Type.Literal("caldav"),
|
|
499
|
+
Type.Literal("microsoft")
|
|
500
|
+
]),
|
|
501
|
+
label: Type.String({ minLength: 1 }),
|
|
502
|
+
username: optionalString(),
|
|
503
|
+
clientId: optionalString(),
|
|
504
|
+
clientSecret: optionalString(),
|
|
505
|
+
refreshToken: optionalString(),
|
|
506
|
+
password: optionalString(),
|
|
507
|
+
serverUrl: optionalString(),
|
|
508
|
+
authSessionId: optionalString(),
|
|
509
|
+
selectedCalendarUrls: Type.Optional(Type.Array(Type.String({ minLength: 1 }))),
|
|
510
|
+
forgeCalendarUrl: optionalString(),
|
|
511
|
+
createForgeCalendar: Type.Optional(Type.Boolean())
|
|
512
|
+
}),
|
|
513
|
+
method: "POST",
|
|
514
|
+
path: "/api/v1/calendar/connections"
|
|
515
|
+
});
|
|
516
|
+
api.registerTool({
|
|
517
|
+
name: "forge_sync_calendar_connection",
|
|
518
|
+
label: "Forge Sync Calendar Connection",
|
|
519
|
+
description: "Pull and push changes for one connected calendar provider.",
|
|
520
|
+
parameters: Type.Object({
|
|
521
|
+
connectionId: Type.String({ minLength: 1 })
|
|
522
|
+
}),
|
|
523
|
+
async execute(_toolCallId, params) {
|
|
524
|
+
const typed = params;
|
|
525
|
+
return jsonResult(await runWrite(config, {
|
|
526
|
+
method: "POST",
|
|
527
|
+
path: `/api/v1/calendar/connections/${typed.connectionId}/sync`,
|
|
528
|
+
body: {}
|
|
529
|
+
}));
|
|
530
|
+
}
|
|
531
|
+
});
|
|
532
|
+
registerWriteTool(api, config, {
|
|
533
|
+
name: "forge_create_work_block_template",
|
|
534
|
+
label: "Forge Create Work Block",
|
|
535
|
+
description: "Create a recurring work-block template such as Main Activity, Secondary Activity, Third Activity, Rest, Holiday, or Custom. This is a planning helper; agents can also use forge_create_entities with entityType work_block_template.",
|
|
536
|
+
parameters: Type.Object({
|
|
537
|
+
title: Type.String({ minLength: 1 }),
|
|
538
|
+
kind: Type.Union([
|
|
539
|
+
Type.Literal("main_activity"),
|
|
540
|
+
Type.Literal("secondary_activity"),
|
|
541
|
+
Type.Literal("third_activity"),
|
|
542
|
+
Type.Literal("rest"),
|
|
543
|
+
Type.Literal("holiday"),
|
|
544
|
+
Type.Literal("custom")
|
|
545
|
+
]),
|
|
546
|
+
color: Type.String({ minLength: 1 }),
|
|
547
|
+
timezone: Type.String({ minLength: 1 }),
|
|
548
|
+
weekDays: Type.Array(Type.Integer({ minimum: 0, maximum: 6 })),
|
|
549
|
+
startMinute: Type.Integer({ minimum: 0, maximum: 1440 }),
|
|
550
|
+
endMinute: Type.Integer({ minimum: 0, maximum: 1440 }),
|
|
551
|
+
startsOn: Type.Optional(Type.Union([Type.String({ minLength: 1 }), Type.Null()])),
|
|
552
|
+
endsOn: Type.Optional(Type.Union([Type.String({ minLength: 1 }), Type.Null()])),
|
|
553
|
+
blockingState: Type.Union([
|
|
554
|
+
Type.Literal("allowed"),
|
|
555
|
+
Type.Literal("blocked")
|
|
556
|
+
])
|
|
557
|
+
}),
|
|
558
|
+
method: "POST",
|
|
559
|
+
path: "/api/v1/calendar/work-block-templates"
|
|
560
|
+
});
|
|
561
|
+
registerWriteTool(api, config, {
|
|
562
|
+
name: "forge_recommend_task_timeboxes",
|
|
563
|
+
label: "Forge Recommend Task Timeboxes",
|
|
564
|
+
description: "Suggest future task timeboxes that fit the current calendar rules and current schedule.",
|
|
565
|
+
parameters: Type.Object({
|
|
566
|
+
taskId: Type.String({ minLength: 1 }),
|
|
567
|
+
from: optionalString(),
|
|
568
|
+
to: optionalString(),
|
|
569
|
+
limit: Type.Optional(Type.Integer({ minimum: 1, maximum: 24 }))
|
|
570
|
+
}),
|
|
571
|
+
method: "POST",
|
|
572
|
+
path: "/api/v1/calendar/timeboxes/recommend"
|
|
573
|
+
});
|
|
574
|
+
registerWriteTool(api, config, {
|
|
575
|
+
name: "forge_create_task_timebox",
|
|
576
|
+
label: "Forge Create Task Timebox",
|
|
577
|
+
description: "Create a planned task timebox directly in Forge's calendar domain. This is a planning helper; agents can also use forge_create_entities with entityType task_timebox.",
|
|
578
|
+
parameters: Type.Object({
|
|
579
|
+
taskId: Type.String({ minLength: 1 }),
|
|
580
|
+
projectId: optionalNullableString(),
|
|
581
|
+
title: Type.String({ minLength: 1 }),
|
|
582
|
+
startsAt: Type.String({ minLength: 1 }),
|
|
583
|
+
endsAt: Type.String({ minLength: 1 }),
|
|
584
|
+
source: Type.Optional(Type.Union([
|
|
585
|
+
Type.Literal("manual"),
|
|
586
|
+
Type.Literal("suggested"),
|
|
587
|
+
Type.Literal("live_run")
|
|
588
|
+
]))
|
|
589
|
+
}),
|
|
590
|
+
method: "POST",
|
|
591
|
+
path: "/api/v1/calendar/timeboxes"
|
|
592
|
+
});
|
|
426
593
|
}
|