@trevonistrevon/pi-loop 0.5.9 → 0.6.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.
Files changed (152) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/README.md +64 -5
  3. package/dist/api.d.ts +11 -0
  4. package/dist/api.js +10 -0
  5. package/dist/commands/loop-command.d.ts +9 -2
  6. package/dist/commands/loop-command.js +81 -51
  7. package/dist/commands/tasks-command.js +3 -3
  8. package/dist/coordinator.d.ts +1 -1
  9. package/dist/index.d.ts +2 -1
  10. package/dist/index.js +89 -19
  11. package/dist/loop-format.d.ts +3 -0
  12. package/dist/loop-format.js +20 -0
  13. package/dist/loop-parse.d.ts +1 -0
  14. package/dist/loop-parse.js +59 -6
  15. package/dist/loop-reducer.d.ts +13 -1
  16. package/dist/loop-reducer.js +26 -0
  17. package/dist/monitor-manager.js +1 -1
  18. package/dist/notification-reducer.d.ts +2 -0
  19. package/dist/reducer-backed-store.d.ts +1 -1
  20. package/dist/reducer-backed-store.js +1 -1
  21. package/dist/rpc/channels.d.ts +73 -0
  22. package/dist/rpc/channels.js +30 -0
  23. package/dist/rpc/cross-extension-rpc.d.ts +59 -0
  24. package/dist/rpc/cross-extension-rpc.js +117 -0
  25. package/dist/runtime/loop-events.d.ts +26 -0
  26. package/dist/runtime/loop-events.js +26 -0
  27. package/dist/runtime/monitor-ondone-runtime.js +1 -1
  28. package/dist/runtime/native-task-rpc.d.ts +22 -0
  29. package/dist/runtime/native-task-rpc.js +50 -0
  30. package/dist/runtime/notification-runtime.d.ts +2 -1
  31. package/dist/runtime/notification-runtime.js +19 -7
  32. package/dist/runtime/task-backlog-runtime.d.ts +5 -1
  33. package/dist/runtime/task-backlog-runtime.js +14 -7
  34. package/dist/runtime/task-mutations.d.ts +39 -0
  35. package/dist/runtime/task-mutations.js +68 -0
  36. package/dist/runtime/task-rpc.d.ts +4 -0
  37. package/dist/runtime/task-rpc.js +40 -58
  38. package/dist/scheduler.js +25 -7
  39. package/dist/store.d.ts +9 -1
  40. package/dist/store.js +57 -0
  41. package/dist/tools/loop-tools.d.ts +8 -0
  42. package/dist/tools/loop-tools.js +105 -15
  43. package/dist/tools/monitor-tools.js +1 -3
  44. package/dist/tools/native-task-tools.d.ts +2 -6
  45. package/dist/tools/native-task-tools.js +25 -55
  46. package/dist/tools/tool-result.d.ts +8 -0
  47. package/dist/tools/tool-result.js +4 -0
  48. package/dist/trigger-system.js +1 -1
  49. package/dist/types.d.ts +24 -1
  50. package/package.json +15 -2
  51. package/src/api.ts +36 -0
  52. package/src/commands/loop-command.ts +100 -55
  53. package/src/commands/tasks-command.ts +3 -3
  54. package/src/coordinator.ts +1 -1
  55. package/src/index.ts +92 -19
  56. package/src/loop-format.ts +22 -0
  57. package/src/loop-parse.ts +62 -8
  58. package/src/loop-reducer.ts +41 -1
  59. package/src/monitor-manager.ts +1 -1
  60. package/src/notification-reducer.ts +3 -0
  61. package/src/reducer-backed-store.ts +3 -3
  62. package/src/rpc/channels.ts +97 -0
  63. package/src/rpc/cross-extension-rpc.ts +152 -0
  64. package/src/runtime/loop-events.ts +60 -0
  65. package/src/runtime/monitor-ondone-runtime.ts +1 -1
  66. package/src/runtime/native-task-rpc.ts +139 -0
  67. package/src/runtime/notification-runtime.ts +21 -8
  68. package/src/runtime/task-backlog-runtime.ts +25 -7
  69. package/src/runtime/task-mutations.ts +103 -0
  70. package/src/runtime/task-rpc.ts +48 -54
  71. package/src/scheduler.ts +25 -8
  72. package/src/store.ts +59 -2
  73. package/src/tools/loop-tools.ts +129 -16
  74. package/src/tools/monitor-tools.ts +1 -4
  75. package/src/tools/native-task-tools.ts +31 -52
  76. package/src/tools/tool-result.ts +4 -0
  77. package/src/trigger-system.ts +5 -5
  78. package/src/types.ts +29 -1
  79. package/.release-please-manifest.json +0 -3
  80. package/AGENTS.md +0 -83
  81. package/CONTRIBUTING.md +0 -69
  82. package/Dockerfile +0 -17
  83. package/benchmarks/experiment-sim.js +0 -30
  84. package/coverage/base.css +0 -224
  85. package/coverage/block-navigation.js +0 -87
  86. package/coverage/coverage-final.json +0 -33
  87. package/coverage/favicon.png +0 -0
  88. package/coverage/index.html +0 -176
  89. package/coverage/prettify.css +0 -1
  90. package/coverage/prettify.js +0 -2
  91. package/coverage/sort-arrow-sprite.png +0 -0
  92. package/coverage/sorter.js +0 -210
  93. package/coverage/src/commands/index.html +0 -131
  94. package/coverage/src/commands/loop-command.ts.html +0 -634
  95. package/coverage/src/commands/tasks-command.ts.html +0 -490
  96. package/coverage/src/coordinator.ts.html +0 -430
  97. package/coverage/src/goal-coordinator.ts.html +0 -259
  98. package/coverage/src/goal-reducer.ts.html +0 -982
  99. package/coverage/src/goal-store.ts.html +0 -742
  100. package/coverage/src/goal-verifier.ts.html +0 -808
  101. package/coverage/src/index.html +0 -386
  102. package/coverage/src/index.ts.html +0 -1111
  103. package/coverage/src/loop-parse.ts.html +0 -574
  104. package/coverage/src/loop-reducer.ts.html +0 -559
  105. package/coverage/src/monitor-completion-coordinator.ts.html +0 -157
  106. package/coverage/src/monitor-manager.ts.html +0 -940
  107. package/coverage/src/monitor-reducer.ts.html +0 -583
  108. package/coverage/src/notification-reducer.ts.html +0 -550
  109. package/coverage/src/reducer-backed-store.ts.html +0 -589
  110. package/coverage/src/runtime/index.html +0 -206
  111. package/coverage/src/runtime/monitor-ondone-runtime.ts.html +0 -310
  112. package/coverage/src/runtime/notification-runtime.ts.html +0 -721
  113. package/coverage/src/runtime/scope.ts.html +0 -196
  114. package/coverage/src/runtime/session-runtime.ts.html +0 -679
  115. package/coverage/src/runtime/task-backlog-runtime.ts.html +0 -574
  116. package/coverage/src/runtime/task-events.ts.html +0 -208
  117. package/coverage/src/runtime/task-rpc.ts.html +0 -541
  118. package/coverage/src/scheduler.ts.html +0 -400
  119. package/coverage/src/store.ts.html +0 -667
  120. package/coverage/src/task-backlog-coordinator.ts.html +0 -181
  121. package/coverage/src/task-reducer.ts.html +0 -550
  122. package/coverage/src/task-store.ts.html +0 -526
  123. package/coverage/src/tools/index.html +0 -146
  124. package/coverage/src/tools/loop-tools.ts.html +0 -1000
  125. package/coverage/src/tools/monitor-tools.ts.html +0 -547
  126. package/coverage/src/tools/native-task-tools.ts.html +0 -556
  127. package/coverage/src/trigger-system.ts.html +0 -547
  128. package/coverage/src/ui/index.html +0 -116
  129. package/coverage/src/ui/widget.ts.html +0 -292
  130. package/dist/goal-coordinator.d.ts +0 -22
  131. package/dist/goal-coordinator.js +0 -28
  132. package/dist/goal-reducer.d.ts +0 -98
  133. package/dist/goal-reducer.js +0 -190
  134. package/dist/goal-store.d.ts +0 -22
  135. package/dist/goal-store.js +0 -188
  136. package/dist/goal-types.d.ts +0 -82
  137. package/dist/goal-types.js +0 -1
  138. package/dist/goal-verifier.d.ts +0 -20
  139. package/dist/goal-verifier.js +0 -198
  140. package/docker-compose.yml +0 -12
  141. package/docs/architecture/goal-state-schema.md +0 -505
  142. package/docs/architecture/state-machine-migration.md +0 -546
  143. package/docs/architecture/state-machine-reducer-event-model.md +0 -823
  144. package/docs/architecture/state-machine-test-matrix.md +0 -249
  145. package/docs/architecture/state-machine-transition-map.md +0 -436
  146. package/release-please-config.json +0 -9
  147. package/src/goal-coordinator.ts +0 -58
  148. package/src/goal-reducer.ts +0 -299
  149. package/src/goal-store.ts +0 -219
  150. package/src/goal-types.ts +0 -104
  151. package/src/goal-verifier.ts +0 -241
  152. package/vitest.config.ts +0 -29
