@akalsey/sapience-goals 0.1.2 → 0.2.1
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/dist/src/events.js +12 -0
- package/dist/src/service.js +13 -0
- package/dist/src/types.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { appendFile, mkdir } from "fs/promises";
|
|
2
|
+
import { dirname } from "path";
|
|
3
|
+
export async function appendEvent(eventsPath, event) {
|
|
4
|
+
try {
|
|
5
|
+
const full = { ...event, ts: event.ts ?? new Date().toISOString() };
|
|
6
|
+
await mkdir(dirname(eventsPath), { recursive: true });
|
|
7
|
+
await appendFile(eventsPath, JSON.stringify(full) + "\n", "utf-8");
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
// Observability must never break the host plugin.
|
|
11
|
+
}
|
|
12
|
+
}
|
package/dist/src/service.js
CHANGED
|
@@ -5,6 +5,7 @@ import { resolveDataPath, generateId, isWithinActiveHours, nextWeeklyDate } from
|
|
|
5
5
|
import { loadGoals, saveGoals, addGoal, updateNextDelivery } from "./goal-store.js";
|
|
6
6
|
import { readNewGoals, savePosition } from "./inbox-reader.js";
|
|
7
7
|
import { deliverDecomposition, deliverWeeklyStatus } from "./delivery.js";
|
|
8
|
+
import { appendEvent } from "./events.js";
|
|
8
9
|
function mergeConfig(raw, workspaceDir) {
|
|
9
10
|
return {
|
|
10
11
|
...DEFAULT_CONFIG,
|
|
@@ -14,6 +15,7 @@ function mergeConfig(raw, workspaceDir) {
|
|
|
14
15
|
...DEFAULT_CONFIG.output,
|
|
15
16
|
...(raw.output ?? {}),
|
|
16
17
|
goalsPath: resolveDataPath(raw.output?.goalsPath, workspaceDir, DEFAULT_CONFIG.output.goalsPath),
|
|
18
|
+
eventsPath: resolveDataPath(raw.output?.eventsPath, workspaceDir, DEFAULT_CONFIG.output.eventsPath),
|
|
17
19
|
},
|
|
18
20
|
inboxPath: resolveDataPath(raw.inboxPath, workspaceDir, DEFAULT_CONFIG.inboxPath),
|
|
19
21
|
inboxPositionPath: resolveDataPath(raw.inboxPositionPath, workspaceDir, DEFAULT_CONFIG.inboxPositionPath),
|
|
@@ -27,6 +29,8 @@ export default definePluginEntry({
|
|
|
27
29
|
name: "Sapience Goals",
|
|
28
30
|
description: "Persistent fuzzy goal tracking with weekly status delivery",
|
|
29
31
|
register(api) {
|
|
32
|
+
if (!api.runtime?.agent?.resolveAgentWorkspaceDir)
|
|
33
|
+
return;
|
|
30
34
|
const workspaceDir = api.runtime.agent.resolveAgentWorkspaceDir(api.pluginConfig);
|
|
31
35
|
const config = mergeConfig(api.pluginConfig, workspaceDir);
|
|
32
36
|
api.registerTool({
|
|
@@ -58,6 +62,7 @@ export default definePluginEntry({
|
|
|
58
62
|
goals = addGoal(goals, goal);
|
|
59
63
|
await saveGoals(goals, config.output.goalsPath);
|
|
60
64
|
await deliverDecomposition(description, api);
|
|
65
|
+
await appendEvent(config.output.eventsPath, { plugin: "goals", type: "goal_created", goal_id: goal.id });
|
|
61
66
|
return { content: [{ type: "text", text: JSON.stringify({ id: goal.id }) }] };
|
|
62
67
|
}
|
|
63
68
|
catch (err) {
|
|
@@ -72,6 +77,7 @@ export default definePluginEntry({
|
|
|
72
77
|
async execute(_id, _params) {
|
|
73
78
|
try {
|
|
74
79
|
if (!isWithinActiveHours(config)) {
|
|
80
|
+
await appendEvent(config.output.eventsPath, { plugin: "goals", type: "check_skipped", reason: "outside_hours" });
|
|
75
81
|
return { content: [{ type: "text", text: "SILENT_REPLY_TOKEN" }] };
|
|
76
82
|
}
|
|
77
83
|
let goals = await loadGoals(config.output.goalsPath);
|
|
@@ -91,17 +97,24 @@ export default definePluginEntry({
|
|
|
91
97
|
};
|
|
92
98
|
goals = addGoal(goals, goal);
|
|
93
99
|
await deliverDecomposition(description, api);
|
|
100
|
+
await appendEvent(config.output.eventsPath, { plugin: "goals", type: "goal_created", goal_id: goal.id });
|
|
94
101
|
}
|
|
95
102
|
if (newDescriptions.length > 0) {
|
|
96
103
|
await savePosition(newPosition, config.inboxPositionPath);
|
|
97
104
|
}
|
|
105
|
+
let delivered = 0;
|
|
98
106
|
for (const goal of goals) {
|
|
99
107
|
if (isWeeklyCheckInDue(goal)) {
|
|
100
108
|
await deliverWeeklyStatus(goal, api);
|
|
109
|
+
delivered++;
|
|
110
|
+
await appendEvent(config.output.eventsPath, { plugin: "goals", type: "status_delivered", goal_id: goal.id });
|
|
101
111
|
goals = updateNextDelivery(goals, goal.id, nextWeeklyDate(config.weeklyCheckInDay, config.weeklyCheckInTime, config.activeHours.timezone));
|
|
102
112
|
}
|
|
103
113
|
}
|
|
104
114
|
await saveGoals(goals, config.output.goalsPath);
|
|
115
|
+
if (newDescriptions.length === 0 && delivered === 0) {
|
|
116
|
+
await appendEvent(config.output.eventsPath, { plugin: "goals", type: "check_skipped", reason: "nothing_due" });
|
|
117
|
+
}
|
|
105
118
|
return { content: [{ type: "text", text: "SILENT_REPLY_TOKEN" }] };
|
|
106
119
|
}
|
|
107
120
|
catch (err) {
|
package/dist/src/types.js
CHANGED
|
@@ -5,5 +5,5 @@ export const DEFAULT_CONFIG = {
|
|
|
5
5
|
weeklyCheckInTime: "09:00",
|
|
6
6
|
inboxPath: "goals/inbox.md",
|
|
7
7
|
inboxPositionPath: "goals/inbox-position.json",
|
|
8
|
-
output: { goalsPath: "goals/goals.json" },
|
|
8
|
+
output: { goalsPath: "goals/goals.json", eventsPath: "sapience/events.jsonl" },
|
|
9
9
|
};
|