@trevonistrevon/pi-loop 0.5.8 → 0.6.0

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 (127) hide show
  1. package/.release-please-manifest.json +3 -0
  2. package/AGENTS.md +52 -12
  3. package/CHANGELOG.md +59 -0
  4. package/CONTRIBUTING.md +13 -3
  5. package/Dockerfile +17 -0
  6. package/README.md +47 -0
  7. package/coverage/coverage-final.json +35 -31
  8. package/coverage/index.html +64 -49
  9. package/coverage/src/api.ts.html +193 -0
  10. package/coverage/src/commands/index.html +32 -32
  11. package/coverage/src/commands/loop-command.ts.html +170 -170
  12. package/coverage/src/commands/tasks-command.ts.html +135 -135
  13. package/coverage/src/coordinator.ts.html +26 -26
  14. package/coverage/src/index.html +61 -106
  15. package/coverage/src/index.ts.html +280 -94
  16. package/coverage/src/loop-parse.ts.html +90 -57
  17. package/coverage/src/loop-reducer.ts.html +25 -25
  18. package/coverage/src/monitor-completion-coordinator.ts.html +1 -1
  19. package/coverage/src/monitor-manager.ts.html +95 -71
  20. package/coverage/src/monitor-reducer.ts.html +15 -15
  21. package/coverage/src/notification-reducer.ts.html +7 -7
  22. package/coverage/src/reducer-backed-store.ts.html +57 -57
  23. package/coverage/src/rpc/channels.ts.html +376 -0
  24. package/coverage/src/rpc/cross-extension-rpc.ts.html +541 -0
  25. package/coverage/src/rpc/index.html +131 -0
  26. package/coverage/src/runtime/index.html +89 -29
  27. package/coverage/src/{goal-coordinator.ts.html → runtime/loop-events.ts.html} +79 -73
  28. package/coverage/src/runtime/monitor-ondone-runtime.ts.html +5 -5
  29. package/coverage/src/runtime/native-task-rpc.ts.html +502 -0
  30. package/coverage/src/runtime/notification-runtime.ts.html +14 -14
  31. package/coverage/src/runtime/scope.ts.html +17 -17
  32. package/coverage/src/runtime/session-runtime.ts.html +40 -40
  33. package/coverage/src/runtime/task-backlog-runtime.ts.html +66 -24
  34. package/coverage/src/runtime/task-events.ts.html +208 -0
  35. package/coverage/src/runtime/task-mutations.ts.html +394 -0
  36. package/coverage/src/runtime/task-rpc.ts.html +106 -118
  37. package/coverage/src/scheduler.ts.html +12 -12
  38. package/coverage/src/store.ts.html +20 -20
  39. package/coverage/src/task-backlog-coordinator.ts.html +8 -8
  40. package/coverage/src/task-reducer.ts.html +42 -42
  41. package/coverage/src/task-store.ts.html +49 -49
  42. package/coverage/src/tools/index.html +39 -24
  43. package/coverage/src/tools/loop-tools.ts.html +12 -21
  44. package/coverage/src/tools/monitor-tools.ts.html +12 -21
  45. package/coverage/src/tools/native-task-tools.ts.html +52 -94
  46. package/coverage/src/tools/tool-result.ts.html +97 -0
  47. package/coverage/src/trigger-system.ts.html +12 -12
  48. package/coverage/src/ui/index.html +1 -1
  49. package/coverage/src/ui/widget.ts.html +23 -23
  50. package/dist/api.d.ts +11 -0
  51. package/dist/api.js +10 -0
  52. package/dist/commands/loop-command.js +2 -2
  53. package/dist/commands/tasks-command.js +3 -3
  54. package/dist/coordinator.d.ts +1 -1
  55. package/dist/index.js +80 -20
  56. package/dist/loop-parse.js +14 -5
  57. package/dist/monitor-manager.d.ts +4 -1
  58. package/dist/monitor-manager.js +5 -3
  59. package/dist/reducer-backed-store.d.ts +1 -1
  60. package/dist/reducer-backed-store.js +1 -1
  61. package/dist/rpc/channels.d.ts +73 -0
  62. package/dist/rpc/channels.js +30 -0
  63. package/dist/rpc/cross-extension-rpc.d.ts +59 -0
  64. package/dist/rpc/cross-extension-rpc.js +117 -0
  65. package/dist/runtime/loop-events.d.ts +26 -0
  66. package/dist/runtime/loop-events.js +26 -0
  67. package/dist/runtime/native-task-rpc.d.ts +22 -0
  68. package/dist/runtime/native-task-rpc.js +50 -0
  69. package/dist/runtime/task-backlog-runtime.d.ts +3 -0
  70. package/dist/runtime/task-backlog-runtime.js +4 -1
  71. package/dist/runtime/task-mutations.d.ts +39 -0
  72. package/dist/runtime/task-mutations.js +68 -0
  73. package/dist/runtime/task-rpc.d.ts +4 -0
  74. package/dist/runtime/task-rpc.js +40 -58
  75. package/dist/scheduler.js +1 -1
  76. package/dist/tools/loop-tools.js +1 -3
  77. package/dist/tools/monitor-tools.js +1 -3
  78. package/dist/tools/native-task-tools.d.ts +2 -6
  79. package/dist/tools/native-task-tools.js +25 -55
  80. package/dist/tools/tool-result.d.ts +8 -0
  81. package/dist/tools/tool-result.js +4 -0
  82. package/docker-compose.yml +12 -0
  83. package/docs/architecture/state-machine-migration.md +0 -44
  84. package/docs/architecture/state-machine-reducer-event-model.md +2 -3
  85. package/package.json +6 -1
  86. package/release-please-config.json +9 -0
  87. package/src/api.ts +36 -0
  88. package/src/commands/loop-command.ts +2 -2
  89. package/src/commands/tasks-command.ts +3 -3
  90. package/src/coordinator.ts +1 -1
  91. package/src/index.ts +84 -22
  92. package/src/loop-parse.ts +18 -7
  93. package/src/monitor-manager.ts +11 -3
  94. package/src/reducer-backed-store.ts +3 -3
  95. package/src/rpc/channels.ts +97 -0
  96. package/src/rpc/cross-extension-rpc.ts +152 -0
  97. package/src/runtime/loop-events.ts +60 -0
  98. package/src/runtime/native-task-rpc.ts +139 -0
  99. package/src/runtime/task-backlog-runtime.ts +14 -0
  100. package/src/runtime/task-mutations.ts +103 -0
  101. package/src/runtime/task-rpc.ts +48 -54
  102. package/src/scheduler.ts +1 -1
  103. package/src/tools/loop-tools.ts +1 -4
  104. package/src/tools/monitor-tools.ts +1 -4
  105. package/src/tools/native-task-tools.ts +31 -52
  106. package/src/tools/tool-result.ts +4 -0
  107. package/src/trigger-system.ts +4 -4
  108. package/vitest.config.ts +11 -7
  109. package/coverage/src/goal-reducer.ts.html +0 -982
  110. package/coverage/src/goal-store.ts.html +0 -742
  111. package/coverage/src/goal-verifier.ts.html +0 -808
  112. package/dist/goal-coordinator.d.ts +0 -22
  113. package/dist/goal-coordinator.js +0 -28
  114. package/dist/goal-reducer.d.ts +0 -98
  115. package/dist/goal-reducer.js +0 -190
  116. package/dist/goal-store.d.ts +0 -22
  117. package/dist/goal-store.js +0 -188
  118. package/dist/goal-types.d.ts +0 -82
  119. package/dist/goal-types.js +0 -1
  120. package/dist/goal-verifier.d.ts +0 -20
  121. package/dist/goal-verifier.js +0 -198
  122. package/docs/architecture/goal-state-schema.md +0 -505
  123. package/src/goal-coordinator.ts +0 -58
  124. package/src/goal-reducer.ts +0 -299
  125. package/src/goal-store.ts +0 -219
  126. package/src/goal-types.ts +0 -104
  127. package/src/goal-verifier.ts +0 -241