@@ -1,58 +0,0 @@
1
- import type { ReducerEffect, ReducerEvent } from "./coordinator.js";
2
- import type { GoalReducerState } from "./goal-types.js";
3
- import { verifyGoal } from "./goal-verifier.js";
4
- import type { LoopReducerState } from "./loop-reducer.js";
5
- import type { MonitorReducerState } from "./monitor-reducer.js";
6
- import type { TaskReducerState } from "./task-reducer.js";
7
-
8
- export type GoalVerificationRequestedEvent = ReducerEvent<
9
- "GOAL_VERIFICATION_REQUESTED",
10
- { id: string }
11
- >;
12
-
13
- export interface GoalCoordinatorSnapshot {
14
- goalState: GoalReducerState;
15
- taskState: TaskReducerState;
16
- loopState: LoopReducerState;
17
- monitorState: MonitorReducerState;
18
- }
19
-
20
- export function reduceGoalVerificationRequest(
21
- event: GoalVerificationRequestedEvent,
22
- snapshot: GoalCoordinatorSnapshot,
23
- ): ReducerEffect[] {
24
- if (event.type !== "GOAL_VERIFICATION_REQUESTED") return [];
25
-
26
- const goal = snapshot.goalState.goalsById[event.payload.id];
27
- if (!goal) return [];
28
-
29
- return verifyGoal({
30
- goal,
31
- taskState: snapshot.taskState,
32
- loopState: snapshot.loopState,
33
- monitorState: snapshot.monitorState,
34
- at: event.at,
35
- }).effects;
36
- }
37
-
38
- export interface GoalCoordinatorOptions {
39
- getGoalState: () => GoalReducerState;
40
- getTaskState: () => TaskReducerState;
41
- getLoopState: () => LoopReducerState;
42
- getMonitorState: () => MonitorReducerState;
43
- }
44
-
45
- export function createGoalCoordinatorReducer(options: GoalCoordinatorOptions) {
46
- const { getGoalState, getTaskState, getLoopState, getMonitorState } = options;
47
-
48
- return (event: ReducerEvent): ReducerEffect[] => {
49
- if (event.type !== "GOAL_VERIFICATION_REQUESTED") return [];
50
-
51
- return reduceGoalVerificationRequest(event as GoalVerificationRequestedEvent, {
52
- goalState: getGoalState(),
53
- taskState: getTaskState(),
54
- loopState: getLoopState(),
55
- monitorState: getMonitorState(),
56
- });
57
- };
58
- }
@@ -1,299 +0,0 @@
1
- import type {
2
- GoalCriteria,
3
- GoalEntry,
4
- GoalProgressSnapshot,
5
- GoalReducerState,
6
- GoalScope,
7
- GoalVerificationState,
8
- } from "./goal-types.js";
9
-
10
- export type GoalReducerEvent =
11
- | {
12
- type: "GOAL_CREATED";
13
- at: number;
14
- source: "tool" | "command" | "scheduler" | "eventbus" | "monitor" | "session" | "coordinator" | "system";
15
- entityType?: "goal";
16
- entityId?: string;
17
- payload: {
18
- title: string;
19
- description: string;
20
- scope: GoalScope;
21
- criteria: GoalCriteria;
22
- metadata?: Record<string, unknown>;
23
- };
24
- }
25
- | {
26
- type: "GOAL_ACTIVATED" | "GOAL_VERIFICATION_STARTED" | "GOAL_UNBLOCKED";
27
- at: number;
28
- source: "tool" | "command" | "scheduler" | "eventbus" | "monitor" | "session" | "coordinator" | "system";
29
- entityType?: "goal";
30
- entityId?: string;
31
- payload: { id: string };
32
- }
33
- | {
34
- type: "GOAL_PROGRESS_RECORDED";
35
- at: number;
36
- source: "tool" | "command" | "scheduler" | "eventbus" | "monitor" | "session" | "coordinator" | "system";
37
- entityType?: "goal";
38
- entityId?: string;
39
- payload: { id: string; progress: GoalProgressSnapshot };
40
- }
41
- | {
42
- type: "GOAL_VERIFICATION_PASSED" | "GOAL_VERIFICATION_FAILED" | "GOAL_BLOCKED" | "GOAL_FAILED";
43
- at: number;
44
- source: "tool" | "command" | "scheduler" | "eventbus" | "monitor" | "session" | "coordinator" | "system";
45
- entityType?: "goal";
46
- entityId?: string;
47
- payload: { id: string; reason: string; progress?: GoalProgressSnapshot };
48
- }
49
- | {
50
- type: "GOAL_SATISFIED" | "GOAL_ARCHIVED";
51
- at: number;
52
- source: "tool" | "command" | "scheduler" | "eventbus" | "monitor" | "session" | "coordinator" | "system";
53
- entityType?: "goal";
54
- entityId?: string;
55
- payload: { id: string; reason?: string };
56
- }
57
- | {
58
- type: "GOAL_UPDATED";
59
- at: number;
60
- source: "tool" | "command" | "scheduler" | "eventbus" | "monitor" | "session" | "coordinator" | "system";
61
- entityType?: "goal";
62
- entityId?: string;
63
- payload: {
64
- id: string;
65
- title?: string;
66
- description?: string;
67
- scope?: GoalScope;
68
- criteria?: GoalCriteria;
69
- metadata?: Record<string, unknown>;
70
- };
71
- };
72
-
73
- export type GoalReducerEffect =
74
- | {
75
- type: "PERSIST_GOAL";
76
- entityType: "goal";
77
- entityId: string;
78
- payload: { goal: GoalEntry };
79
- }
80
- | {
81
- type: "REQUEST_GOAL_VERIFICATION";
82
- entityType: "goal";
83
- entityId: string;
84
- payload: { id: string };
85
- }
86
- | {
87
- // Diagnostic: a transition was dropped because the goal is in a terminal
88
- // state. Surfaced (rather than silently ignored) so the effect sink can log
89
- // it. Carries no state change.
90
- type: "GOAL_TRANSITION_REJECTED";
91
- entityType: "goal";
92
- entityId: string;
93
- payload: { id: string; status: GoalEntry["status"]; attempted: string };
94
- };
95
-
96
- export interface GoalReduceResult {
97
- state: GoalReducerState;
98
- effects: GoalReducerEffect[];
99
- }
100
-
101
- function cloneState(state: GoalReducerState): GoalReducerState {
102
- return {
103
- nextId: state.nextId,
104
- goalsById: { ...state.goalsById },
105
- };
106
- }
107
-
108
- function emptyProgress(): GoalProgressSnapshot {
109
- return {
110
- totalTasks: 0,
111
- pendingTasks: 0,
112
- inProgressTasks: 0,
113
- completedTasks: 0,
114
- activeLoops: 0,
115
- pausedLoops: 0,
116
- runningMonitors: 0,
117
- completedMonitors: 0,
118
- erroredMonitors: 0,
119
- stoppedMonitors: 0,
120
- };
121
- }
122
-
123
- function emptyVerification(): GoalVerificationState {
124
- return {
125
- attempts: 0,
126
- passes: 0,
127
- failures: 0,
128
- };
129
- }
130
-
131
- function persist(goal: GoalEntry): GoalReducerEffect {
132
- return {
133
- type: "PERSIST_GOAL",
134
- entityType: "goal",
135
- entityId: goal.id,
136
- payload: { goal },
137
- };
138
- }
139
-
140
- function isTerminal(goal: GoalEntry): boolean {
141
- return goal.status === "satisfied" || goal.status === "failed" || goal.status === "archived";
142
- }
143
-
144
- export function reduceGoalState(state: GoalReducerState, event: GoalReducerEvent): GoalReduceResult {
145
- if (event.type === "GOAL_CREATED") {
146
- const next = cloneState(state);
147
- const id = String(next.nextId++);
148
- const goal: GoalEntry = {
149
- id,
150
- title: event.payload.title,
151
- description: event.payload.description,
152
- status: "pending",
153
- verificationStatus: "unknown",
154
- createdAt: event.at,
155
- updatedAt: event.at,
156
- scope: event.payload.scope,
157
- criteria: event.payload.criteria,
158
- progress: emptyProgress(),
159
- verification: emptyVerification(),
160
- metadata: event.payload.metadata,
161
- };
162
- next.goalsById[id] = goal;
163
- return {
164
- state: next,
165
- effects: [persist(goal)],
166
- };
167
- }
168
-
169
- const id = event.payload.id;
170
- const current = state.goalsById[id];
171
- if (!current) return { state, effects: [] };
172
- if (isTerminal(current) && event.type !== "GOAL_ARCHIVED") {
173
- return {
174
- state,
175
- effects: [{
176
- type: "GOAL_TRANSITION_REJECTED",
177
- entityType: "goal",
178
- entityId: id,
179
- payload: { id, status: current.status, attempted: event.type },
180
- }],
181
- };
182
- }
183
-
184
- const next = cloneState(state);
185
- const goal: GoalEntry = {
186
- ...current,
187
- progress: { ...current.progress },
188
- verification: { ...current.verification },
189
- };
190
-
191
- let extraEffects: GoalReducerEffect[] = [];
192
-
193
- if (event.type === "GOAL_ACTIVATED") {
194
- goal.status = "active";
195
- goal.activatedAt ??= event.at;
196
- goal.updatedAt = event.at;
197
- extraEffects = [{
198
- type: "REQUEST_GOAL_VERIFICATION",
199
- entityType: "goal",
200
- entityId: id,
201
- payload: { id },
202
- }];
203
- }
204
-
205
- if (event.type === "GOAL_PROGRESS_RECORDED") {
206
- goal.progress = event.payload.progress;
207
- goal.updatedAt = event.at;
208
- }
209
-
210
- if (event.type === "GOAL_VERIFICATION_STARTED") {
211
- goal.verificationStatus = "checking";
212
- goal.verification.attempts += 1;
213
- goal.verification.lastCheckedAt = event.at;
214
- goal.updatedAt = event.at;
215
- }
216
-
217
- if (event.type === "GOAL_VERIFICATION_PASSED") {
218
- if (event.payload.progress) goal.progress = event.payload.progress;
219
- goal.status = "satisfied";
220
- goal.verificationStatus = "verified";
221
- goal.verification.passes += 1;
222
- goal.verification.lastPassedAt = event.at;
223
- goal.verification.lastCheckedAt = event.at;
224
- goal.verification.lastReason = event.payload.reason;
225
- goal.resolvedAt = event.at;
226
- goal.updatedAt = event.at;
227
- }
228
-
229
- if (event.type === "GOAL_VERIFICATION_FAILED") {
230
- if (event.payload.progress) goal.progress = event.payload.progress;
231
- goal.verificationStatus = "unverified";
232
- goal.verification.failures += 1;
233
- goal.verification.lastFailedAt = event.at;
234
- goal.verification.lastCheckedAt = event.at;
235
- goal.verification.lastReason = event.payload.reason;
236
- if (goal.status === "pending") goal.status = "active";
237
- goal.updatedAt = event.at;
238
- }
239
-
240
- if (event.type === "GOAL_BLOCKED") {
241
- if (event.payload.progress) goal.progress = event.payload.progress;
242
- goal.status = "blocked";
243
- goal.verificationStatus = "inconclusive";
244
- goal.verification.failures += 1;
245
- goal.verification.lastFailedAt = event.at;
246
- goal.verification.lastCheckedAt = event.at;
247
- goal.verification.lastReason = event.payload.reason;
248
- goal.updatedAt = event.at;
249
- }
250
-
251
- if (event.type === "GOAL_UNBLOCKED") {
252
- goal.status = "active";
253
- goal.updatedAt = event.at;
254
- }
255
-
256
- if (event.type === "GOAL_SATISFIED") {
257
- goal.status = "satisfied";
258
- goal.verificationStatus = "verified";
259
- goal.verification.lastReason = event.payload.reason ?? goal.verification.lastReason;
260
- goal.resolvedAt = event.at;
261
- goal.updatedAt = event.at;
262
- }
263
-
264
- if (event.type === "GOAL_FAILED") {
265
- if (event.payload.progress) goal.progress = event.payload.progress;
266
- goal.status = "failed";
267
- goal.verificationStatus = "unverified";
268
- goal.verification.failures += 1;
269
- goal.verification.lastFailedAt = event.at;
270
- goal.verification.lastCheckedAt = event.at;
271
- goal.verification.lastReason = event.payload.reason;
272
- goal.resolvedAt = event.at;
273
- goal.updatedAt = event.at;
274
- }
275
-
276
- if (event.type === "GOAL_ARCHIVED") {
277
- goal.status = "archived";
278
- goal.resolvedAt = event.at;
279
- goal.updatedAt = event.at;
280
- if (event.payload.reason !== undefined) {
281
- goal.verification.lastReason = event.payload.reason;
282
- }
283
- }
284
-
285
- if (event.type === "GOAL_UPDATED") {
286
- if (event.payload.title !== undefined) goal.title = event.payload.title;
287
- if (event.payload.description !== undefined) goal.description = event.payload.description;
288
- if (event.payload.scope !== undefined) goal.scope = event.payload.scope;
289
- if (event.payload.criteria !== undefined) goal.criteria = event.payload.criteria;
290
- if (event.payload.metadata !== undefined) goal.metadata = event.payload.metadata;
291
- goal.updatedAt = event.at;
292
- }
293
-
294
- next.goalsById[id] = goal;
295
- return {
296
- state: next,
297
- effects: [persist(goal), ...extraEffects],
298
- };
299
- }
package/src/goal-store.ts DELETED
@@ -1,219 +0,0 @@
1
- import { homedir } from "node:os";
2
- import { join } from "node:path";
3
- import { type GoalReducerEvent, reduceGoalState } from "./goal-reducer.js";
4
- import type {
5
- GoalCriteria,
6
- GoalEntry,
7
- GoalProgressSnapshot,
8
- GoalReducerState,
9
- GoalScope,
10
- GoalStoreData,
11
- } from "./goal-types.js";
12
- import { ReducerBackedStore } from "./reducer-backed-store.js";
13
-
14
- const GOALS_DIR = join(homedir(), ".pi", "goals");
15
- const MAX_GOALS = 200;
16
-
17
- export class GoalStore extends ReducerBackedStore<GoalEntry, GoalReducerState, GoalReducerEvent, GoalStoreData> {
18
- constructor(listIdOrPath?: string) {
19
- super(
20
- {
21
- baseDir: GOALS_DIR,
22
- reduce: (state, event) => reduceGoalState(state, event),
23
- toReducerState: (nextId, entries) => ({ nextId, goalsById: Object.fromEntries(entries.entries()) }),
24
- fromReducerState: (state) => ({ nextId: state.nextId, entries: new Map(Object.entries(state.goalsById)) }),
25
- serialize: (nextId, entries) => ({ nextId, goals: Array.from(entries.values()) }),
26
- deserialize: (data) => ({ nextId: data.nextId, entries: new Map(data.goals.map((g) => [g.id, g])) }),
27
- },
28
- listIdOrPath,
29
- );
30
- }
31
-
32
- create(
33
- title: string,
34
- description: string,
35
- scope: GoalScope,
36
- criteria: GoalCriteria,
37
- metadata?: Record<string, unknown>,
38
- ): GoalEntry {
39
- return this.withLock(() => {
40
- if (this.entries.size >= MAX_GOALS) {
41
- throw new Error(`Maximum of ${MAX_GOALS} goals reached. Archive some before creating new ones.`);
42
- }
43
- this.applyReducerEvent({
44
- type: "GOAL_CREATED",
45
- at: Date.now(),
46
- source: "tool",
47
- entityType: "goal",
48
- payload: {
49
- title,
50
- description,
51
- scope,
52
- criteria,
53
- metadata,
54
- },
55
- });
56
- return this.entries.get(String(this.nextId - 1))!;
57
- });
58
- }
59
-
60
- activate(id: string): GoalEntry | undefined {
61
- return this.withLock(() => {
62
- if (!this.entries.has(id)) return undefined;
63
- this.applyReducerEvent({
64
- type: "GOAL_ACTIVATED",
65
- at: Date.now(),
66
- source: "tool",
67
- entityType: "goal",
68
- entityId: id,
69
- payload: { id },
70
- });
71
- return this.entries.get(id);
72
- });
73
- }
74
-
75
- recordProgress(id: string, progress: GoalProgressSnapshot): GoalEntry | undefined {
76
- return this.withLock(() => {
77
- if (!this.entries.has(id)) return undefined;
78
- this.applyReducerEvent({
79
- type: "GOAL_PROGRESS_RECORDED",
80
- at: Date.now(),
81
- source: "coordinator",
82
- entityType: "goal",
83
- entityId: id,
84
- payload: { id, progress },
85
- });
86
- return this.entries.get(id);
87
- });
88
- }
89
-
90
- markVerificationStarted(id: string): GoalEntry | undefined {
91
- return this.withLock(() => {
92
- if (!this.entries.has(id)) return undefined;
93
- this.applyReducerEvent({
94
- type: "GOAL_VERIFICATION_STARTED",
95
- at: Date.now(),
96
- source: "coordinator",
97
- entityType: "goal",
98
- entityId: id,
99
- payload: { id },
100
- });
101
- return this.entries.get(id);
102
- });
103
- }
104
-
105
- markVerified(id: string, reason: string, progress?: GoalProgressSnapshot): GoalEntry | undefined {
106
- return this.withLock(() => {
107
- if (!this.entries.has(id)) return undefined;
108
- this.applyReducerEvent({
109
- type: "GOAL_VERIFICATION_PASSED",
110
- at: Date.now(),
111
- source: "coordinator",
112
- entityType: "goal",
113
- entityId: id,
114
- payload: { id, reason, progress },
115
- });
116
- return this.entries.get(id);
117
- });
118
- }
119
-
120
- markFailed(id: string, reason: string, progress?: GoalProgressSnapshot): GoalEntry | undefined {
121
- return this.withLock(() => {
122
- if (!this.entries.has(id)) return undefined;
123
- this.applyReducerEvent({
124
- type: "GOAL_FAILED",
125
- at: Date.now(),
126
- source: "coordinator",
127
- entityType: "goal",
128
- entityId: id,
129
- payload: { id, reason, progress },
130
- });
131
- return this.entries.get(id);
132
- });
133
- }
134
-
135
- markBlocked(id: string, reason: string, progress?: GoalProgressSnapshot): GoalEntry | undefined {
136
- return this.withLock(() => {
137
- if (!this.entries.has(id)) return undefined;
138
- this.applyReducerEvent({
139
- type: "GOAL_BLOCKED",
140
- at: Date.now(),
141
- source: "coordinator",
142
- entityType: "goal",
143
- entityId: id,
144
- payload: { id, reason, progress },
145
- });
146
- return this.entries.get(id);
147
- });
148
- }
149
-
150
- unblock(id: string): GoalEntry | undefined {
151
- return this.withLock(() => {
152
- if (!this.entries.has(id)) return undefined;
153
- this.applyReducerEvent({
154
- type: "GOAL_UNBLOCKED",
155
- at: Date.now(),
156
- source: "coordinator",
157
- entityType: "goal",
158
- entityId: id,
159
- payload: { id },
160
- });
161
- return this.entries.get(id);
162
- });
163
- }
164
-
165
- updateDetails(
166
- id: string,
167
- fields: {
168
- title?: string;
169
- description?: string;
170
- scope?: GoalScope;
171
- criteria?: GoalCriteria;
172
- metadata?: Record<string, unknown>;
173
- },
174
- ): GoalEntry | undefined {
175
- return this.withLock(() => {
176
- if (!this.entries.has(id)) return undefined;
177
- if (
178
- fields.title === undefined
179
- && fields.description === undefined
180
- && fields.scope === undefined
181
- && fields.criteria === undefined
182
- && fields.metadata === undefined
183
- ) {
184
- return this.entries.get(id);
185
- }
186
- this.applyReducerEvent({
187
- type: "GOAL_UPDATED",
188
- at: Date.now(),
189
- source: "tool",
190
- entityType: "goal",
191
- entityId: id,
192
- payload: {
193
- id,
194
- title: fields.title,
195
- description: fields.description,
196
- scope: fields.scope,
197
- criteria: fields.criteria,
198
- metadata: fields.metadata,
199
- },
200
- });
201
- return this.entries.get(id);
202
- });
203
- }
204
-
205
- archive(id: string, reason?: string): GoalEntry | undefined {
206
- return this.withLock(() => {
207
- if (!this.entries.has(id)) return undefined;
208
- this.applyReducerEvent({
209
- type: "GOAL_ARCHIVED",
210
- at: Date.now(),
211
- source: "tool",
212
- entityType: "goal",
213
- entityId: id,
214
- payload: { id, reason },
215
- });
216
- return this.entries.get(id);
217
- });
218
- }
219
- }
package/src/goal-types.ts DELETED
@@ -1,104 +0,0 @@
1
- export type GoalStatus =
2
- | "pending"
3
- | "active"
4
- | "satisfied"
5
- | "blocked"
6
- | "failed"
7
- | "archived";
8
-
9
- export type GoalVerificationStatus =
10
- | "unknown"
11
- | "checking"
12
- | "verified"
13
- | "unverified"
14
- | "inconclusive";
15
-
16
- export interface GoalScope {
17
- taskIds?: string[];
18
- loopIds?: string[];
19
- monitorIds?: string[];
20
- tags?: string[];
21
- subjectPrefixes?: string[];
22
- includeFutureMatchingTasks?: boolean;
23
- includeFutureMatchingLoops?: boolean;
24
- includeFutureMatchingMonitors?: boolean;
25
- }
26
-
27
- export interface GoalSuccessCriteria {
28
- minCompletedTasks?: number;
29
- requiredTaskIds?: string[];
30
- requiredMonitorIdsCompleted?: string[];
31
- requiredLoopIdsPresent?: string[];
32
- requireNoPendingTasksInScope?: boolean;
33
- requireLatestVerificationPass?: boolean;
34
- }
35
-
36
- export interface GoalFailureCriteria {
37
- anyMonitorIdsErrored?: string[];
38
- maxVerificationFailures?: number;
39
- failIfTaskIdsDeleted?: string[];
40
- }
41
-
42
- export interface GoalBlockedCriteria {
43
- blockedIfAllTasksCompletedButVerificationFails?: boolean;
44
- blockedIfNoScopedProgressSinceMs?: number;
45
- blockedIfRequiredLoopMissing?: boolean;
46
- }
47
-
48
- export interface GoalCriteria {
49
- success: GoalSuccessCriteria;
50
- failure?: GoalFailureCriteria;
51
- blocked?: GoalBlockedCriteria;
52
- }
53
-
54
- export interface GoalProgressSnapshot {
55
- totalTasks: number;
56
- pendingTasks: number;
57
- inProgressTasks: number;
58
- completedTasks: number;
59
- activeLoops: number;
60
- pausedLoops: number;
61
- runningMonitors: number;
62
- completedMonitors: number;
63
- erroredMonitors: number;
64
- stoppedMonitors: number;
65
- lastProgressAt?: number;
66
- }
67
-
68
- export interface GoalVerificationState {
69
- attempts: number;
70
- passes: number;
71
- failures: number;
72
- lastCheckedAt?: number;
73
- lastPassedAt?: number;
74
- lastFailedAt?: number;
75
- lastReason?: string;
76
- nextCheckAfter?: number;
77
- }
78
-
79
- export interface GoalEntry {
80
- id: string;
81
- title: string;
82
- description: string;
83
- status: GoalStatus;
84
- verificationStatus: GoalVerificationStatus;
85
- createdAt: number;
86
- updatedAt: number;
87
- activatedAt?: number;
88
- resolvedAt?: number;
89
- scope: GoalScope;
90
- criteria: GoalCriteria;
91
- progress: GoalProgressSnapshot;
92
- verification: GoalVerificationState;
93
- metadata?: Record<string, unknown>;
94
- }
95
-
96
- export interface GoalReducerState {
97
- nextId: number;
98
- goalsById: Record<string, GoalEntry>;
99
- }
100
-
101
- export interface GoalStoreData {
102
- nextId: number;
103
- goals: GoalEntry[];
104
- }