@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,241 +0,0 @@
1
- import type { ReducerEffect, ReducerEvent } from "./coordinator.js";
2
- import type { GoalEntry, GoalProgressSnapshot } from "./goal-types.js";
3
- import type { LoopReducerState } from "./loop-reducer.js";
4
- import type { MonitorReducerState } from "./monitor-reducer.js";
5
- import type { TaskReducerState } from "./task-reducer.js";
6
- import type { TaskEntry } from "./task-types.js";
7
- import type { LoopEntry, MonitorEntry } from "./types.js";
8
-
9
- export interface GoalVerifierInput {
10
- goal: GoalEntry;
11
- taskState: TaskReducerState;
12
- loopState: LoopReducerState;
13
- monitorState: MonitorReducerState;
14
- at: number;
15
- }
16
-
17
- export interface GoalVerifierResult {
18
- progress: GoalProgressSnapshot;
19
- verdict: "passed" | "failed" | "blocked";
20
- reason: string;
21
- effects: ReducerEffect[];
22
- }
23
-
24
- function uniqueById<T extends { id: string }>(items: T[]): T[] {
25
- const seen = new Set<string>();
26
- const result: T[] = [];
27
- for (const item of items) {
28
- if (seen.has(item.id)) continue;
29
- seen.add(item.id);
30
- result.push(item);
31
- }
32
- return result;
33
- }
34
-
35
- function selectTasks(goal: GoalEntry, taskState: TaskReducerState): TaskEntry[] {
36
- const selected: TaskEntry[] = [];
37
- for (const id of goal.scope.taskIds ?? []) {
38
- const task = taskState.tasksById[id];
39
- if (task) selected.push(task);
40
- }
41
- for (const prefix of goal.scope.subjectPrefixes ?? []) {
42
- for (const task of Object.values(taskState.tasksById)) {
43
- if (task.subject.startsWith(prefix)) selected.push(task);
44
- }
45
- }
46
- return uniqueById(selected);
47
- }
48
-
49
- function selectLoops(goal: GoalEntry, loopState: LoopReducerState): LoopEntry[] {
50
- const selected: LoopEntry[] = [];
51
- for (const id of goal.scope.loopIds ?? []) {
52
- const loop = loopState.loopsById[id];
53
- if (loop) selected.push(loop);
54
- }
55
- return uniqueById(selected);
56
- }
57
-
58
- function selectMonitors(goal: GoalEntry, monitorState: MonitorReducerState): MonitorEntry[] {
59
- const selected: MonitorEntry[] = [];
60
- for (const id of goal.scope.monitorIds ?? []) {
61
- const monitor = monitorState.monitorsById[id];
62
- if (monitor) selected.push(monitor);
63
- }
64
- return uniqueById(selected);
65
- }
66
-
67
- export function projectGoalProgress(
68
- goal: GoalEntry,
69
- taskState: TaskReducerState,
70
- loopState: LoopReducerState,
71
- monitorState: MonitorReducerState,
72
- ): GoalProgressSnapshot {
73
- const tasks = selectTasks(goal, taskState);
74
- const loops = selectLoops(goal, loopState);
75
- const monitors = selectMonitors(goal, monitorState);
76
-
77
- const timestamps: number[] = [];
78
- for (const task of tasks) timestamps.push(task.updatedAt);
79
- for (const loop of loops) timestamps.push(loop.updatedAt);
80
- for (const monitor of monitors) timestamps.push(monitor.completedAt ?? monitor.startedAt);
81
-
82
- return {
83
- totalTasks: tasks.length,
84
- pendingTasks: tasks.filter(task => task.status === "pending").length,
85
- inProgressTasks: tasks.filter(task => task.status === "in_progress").length,
86
- completedTasks: tasks.filter(task => task.status === "completed").length,
87
- activeLoops: loops.filter(loop => loop.status === "active").length,
88
- pausedLoops: loops.filter(loop => loop.status === "paused").length,
89
- runningMonitors: monitors.filter(monitor => monitor.status === "running").length,
90
- completedMonitors: monitors.filter(monitor => monitor.status === "completed").length,
91
- erroredMonitors: monitors.filter(monitor => monitor.status === "error").length,
92
- stoppedMonitors: monitors.filter(monitor => monitor.status === "stopped").length,
93
- lastProgressAt: timestamps.length > 0 ? Math.max(...timestamps) : undefined,
94
- };
95
- }
96
-
97
- function dispatchEffect(event: ReducerEvent): ReducerEffect<"DISPATCH_EVENT", { event: ReducerEvent }> {
98
- return {
99
- type: "DISPATCH_EVENT",
100
- entityType: "goal",
101
- entityId: event.entityId,
102
- payload: { event },
103
- };
104
- }
105
-
106
- function buildEffects(goal: GoalEntry, at: number, progress: GoalProgressSnapshot, resultType: string, reason: string) {
107
- return [
108
- dispatchEffect({
109
- type: "GOAL_VERIFICATION_STARTED",
110
- at,
111
- source: "coordinator",
112
- entityType: "goal",
113
- entityId: goal.id,
114
- payload: { id: goal.id },
115
- }),
116
- dispatchEffect({
117
- type: "GOAL_PROGRESS_RECORDED",
118
- at,
119
- source: "coordinator",
120
- entityType: "goal",
121
- entityId: goal.id,
122
- payload: { id: goal.id, progress },
123
- }),
124
- dispatchEffect({
125
- type: resultType,
126
- at,
127
- source: "coordinator",
128
- entityType: "goal",
129
- entityId: goal.id,
130
- payload: { id: goal.id, reason, progress },
131
- }),
132
- ];
133
- }
134
-
135
- export function verifyGoal(input: GoalVerifierInput): GoalVerifierResult {
136
- const { goal, taskState, loopState, monitorState, at } = input;
137
- const progress = projectGoalProgress(goal, taskState, loopState, monitorState);
138
-
139
- if (goal.criteria.failure?.maxVerificationFailures !== undefined
140
- && goal.verification.failures >= goal.criteria.failure.maxVerificationFailures) {
141
- return {
142
- progress,
143
- verdict: "failed",
144
- reason: "maximum verification failures reached",
145
- effects: buildEffects(goal, at, progress, "GOAL_FAILED", "maximum verification failures reached"),
146
- };
147
- }
148
-
149
- for (const monitorId of goal.criteria.failure?.anyMonitorIdsErrored ?? []) {
150
- if (monitorState.monitorsById[monitorId]?.status === "error") {
151
- return {
152
- progress,
153
- verdict: "failed",
154
- reason: `monitor #${monitorId} errored`,
155
- effects: buildEffects(goal, at, progress, "GOAL_FAILED", `monitor #${monitorId} errored`),
156
- };
157
- }
158
- }
159
-
160
- for (const taskId of goal.criteria.failure?.failIfTaskIdsDeleted ?? []) {
161
- if (!taskState.tasksById[taskId]) {
162
- return {
163
- progress,
164
- verdict: "failed",
165
- reason: `task #${taskId} missing`,
166
- effects: buildEffects(goal, at, progress, "GOAL_FAILED", `task #${taskId} missing`),
167
- };
168
- }
169
- }
170
-
171
- const requiredTasksDone = (goal.criteria.success.requiredTaskIds ?? [])
172
- .every(taskId => taskState.tasksById[taskId]?.status === "completed");
173
- const requiredMonitorsDone = (goal.criteria.success.requiredMonitorIdsCompleted ?? [])
174
- .every(monitorId => monitorState.monitorsById[monitorId]?.status === "completed");
175
- const requiredLoopsPresent = (goal.criteria.success.requiredLoopIdsPresent ?? [])
176
- .every(loopId => Boolean(loopState.loopsById[loopId]));
177
- const minCompletedTasksMet = progress.completedTasks >= (goal.criteria.success.minCompletedTasks ?? 0);
178
- const noPendingWork = !goal.criteria.success.requireNoPendingTasksInScope
179
- || (progress.pendingTasks === 0 && progress.inProgressTasks === 0);
180
- const latestVerificationPass = !goal.criteria.success.requireLatestVerificationPass
181
- || goal.verificationStatus === "verified";
182
-
183
- const success = requiredTasksDone
184
- && requiredMonitorsDone
185
- && requiredLoopsPresent
186
- && minCompletedTasksMet
187
- && noPendingWork
188
- && latestVerificationPass;
189
-
190
- if (success) {
191
- return {
192
- progress,
193
- verdict: "passed",
194
- reason: "success criteria satisfied",
195
- effects: buildEffects(goal, at, progress, "GOAL_VERIFICATION_PASSED", "success criteria satisfied"),
196
- };
197
- }
198
-
199
- if (goal.criteria.blocked?.blockedIfRequiredLoopMissing && !requiredLoopsPresent) {
200
- return {
201
- progress,
202
- verdict: "blocked",
203
- reason: "required loop missing",
204
- effects: buildEffects(goal, at, progress, "GOAL_BLOCKED", "required loop missing"),
205
- };
206
- }
207
-
208
- if (
209
- goal.criteria.blocked?.blockedIfNoScopedProgressSinceMs !== undefined
210
- && progress.lastProgressAt !== undefined
211
- && at - progress.lastProgressAt >= goal.criteria.blocked.blockedIfNoScopedProgressSinceMs
212
- ) {
213
- return {
214
- progress,
215
- verdict: "blocked",
216
- reason: "no scoped progress within configured interval",
217
- effects: buildEffects(goal, at, progress, "GOAL_BLOCKED", "no scoped progress within configured interval"),
218
- };
219
- }
220
-
221
- if (
222
- goal.criteria.blocked?.blockedIfAllTasksCompletedButVerificationFails
223
- && progress.totalTasks > 0
224
- && progress.pendingTasks === 0
225
- && progress.inProgressTasks === 0
226
- ) {
227
- return {
228
- progress,
229
- verdict: "blocked",
230
- reason: "all scoped tasks completed but verification has not passed",
231
- effects: buildEffects(goal, at, progress, "GOAL_BLOCKED", "all scoped tasks completed but verification has not passed"),
232
- };
233
- }
234
-
235
- return {
236
- progress,
237
- verdict: "failed",
238
- reason: "success criteria not yet satisfied",
239
- effects: buildEffects(goal, at, progress, "GOAL_VERIFICATION_FAILED", "success criteria not yet satisfied"),
240
- };
241
- }
package/vitest.config.ts DELETED
@@ -1,29 +0,0 @@
1
- import { defineConfig } from "vitest/config";
2
-
3
- export default defineConfig({
4
- test: {
5
- environment: "node",
6
- include: ["test/**/*.test.ts"],
7
- exclude: ["node_modules", "dist"],
8
- // CI runners are slower than local; 15s gives real-child-process
9
- // tests (monitor stop, lifecycle) enough headroom.
10
- testTimeout: 15000,
11
- hookTimeout: 15000,
12
- coverage: {
13
- provider: "v8",
14
- reporter: ["text-summary", "html", "json"],
15
- include: ["src/**/*.ts"],
16
- // Type-only modules and test helpers carry no executable logic worth gating.
17
- exclude: ["src/**/*-types.ts", "src/types.ts"],
18
- // Floors set just below current actuals (stmts 84%, branches 75%,
19
- // funcs 95%, lines 86%) to catch regressions. Raised in Phase 4 after the
20
- // runtime/ + tools/ suites landed.
21
- thresholds: {
22
- statements: 82,
23
- branches: 73,
24
- functions: 94,
25
- lines: 84,
26
- },
27
- },
28
- },
29
- });