@@ -1,22 +0,0 @@
1
- import type { ReducerEffect, ReducerEvent } from "./coordinator.js";
2
- import type { GoalReducerState } 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
- export type GoalVerificationRequestedEvent = ReducerEvent<"GOAL_VERIFICATION_REQUESTED", {
7
- id: string;
8
- }>;
9
- export interface GoalCoordinatorSnapshot {
10
- goalState: GoalReducerState;
11
- taskState: TaskReducerState;
12
- loopState: LoopReducerState;
13
- monitorState: MonitorReducerState;
14
- }
15
- export declare function reduceGoalVerificationRequest(event: GoalVerificationRequestedEvent, snapshot: GoalCoordinatorSnapshot): ReducerEffect[];
16
- export interface GoalCoordinatorOptions {
17
- getGoalState: () => GoalReducerState;
18
- getTaskState: () => TaskReducerState;
19
- getLoopState: () => LoopReducerState;
20
- getMonitorState: () => MonitorReducerState;
21
- }
22
- export declare function createGoalCoordinatorReducer(options: GoalCoordinatorOptions): (event: ReducerEvent) => ReducerEffect[];
@@ -1,28 +0,0 @@
1
- import { verifyGoal } from "./goal-verifier.js";
2
- export function reduceGoalVerificationRequest(event, snapshot) {
3
- if (event.type !== "GOAL_VERIFICATION_REQUESTED")
4
- return [];
5
- const goal = snapshot.goalState.goalsById[event.payload.id];
6
- if (!goal)
7
- return [];
8
- return verifyGoal({
9
- goal,
10
- taskState: snapshot.taskState,
11
- loopState: snapshot.loopState,
12
- monitorState: snapshot.monitorState,
13
- at: event.at,
14
- }).effects;
15
- }
16
- export function createGoalCoordinatorReducer(options) {
17
- const { getGoalState, getTaskState, getLoopState, getMonitorState } = options;
18
- return (event) => {
19
- if (event.type !== "GOAL_VERIFICATION_REQUESTED")
20
- return [];
21
- return reduceGoalVerificationRequest(event, {
22
- goalState: getGoalState(),
23
- taskState: getTaskState(),
24
- loopState: getLoopState(),
25
- monitorState: getMonitorState(),
26
- });
27
- };
28
- }
@@ -1,98 +0,0 @@
1
- import type { GoalCriteria, GoalEntry, GoalProgressSnapshot, GoalReducerState, GoalScope } from "./goal-types.js";
2
- export type GoalReducerEvent = {
3
- type: "GOAL_CREATED";
4
- at: number;
5
- source: "tool" | "command" | "scheduler" | "eventbus" | "monitor" | "session" | "coordinator" | "system";
6
- entityType?: "goal";
7
- entityId?: string;
8
- payload: {
9
- title: string;
10
- description: string;
11
- scope: GoalScope;
12
- criteria: GoalCriteria;
13
- metadata?: Record<string, unknown>;
14
- };
15
- } | {
16
- type: "GOAL_ACTIVATED" | "GOAL_VERIFICATION_STARTED" | "GOAL_UNBLOCKED";
17
- at: number;
18
- source: "tool" | "command" | "scheduler" | "eventbus" | "monitor" | "session" | "coordinator" | "system";
19
- entityType?: "goal";
20
- entityId?: string;
21
- payload: {
22
- id: string;
23
- };
24
- } | {
25
- type: "GOAL_PROGRESS_RECORDED";
26
- at: number;
27
- source: "tool" | "command" | "scheduler" | "eventbus" | "monitor" | "session" | "coordinator" | "system";
28
- entityType?: "goal";
29
- entityId?: string;
30
- payload: {
31
- id: string;
32
- progress: GoalProgressSnapshot;
33
- };
34
- } | {
35
- type: "GOAL_VERIFICATION_PASSED" | "GOAL_VERIFICATION_FAILED" | "GOAL_BLOCKED" | "GOAL_FAILED";
36
- at: number;
37
- source: "tool" | "command" | "scheduler" | "eventbus" | "monitor" | "session" | "coordinator" | "system";
38
- entityType?: "goal";
39
- entityId?: string;
40
- payload: {
41
- id: string;
42
- reason: string;
43
- progress?: GoalProgressSnapshot;
44
- };
45
- } | {
46
- type: "GOAL_SATISFIED" | "GOAL_ARCHIVED";
47
- at: number;
48
- source: "tool" | "command" | "scheduler" | "eventbus" | "monitor" | "session" | "coordinator" | "system";
49
- entityType?: "goal";
50
- entityId?: string;
51
- payload: {
52
- id: string;
53
- reason?: string;
54
- };
55
- } | {
56
- type: "GOAL_UPDATED";
57
- at: number;
58
- source: "tool" | "command" | "scheduler" | "eventbus" | "monitor" | "session" | "coordinator" | "system";
59
- entityType?: "goal";
60
- entityId?: string;
61
- payload: {
62
- id: string;
63
- title?: string;
64
- description?: string;
65
- scope?: GoalScope;
66
- criteria?: GoalCriteria;
67
- metadata?: Record<string, unknown>;
68
- };
69
- };
70
- export type GoalReducerEffect = {
71
- type: "PERSIST_GOAL";
72
- entityType: "goal";
73
- entityId: string;
74
- payload: {
75
- goal: GoalEntry;
76
- };
77
- } | {
78
- type: "REQUEST_GOAL_VERIFICATION";
79
- entityType: "goal";
80
- entityId: string;
81
- payload: {
82
- id: string;
83
- };
84
- } | {
85
- type: "GOAL_TRANSITION_REJECTED";
86
- entityType: "goal";
87
- entityId: string;
88
- payload: {
89
- id: string;
90
- status: GoalEntry["status"];
91
- attempted: string;
92
- };
93
- };
94
- export interface GoalReduceResult {
95
- state: GoalReducerState;
96
- effects: GoalReducerEffect[];
97
- }
98
- export declare function reduceGoalState(state: GoalReducerState, event: GoalReducerEvent): GoalReduceResult;
@@ -1,190 +0,0 @@
1
- function cloneState(state) {
2
- return {
3
- nextId: state.nextId,
4
- goalsById: { ...state.goalsById },
5
- };
6
- }
7
- function emptyProgress() {
8
- return {
9
- totalTasks: 0,
10
- pendingTasks: 0,
11
- inProgressTasks: 0,
12
- completedTasks: 0,
13
- activeLoops: 0,
14
- pausedLoops: 0,
15
- runningMonitors: 0,
16
- completedMonitors: 0,
17
- erroredMonitors: 0,
18
- stoppedMonitors: 0,
19
- };
20
- }
21
- function emptyVerification() {
22
- return {
23
- attempts: 0,
24
- passes: 0,
25
- failures: 0,
26
- };
27
- }
28
- function persist(goal) {
29
- return {
30
- type: "PERSIST_GOAL",
31
- entityType: "goal",
32
- entityId: goal.id,
33
- payload: { goal },
34
- };
35
- }
36
- function isTerminal(goal) {
37
- return goal.status === "satisfied" || goal.status === "failed" || goal.status === "archived";
38
- }
39
- export function reduceGoalState(state, event) {
40
- if (event.type === "GOAL_CREATED") {
41
- const next = cloneState(state);
42
- const id = String(next.nextId++);
43
- const goal = {
44
- id,
45
- title: event.payload.title,
46
- description: event.payload.description,
47
- status: "pending",
48
- verificationStatus: "unknown",
49
- createdAt: event.at,
50
- updatedAt: event.at,
51
- scope: event.payload.scope,
52
- criteria: event.payload.criteria,
53
- progress: emptyProgress(),
54
- verification: emptyVerification(),
55
- metadata: event.payload.metadata,
56
- };
57
- next.goalsById[id] = goal;
58
- return {
59
- state: next,
60
- effects: [persist(goal)],
61
- };
62
- }
63
- const id = event.payload.id;
64
- const current = state.goalsById[id];
65
- if (!current)
66
- return { state, effects: [] };
67
- if (isTerminal(current) && event.type !== "GOAL_ARCHIVED") {
68
- return {
69
- state,
70
- effects: [{
71
- type: "GOAL_TRANSITION_REJECTED",
72
- entityType: "goal",
73
- entityId: id,
74
- payload: { id, status: current.status, attempted: event.type },
75
- }],
76
- };
77
- }
78
- const next = cloneState(state);
79
- const goal = {
80
- ...current,
81
- progress: { ...current.progress },
82
- verification: { ...current.verification },
83
- };
84
- let extraEffects = [];
85
- if (event.type === "GOAL_ACTIVATED") {
86
- goal.status = "active";
87
- goal.activatedAt ??= event.at;
88
- goal.updatedAt = event.at;
89
- extraEffects = [{
90
- type: "REQUEST_GOAL_VERIFICATION",
91
- entityType: "goal",
92
- entityId: id,
93
- payload: { id },
94
- }];
95
- }
96
- if (event.type === "GOAL_PROGRESS_RECORDED") {
97
- goal.progress = event.payload.progress;
98
- goal.updatedAt = event.at;
99
- }
100
- if (event.type === "GOAL_VERIFICATION_STARTED") {
101
- goal.verificationStatus = "checking";
102
- goal.verification.attempts += 1;
103
- goal.verification.lastCheckedAt = event.at;
104
- goal.updatedAt = event.at;
105
- }
106
- if (event.type === "GOAL_VERIFICATION_PASSED") {
107
- if (event.payload.progress)
108
- goal.progress = event.payload.progress;
109
- goal.status = "satisfied";
110
- goal.verificationStatus = "verified";
111
- goal.verification.passes += 1;
112
- goal.verification.lastPassedAt = event.at;
113
- goal.verification.lastCheckedAt = event.at;
114
- goal.verification.lastReason = event.payload.reason;
115
- goal.resolvedAt = event.at;
116
- goal.updatedAt = event.at;
117
- }
118
- if (event.type === "GOAL_VERIFICATION_FAILED") {
119
- if (event.payload.progress)
120
- goal.progress = event.payload.progress;
121
- goal.verificationStatus = "unverified";
122
- goal.verification.failures += 1;
123
- goal.verification.lastFailedAt = event.at;
124
- goal.verification.lastCheckedAt = event.at;
125
- goal.verification.lastReason = event.payload.reason;
126
- if (goal.status === "pending")
127
- goal.status = "active";
128
- goal.updatedAt = event.at;
129
- }
130
- if (event.type === "GOAL_BLOCKED") {
131
- if (event.payload.progress)
132
- goal.progress = event.payload.progress;
133
- goal.status = "blocked";
134
- goal.verificationStatus = "inconclusive";
135
- goal.verification.failures += 1;
136
- goal.verification.lastFailedAt = event.at;
137
- goal.verification.lastCheckedAt = event.at;
138
- goal.verification.lastReason = event.payload.reason;
139
- goal.updatedAt = event.at;
140
- }
141
- if (event.type === "GOAL_UNBLOCKED") {
142
- goal.status = "active";
143
- goal.updatedAt = event.at;
144
- }
145
- if (event.type === "GOAL_SATISFIED") {
146
- goal.status = "satisfied";
147
- goal.verificationStatus = "verified";
148
- goal.verification.lastReason = event.payload.reason ?? goal.verification.lastReason;
149
- goal.resolvedAt = event.at;
150
- goal.updatedAt = event.at;
151
- }
152
- if (event.type === "GOAL_FAILED") {
153
- if (event.payload.progress)
154
- goal.progress = event.payload.progress;
155
- goal.status = "failed";
156
- goal.verificationStatus = "unverified";
157
- goal.verification.failures += 1;
158
- goal.verification.lastFailedAt = event.at;
159
- goal.verification.lastCheckedAt = event.at;
160
- goal.verification.lastReason = event.payload.reason;
161
- goal.resolvedAt = event.at;
162
- goal.updatedAt = event.at;
163
- }
164
- if (event.type === "GOAL_ARCHIVED") {
165
- goal.status = "archived";
166
- goal.resolvedAt = event.at;
167
- goal.updatedAt = event.at;
168
- if (event.payload.reason !== undefined) {
169
- goal.verification.lastReason = event.payload.reason;
170
- }
171
- }
172
- if (event.type === "GOAL_UPDATED") {
173
- if (event.payload.title !== undefined)
174
- goal.title = event.payload.title;
175
- if (event.payload.description !== undefined)
176
- goal.description = event.payload.description;
177
- if (event.payload.scope !== undefined)
178
- goal.scope = event.payload.scope;
179
- if (event.payload.criteria !== undefined)
180
- goal.criteria = event.payload.criteria;
181
- if (event.payload.metadata !== undefined)
182
- goal.metadata = event.payload.metadata;
183
- goal.updatedAt = event.at;
184
- }
185
- next.goalsById[id] = goal;
186
- return {
187
- state: next,
188
- effects: [persist(goal), ...extraEffects],
189
- };
190
- }
@@ -1,22 +0,0 @@
1
- import { type GoalReducerEvent } from "./goal-reducer.js";
2
- import type { GoalCriteria, GoalEntry, GoalProgressSnapshot, GoalReducerState, GoalScope, GoalStoreData } from "./goal-types.js";
3
- import { ReducerBackedStore } from "./reducer-backed-store.js";
4
- export declare class GoalStore extends ReducerBackedStore<GoalEntry, GoalReducerState, GoalReducerEvent, GoalStoreData> {
5
- constructor(listIdOrPath?: string);
6
- create(title: string, description: string, scope: GoalScope, criteria: GoalCriteria, metadata?: Record<string, unknown>): GoalEntry;
7
- activate(id: string): GoalEntry | undefined;
8
- recordProgress(id: string, progress: GoalProgressSnapshot): GoalEntry | undefined;
9
- markVerificationStarted(id: string): GoalEntry | undefined;
10
- markVerified(id: string, reason: string, progress?: GoalProgressSnapshot): GoalEntry | undefined;
11
- markFailed(id: string, reason: string, progress?: GoalProgressSnapshot): GoalEntry | undefined;
12
- markBlocked(id: string, reason: string, progress?: GoalProgressSnapshot): GoalEntry | undefined;
13
- unblock(id: string): GoalEntry | undefined;
14
- updateDetails(id: string, fields: {
15
- title?: string;
16
- description?: string;
17
- scope?: GoalScope;
18
- criteria?: GoalCriteria;
19
- metadata?: Record<string, unknown>;
20
- }): GoalEntry | undefined;
21
- archive(id: string, reason?: string): GoalEntry | undefined;
22
- }
@@ -1,188 +0,0 @@
1
- import { homedir } from "node:os";
2
- import { join } from "node:path";
3
- import { reduceGoalState } from "./goal-reducer.js";
4
- import { ReducerBackedStore } from "./reducer-backed-store.js";
5
- const GOALS_DIR = join(homedir(), ".pi", "goals");
6
- const MAX_GOALS = 200;
7
- export class GoalStore extends ReducerBackedStore {
8
- constructor(listIdOrPath) {
9
- super({
10
- baseDir: GOALS_DIR,
11
- reduce: (state, event) => reduceGoalState(state, event),
12
- toReducerState: (nextId, entries) => ({ nextId, goalsById: Object.fromEntries(entries.entries()) }),
13
- fromReducerState: (state) => ({ nextId: state.nextId, entries: new Map(Object.entries(state.goalsById)) }),
14
- serialize: (nextId, entries) => ({ nextId, goals: Array.from(entries.values()) }),
15
- deserialize: (data) => ({ nextId: data.nextId, entries: new Map(data.goals.map((g) => [g.id, g])) }),
16
- }, listIdOrPath);
17
- }
18
- create(title, description, scope, criteria, metadata) {
19
- return this.withLock(() => {
20
- if (this.entries.size >= MAX_GOALS) {
21
- throw new Error(`Maximum of ${MAX_GOALS} goals reached. Archive some before creating new ones.`);
22
- }
23
- this.applyReducerEvent({
24
- type: "GOAL_CREATED",
25
- at: Date.now(),
26
- source: "tool",
27
- entityType: "goal",
28
- payload: {
29
- title,
30
- description,
31
- scope,
32
- criteria,
33
- metadata,
34
- },
35
- });
36
- return this.entries.get(String(this.nextId - 1));
37
- });
38
- }
39
- activate(id) {
40
- return this.withLock(() => {
41
- if (!this.entries.has(id))
42
- return undefined;
43
- this.applyReducerEvent({
44
- type: "GOAL_ACTIVATED",
45
- at: Date.now(),
46
- source: "tool",
47
- entityType: "goal",
48
- entityId: id,
49
- payload: { id },
50
- });
51
- return this.entries.get(id);
52
- });
53
- }
54
- recordProgress(id, progress) {
55
- return this.withLock(() => {
56
- if (!this.entries.has(id))
57
- return undefined;
58
- this.applyReducerEvent({
59
- type: "GOAL_PROGRESS_RECORDED",
60
- at: Date.now(),
61
- source: "coordinator",
62
- entityType: "goal",
63
- entityId: id,
64
- payload: { id, progress },
65
- });
66
- return this.entries.get(id);
67
- });
68
- }
69
- markVerificationStarted(id) {
70
- return this.withLock(() => {
71
- if (!this.entries.has(id))
72
- return undefined;
73
- this.applyReducerEvent({
74
- type: "GOAL_VERIFICATION_STARTED",
75
- at: Date.now(),
76
- source: "coordinator",
77
- entityType: "goal",
78
- entityId: id,
79
- payload: { id },
80
- });
81
- return this.entries.get(id);
82
- });
83
- }
84
- markVerified(id, reason, progress) {
85
- return this.withLock(() => {
86
- if (!this.entries.has(id))
87
- return undefined;
88
- this.applyReducerEvent({
89
- type: "GOAL_VERIFICATION_PASSED",
90
- at: Date.now(),
91
- source: "coordinator",
92
- entityType: "goal",
93
- entityId: id,
94
- payload: { id, reason, progress },
95
- });
96
- return this.entries.get(id);
97
- });
98
- }
99
- markFailed(id, reason, progress) {
100
- return this.withLock(() => {
101
- if (!this.entries.has(id))
102
- return undefined;
103
- this.applyReducerEvent({
104
- type: "GOAL_FAILED",
105
- at: Date.now(),
106
- source: "coordinator",
107
- entityType: "goal",
108
- entityId: id,
109
- payload: { id, reason, progress },
110
- });
111
- return this.entries.get(id);
112
- });
113
- }
114
- markBlocked(id, reason, progress) {
115
- return this.withLock(() => {
116
- if (!this.entries.has(id))
117
- return undefined;
118
- this.applyReducerEvent({
119
- type: "GOAL_BLOCKED",
120
- at: Date.now(),
121
- source: "coordinator",
122
- entityType: "goal",
123
- entityId: id,
124
- payload: { id, reason, progress },
125
- });
126
- return this.entries.get(id);
127
- });
128
- }
129
- unblock(id) {
130
- return this.withLock(() => {
131
- if (!this.entries.has(id))
132
- return undefined;
133
- this.applyReducerEvent({
134
- type: "GOAL_UNBLOCKED",
135
- at: Date.now(),
136
- source: "coordinator",
137
- entityType: "goal",
138
- entityId: id,
139
- payload: { id },
140
- });
141
- return this.entries.get(id);
142
- });
143
- }
144
- updateDetails(id, fields) {
145
- return this.withLock(() => {
146
- if (!this.entries.has(id))
147
- return undefined;
148
- if (fields.title === undefined
149
- && fields.description === undefined
150
- && fields.scope === undefined
151
- && fields.criteria === undefined
152
- && fields.metadata === undefined) {
153
- return this.entries.get(id);
154
- }
155
- this.applyReducerEvent({
156
- type: "GOAL_UPDATED",
157
- at: Date.now(),
158
- source: "tool",
159
- entityType: "goal",
160
- entityId: id,
161
- payload: {
162
- id,
163
- title: fields.title,
164
- description: fields.description,
165
- scope: fields.scope,
166
- criteria: fields.criteria,
167
- metadata: fields.metadata,
168
- },
169
- });
170
- return this.entries.get(id);
171
- });
172
- }
173
- archive(id, reason) {
174
- return this.withLock(() => {
175
- if (!this.entries.has(id))
176
- return undefined;
177
- this.applyReducerEvent({
178
- type: "GOAL_ARCHIVED",
179
- at: Date.now(),
180
- source: "tool",
181
- entityType: "goal",
182
- entityId: id,
183
- payload: { id, reason },
184
- });
185
- return this.entries.get(id);
186
- });
187
- }
188
- }
@@ -1,82 +0,0 @@
1
- export type GoalStatus = "pending" | "active" | "satisfied" | "blocked" | "failed" | "archived";
2
- export type GoalVerificationStatus = "unknown" | "checking" | "verified" | "unverified" | "inconclusive";
3
- export interface GoalScope {
4
- taskIds?: string[];
5
- loopIds?: string[];
6
- monitorIds?: string[];
7
- tags?: string[];
8
- subjectPrefixes?: string[];
9
- includeFutureMatchingTasks?: boolean;
10
- includeFutureMatchingLoops?: boolean;
11
- includeFutureMatchingMonitors?: boolean;
12
- }
13
- export interface GoalSuccessCriteria {
14
- minCompletedTasks?: number;
15
- requiredTaskIds?: string[];
16
- requiredMonitorIdsCompleted?: string[];
17
- requiredLoopIdsPresent?: string[];
18
- requireNoPendingTasksInScope?: boolean;
19
- requireLatestVerificationPass?: boolean;
20
- }
21
- export interface GoalFailureCriteria {
22
- anyMonitorIdsErrored?: string[];
23
- maxVerificationFailures?: number;
24
- failIfTaskIdsDeleted?: string[];
25
- }
26
- export interface GoalBlockedCriteria {
27
- blockedIfAllTasksCompletedButVerificationFails?: boolean;
28
- blockedIfNoScopedProgressSinceMs?: number;
29
- blockedIfRequiredLoopMissing?: boolean;
30
- }
31
- export interface GoalCriteria {
32
- success: GoalSuccessCriteria;
33
- failure?: GoalFailureCriteria;
34
- blocked?: GoalBlockedCriteria;
35
- }
36
- export interface GoalProgressSnapshot {
37
- totalTasks: number;
38
- pendingTasks: number;
39
- inProgressTasks: number;
40
- completedTasks: number;
41
- activeLoops: number;
42
- pausedLoops: number;
43
- runningMonitors: number;
44
- completedMonitors: number;
45
- erroredMonitors: number;
46
- stoppedMonitors: number;
47
- lastProgressAt?: number;
48
- }
49
- export interface GoalVerificationState {
50
- attempts: number;
51
- passes: number;
52
- failures: number;
53
- lastCheckedAt?: number;
54
- lastPassedAt?: number;
55
- lastFailedAt?: number;
56
- lastReason?: string;
57
- nextCheckAfter?: number;
58
- }
59
- export interface GoalEntry {
60
- id: string;
61
- title: string;
62
- description: string;
63
- status: GoalStatus;
64
- verificationStatus: GoalVerificationStatus;
65
- createdAt: number;
66
- updatedAt: number;
67
- activatedAt?: number;
68
- resolvedAt?: number;
69
- scope: GoalScope;
70
- criteria: GoalCriteria;
71
- progress: GoalProgressSnapshot;
72
- verification: GoalVerificationState;
73
- metadata?: Record<string, unknown>;
74
- }
75
- export interface GoalReducerState {
76
- nextId: number;
77
- goalsById: Record<string, GoalEntry>;
78
- }
79
- export interface GoalStoreData {
80
- nextId: number;
81
- goals: GoalEntry[];
82
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,20 +0,0 @@
1
- import type { ReducerEffect } 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
- export interface GoalVerifierInput {
7
- goal: GoalEntry;
8
- taskState: TaskReducerState;
9
- loopState: LoopReducerState;
10
- monitorState: MonitorReducerState;
11
- at: number;
12
- }
13
- export interface GoalVerifierResult {
14
- progress: GoalProgressSnapshot;
15
- verdict: "passed" | "failed" | "blocked";
16
- reason: string;
17
- effects: ReducerEffect[];
18
- }
19
- export declare function projectGoalProgress(goal: GoalEntry, taskState: TaskReducerState, loopState: LoopReducerState, monitorState: MonitorReducerState): GoalProgressSnapshot;
20
- export declare function verifyGoal(input: GoalVerifierInput): GoalVerifierResult;