octie-cli 1.0.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.
- package/README.md +523 -0
- package/dist/cli/commands/approve.d.ts +27 -0
- package/dist/cli/commands/approve.d.ts.map +1 -0
- package/dist/cli/commands/approve.js +119 -0
- package/dist/cli/commands/approve.js.map +1 -0
- package/dist/cli/commands/batch.d.ts +15 -0
- package/dist/cli/commands/batch.d.ts.map +1 -0
- package/dist/cli/commands/batch.js +521 -0
- package/dist/cli/commands/batch.js.map +1 -0
- package/dist/cli/commands/create.d.ts +9 -0
- package/dist/cli/commands/create.d.ts.map +1 -0
- package/dist/cli/commands/create.js +321 -0
- package/dist/cli/commands/create.js.map +1 -0
- package/dist/cli/commands/delete.d.ts +9 -0
- package/dist/cli/commands/delete.d.ts.map +1 -0
- package/dist/cli/commands/delete.js +143 -0
- package/dist/cli/commands/delete.js.map +1 -0
- package/dist/cli/commands/export.d.ts +9 -0
- package/dist/cli/commands/export.d.ts.map +1 -0
- package/dist/cli/commands/export.js +66 -0
- package/dist/cli/commands/export.js.map +1 -0
- package/dist/cli/commands/find.d.ts +16 -0
- package/dist/cli/commands/find.d.ts.map +1 -0
- package/dist/cli/commands/find.js +252 -0
- package/dist/cli/commands/find.js.map +1 -0
- package/dist/cli/commands/get.d.ts +9 -0
- package/dist/cli/commands/get.d.ts.map +1 -0
- package/dist/cli/commands/get.js +74 -0
- package/dist/cli/commands/get.js.map +1 -0
- package/dist/cli/commands/graph.d.ts +9 -0
- package/dist/cli/commands/graph.d.ts.map +1 -0
- package/dist/cli/commands/graph.js +200 -0
- package/dist/cli/commands/graph.js.map +1 -0
- package/dist/cli/commands/import.d.ts +9 -0
- package/dist/cli/commands/import.d.ts.map +1 -0
- package/dist/cli/commands/import.js +807 -0
- package/dist/cli/commands/import.js.map +1 -0
- package/dist/cli/commands/init.d.ts +9 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +57 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/list.d.ts +9 -0
- package/dist/cli/commands/list.d.ts.map +1 -0
- package/dist/cli/commands/list.js +175 -0
- package/dist/cli/commands/list.js.map +1 -0
- package/dist/cli/commands/merge.d.ts +9 -0
- package/dist/cli/commands/merge.d.ts.map +1 -0
- package/dist/cli/commands/merge.js +113 -0
- package/dist/cli/commands/merge.js.map +1 -0
- package/dist/cli/commands/serve.d.ts +9 -0
- package/dist/cli/commands/serve.d.ts.map +1 -0
- package/dist/cli/commands/serve.js +94 -0
- package/dist/cli/commands/serve.js.map +1 -0
- package/dist/cli/commands/update.d.ts +9 -0
- package/dist/cli/commands/update.d.ts.map +1 -0
- package/dist/cli/commands/update.js +423 -0
- package/dist/cli/commands/update.js.map +1 -0
- package/dist/cli/commands/wire.d.ts +15 -0
- package/dist/cli/commands/wire.d.ts.map +1 -0
- package/dist/cli/commands/wire.js +164 -0
- package/dist/cli/commands/wire.js.map +1 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +100 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/output/json.d.ts +16 -0
- package/dist/cli/output/json.d.ts.map +1 -0
- package/dist/cli/output/json.js +29 -0
- package/dist/cli/output/json.js.map +1 -0
- package/dist/cli/output/markdown.d.ts +15 -0
- package/dist/cli/output/markdown.d.ts.map +1 -0
- package/dist/cli/output/markdown.js +206 -0
- package/dist/cli/output/markdown.js.map +1 -0
- package/dist/cli/output/table.d.ts +23 -0
- package/dist/cli/output/table.d.ts.map +1 -0
- package/dist/cli/output/table.js +150 -0
- package/dist/cli/output/table.js.map +1 -0
- package/dist/cli/utils/helpers.d.ts +126 -0
- package/dist/cli/utils/helpers.d.ts.map +1 -0
- package/dist/cli/utils/helpers.js +325 -0
- package/dist/cli/utils/helpers.js.map +1 -0
- package/dist/core/graph/algorithms.d.ts +11 -0
- package/dist/core/graph/algorithms.d.ts.map +1 -0
- package/dist/core/graph/algorithms.js +14 -0
- package/dist/core/graph/algorithms.js.map +1 -0
- package/dist/core/graph/cycle.d.ts +155 -0
- package/dist/core/graph/cycle.d.ts.map +1 -0
- package/dist/core/graph/cycle.js +297 -0
- package/dist/core/graph/cycle.js.map +1 -0
- package/dist/core/graph/index.d.ts +223 -0
- package/dist/core/graph/index.d.ts.map +1 -0
- package/dist/core/graph/index.js +475 -0
- package/dist/core/graph/index.js.map +1 -0
- package/dist/core/graph/operations.d.ts +240 -0
- package/dist/core/graph/operations.d.ts.map +1 -0
- package/dist/core/graph/operations.js +503 -0
- package/dist/core/graph/operations.js.map +1 -0
- package/dist/core/graph/sort.d.ts +76 -0
- package/dist/core/graph/sort.d.ts.map +1 -0
- package/dist/core/graph/sort.js +254 -0
- package/dist/core/graph/sort.js.map +1 -0
- package/dist/core/graph/traversal.d.ts +122 -0
- package/dist/core/graph/traversal.d.ts.map +1 -0
- package/dist/core/graph/traversal.js +336 -0
- package/dist/core/graph/traversal.js.map +1 -0
- package/dist/core/models/task-node.d.ts +328 -0
- package/dist/core/models/task-node.d.ts.map +1 -0
- package/dist/core/models/task-node.js +1090 -0
- package/dist/core/models/task-node.js.map +1 -0
- package/dist/core/registry/index.d.ts +102 -0
- package/dist/core/registry/index.d.ts.map +1 -0
- package/dist/core/registry/index.js +249 -0
- package/dist/core/registry/index.js.map +1 -0
- package/dist/core/registry/root-guard.d.ts +19 -0
- package/dist/core/registry/root-guard.d.ts.map +1 -0
- package/dist/core/registry/root-guard.js +28 -0
- package/dist/core/registry/root-guard.js.map +1 -0
- package/dist/core/storage/atomic-write.d.ts +181 -0
- package/dist/core/storage/atomic-write.d.ts.map +1 -0
- package/dist/core/storage/atomic-write.js +379 -0
- package/dist/core/storage/atomic-write.js.map +1 -0
- package/dist/core/storage/file-store.d.ts +148 -0
- package/dist/core/storage/file-store.d.ts.map +1 -0
- package/dist/core/storage/file-store.js +423 -0
- package/dist/core/storage/file-store.js.map +1 -0
- package/dist/core/storage/indexer.d.ts +138 -0
- package/dist/core/storage/indexer.d.ts.map +1 -0
- package/dist/core/storage/indexer.js +350 -0
- package/dist/core/storage/indexer.js.map +1 -0
- package/dist/core/utils/status-helpers.d.ts +59 -0
- package/dist/core/utils/status-helpers.d.ts.map +1 -0
- package/dist/core/utils/status-helpers.js +149 -0
- package/dist/core/utils/status-helpers.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.d.ts +504 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +182 -0
- package/dist/types/index.js.map +1 -0
- package/dist/web/routes/graph.d.ts +17 -0
- package/dist/web/routes/graph.d.ts.map +1 -0
- package/dist/web/routes/graph.js +277 -0
- package/dist/web/routes/graph.js.map +1 -0
- package/dist/web/routes/projects.d.ts +14 -0
- package/dist/web/routes/projects.d.ts.map +1 -0
- package/dist/web/routes/projects.js +102 -0
- package/dist/web/routes/projects.js.map +1 -0
- package/dist/web/routes/tasks.d.ts +17 -0
- package/dist/web/routes/tasks.d.ts.map +1 -0
- package/dist/web/routes/tasks.js +538 -0
- package/dist/web/routes/tasks.js.map +1 -0
- package/dist/web/server.d.ts +121 -0
- package/dist/web/server.d.ts.map +1 -0
- package/dist/web/server.js +389 -0
- package/dist/web/server.js.map +1 -0
- package/dist/web-ui/assets/index-BB0qvF1y.css +1 -0
- package/dist/web-ui/assets/index-Vmm72oKY.js +34 -0
- package/dist/web-ui/index.html +14 -0
- package/dist/web-ui/vite.svg +1 -0
- package/package.json +94 -0
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Index Manager for fast task lookups
|
|
3
|
+
*
|
|
4
|
+
* Maintains pre-computed indexes for efficient queries:
|
|
5
|
+
* - Status-based grouping (byStatus)
|
|
6
|
+
* - Priority-based grouping (byPriority)
|
|
7
|
+
* - Root tasks (no incoming edges)
|
|
8
|
+
* - Orphan tasks (no edges)
|
|
9
|
+
* - Full-text search index (inverted index)
|
|
10
|
+
* - File reference index
|
|
11
|
+
*
|
|
12
|
+
* Provides O(1) incremental updates and O(n) full rebuild.
|
|
13
|
+
*
|
|
14
|
+
* @module core/storage
|
|
15
|
+
*/
|
|
16
|
+
import { TaskGraphStore } from '../graph/index.js';
|
|
17
|
+
/**
|
|
18
|
+
* Index Manager class
|
|
19
|
+
*
|
|
20
|
+
* Maintains indexes for fast task queries and filtering.
|
|
21
|
+
*/
|
|
22
|
+
export class IndexManager {
|
|
23
|
+
/** Tasks grouped by status */
|
|
24
|
+
_byStatus;
|
|
25
|
+
/** Tasks grouped by priority */
|
|
26
|
+
_byPriority;
|
|
27
|
+
/** Full-text search index (term -> task IDs) */
|
|
28
|
+
_searchText;
|
|
29
|
+
/** File reference index (file path -> task IDs) */
|
|
30
|
+
_files;
|
|
31
|
+
/** Root tasks (no incoming edges) - cached */
|
|
32
|
+
_rootTasks;
|
|
33
|
+
/** Orphan tasks (no edges) - cached */
|
|
34
|
+
_orphanTasks;
|
|
35
|
+
/** Cached result object */
|
|
36
|
+
_cachedIndexes;
|
|
37
|
+
/**
|
|
38
|
+
* Create a new IndexManager
|
|
39
|
+
*/
|
|
40
|
+
constructor() {
|
|
41
|
+
this._byStatus = new Map();
|
|
42
|
+
this._byPriority = new Map();
|
|
43
|
+
this._searchText = new Map();
|
|
44
|
+
this._files = new Map();
|
|
45
|
+
this._rootTasks = new Set();
|
|
46
|
+
this._orphanTasks = new Set();
|
|
47
|
+
this._cachedIndexes = null;
|
|
48
|
+
// Initialize status indexes
|
|
49
|
+
const statuses = ['ready', 'in_progress', 'in_review', 'completed', 'blocked'];
|
|
50
|
+
for (const status of statuses) {
|
|
51
|
+
this._byStatus.set(status, new Set());
|
|
52
|
+
}
|
|
53
|
+
// Initialize priority indexes
|
|
54
|
+
const priorities = ['top', 'second', 'later'];
|
|
55
|
+
for (const priority of priorities) {
|
|
56
|
+
this._byPriority.set(priority, new Set());
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Incremental update for a single task
|
|
61
|
+
* Removes old task from indexes and adds new version
|
|
62
|
+
* O(1) operation for most cases
|
|
63
|
+
*
|
|
64
|
+
* @param task - New or updated task
|
|
65
|
+
* @param oldTask - Previous task state (for removal from old indexes)
|
|
66
|
+
* @param graph - TaskGraphStore for edge information
|
|
67
|
+
*/
|
|
68
|
+
updateTask(task, oldTask, graph) {
|
|
69
|
+
// Remove old task from indexes if exists
|
|
70
|
+
if (oldTask) {
|
|
71
|
+
this._removeTask(oldTask);
|
|
72
|
+
}
|
|
73
|
+
// Add new task to indexes
|
|
74
|
+
this._addTask(task, graph);
|
|
75
|
+
// Invalidate cache
|
|
76
|
+
this._cachedIndexes = null;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Remove task from indexes
|
|
80
|
+
* @param task - Task to remove
|
|
81
|
+
* @private
|
|
82
|
+
*/
|
|
83
|
+
_removeTask(task) {
|
|
84
|
+
// Remove from status index
|
|
85
|
+
this._byStatus.get(task.status)?.delete(task.id);
|
|
86
|
+
// Remove from priority index
|
|
87
|
+
this._byPriority.get(task.priority)?.delete(task.id);
|
|
88
|
+
// Remove from search index
|
|
89
|
+
const text = `${task.title} ${task.description} ${task.notes}`.toLowerCase();
|
|
90
|
+
const tokens = text.match(/\b\w+\b/g) || [];
|
|
91
|
+
for (const token of tokens) {
|
|
92
|
+
this._searchText.get(token)?.delete(task.id);
|
|
93
|
+
// Clean up empty token entries
|
|
94
|
+
if (this._searchText.get(token)?.size === 0) {
|
|
95
|
+
this._searchText.delete(token);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// Remove from file index
|
|
99
|
+
for (const filePath of task.related_files) {
|
|
100
|
+
this._files.get(filePath)?.delete(task.id);
|
|
101
|
+
// Clean up empty file entries
|
|
102
|
+
if (this._files.get(filePath)?.size === 0) {
|
|
103
|
+
this._files.delete(filePath);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// Remove from root/orphan caches (will be rebuilt on next get)
|
|
107
|
+
this._rootTasks.delete(task.id);
|
|
108
|
+
this._orphanTasks.delete(task.id);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Add task to indexes
|
|
112
|
+
* @param task - Task to add
|
|
113
|
+
* @param graph - TaskGraphStore for edge information
|
|
114
|
+
* @private
|
|
115
|
+
*/
|
|
116
|
+
_addTask(task, graph) {
|
|
117
|
+
// Add to status index
|
|
118
|
+
if (!this._byStatus.has(task.status)) {
|
|
119
|
+
this._byStatus.set(task.status, new Set());
|
|
120
|
+
}
|
|
121
|
+
this._byStatus.get(task.status).add(task.id);
|
|
122
|
+
// Add to priority index
|
|
123
|
+
if (!this._byPriority.has(task.priority)) {
|
|
124
|
+
this._byPriority.set(task.priority, new Set());
|
|
125
|
+
}
|
|
126
|
+
this._byPriority.get(task.priority).add(task.id);
|
|
127
|
+
// Add to search index (tokenize and index)
|
|
128
|
+
const text = `${task.title} ${task.description} ${task.notes}`.toLowerCase();
|
|
129
|
+
const tokens = text.match(/\b\w+\b/g) || [];
|
|
130
|
+
for (const token of tokens) {
|
|
131
|
+
if (!this._searchText.has(token)) {
|
|
132
|
+
this._searchText.set(token, new Set());
|
|
133
|
+
}
|
|
134
|
+
this._searchText.get(token).add(task.id);
|
|
135
|
+
}
|
|
136
|
+
// Add to file reference index
|
|
137
|
+
for (const filePath of task.related_files) {
|
|
138
|
+
if (!this._files.has(filePath)) {
|
|
139
|
+
this._files.set(filePath, new Set());
|
|
140
|
+
}
|
|
141
|
+
this._files.get(filePath).add(task.id);
|
|
142
|
+
}
|
|
143
|
+
// Update root/orphan status
|
|
144
|
+
this._updateRootOrphanStatus(task.id, graph);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Update root/orphan status for a task
|
|
148
|
+
* @param taskId - Task ID to check
|
|
149
|
+
* @param graph - TaskGraphStore for edge information
|
|
150
|
+
* @private
|
|
151
|
+
*/
|
|
152
|
+
_updateRootOrphanStatus(taskId, graph) {
|
|
153
|
+
const incoming = graph.getIncomingEdges(taskId);
|
|
154
|
+
const outgoing = graph.getOutgoingEdges(taskId);
|
|
155
|
+
// Root task: no incoming edges
|
|
156
|
+
if (incoming.length === 0) {
|
|
157
|
+
this._rootTasks.add(taskId);
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
this._rootTasks.delete(taskId);
|
|
161
|
+
}
|
|
162
|
+
// Orphan task: no edges at all
|
|
163
|
+
if (incoming.length === 0 && outgoing.length === 0) {
|
|
164
|
+
this._orphanTasks.add(taskId);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
this._orphanTasks.delete(taskId);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Rebuild all indexes from scratch
|
|
172
|
+
* O(n) operation where n is the number of tasks
|
|
173
|
+
*
|
|
174
|
+
* @param tasks - Map of all tasks
|
|
175
|
+
* @param graph - TaskGraphStore for edge information
|
|
176
|
+
*/
|
|
177
|
+
rebuildIndexes(tasks, graph) {
|
|
178
|
+
// Clear existing indexes
|
|
179
|
+
this._byStatus.clear();
|
|
180
|
+
this._byPriority.clear();
|
|
181
|
+
this._searchText.clear();
|
|
182
|
+
this._files.clear();
|
|
183
|
+
this._rootTasks.clear();
|
|
184
|
+
this._orphanTasks.clear();
|
|
185
|
+
// Re-initialize status and priority maps
|
|
186
|
+
const statuses = ['ready', 'in_progress', 'in_review', 'completed', 'blocked'];
|
|
187
|
+
for (const status of statuses) {
|
|
188
|
+
this._byStatus.set(status, new Set());
|
|
189
|
+
}
|
|
190
|
+
const priorities = ['top', 'second', 'later'];
|
|
191
|
+
for (const priority of priorities) {
|
|
192
|
+
this._byPriority.set(priority, new Set());
|
|
193
|
+
}
|
|
194
|
+
// Rebuild from all tasks
|
|
195
|
+
for (const task of tasks.values()) {
|
|
196
|
+
this._addTask(task, graph);
|
|
197
|
+
}
|
|
198
|
+
// Invalidate cache
|
|
199
|
+
this._cachedIndexes = null;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Get task IDs by status
|
|
203
|
+
* @param status - Task status to filter by
|
|
204
|
+
* @returns Array of task IDs
|
|
205
|
+
*/
|
|
206
|
+
getByStatus(status) {
|
|
207
|
+
return Array.from(this._byStatus.get(status) || []);
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Get task IDs by priority
|
|
211
|
+
* @param priority - Task priority to filter by
|
|
212
|
+
* @returns Array of task IDs
|
|
213
|
+
*/
|
|
214
|
+
getByPriority(priority) {
|
|
215
|
+
return Array.from(this._byPriority.get(priority) || []);
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Search tasks by text query
|
|
219
|
+
* @param query - Search query (will be tokenized)
|
|
220
|
+
* @returns Array of task IDs matching any token
|
|
221
|
+
*/
|
|
222
|
+
search(query) {
|
|
223
|
+
const tokens = query.toLowerCase().match(/\b\w+\b/g) || [];
|
|
224
|
+
const results = new Set();
|
|
225
|
+
for (const token of tokens) {
|
|
226
|
+
const matching = this._searchText.get(token);
|
|
227
|
+
if (matching) {
|
|
228
|
+
for (const taskId of matching) {
|
|
229
|
+
results.add(taskId);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return Array.from(results);
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Get task IDs by related file
|
|
237
|
+
* @param filePath - File path to search for
|
|
238
|
+
* @returns Array of task IDs
|
|
239
|
+
*/
|
|
240
|
+
getByFile(filePath) {
|
|
241
|
+
return Array.from(this._files.get(filePath) || []);
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Get root tasks (no incoming edges)
|
|
245
|
+
* @returns Array of task IDs
|
|
246
|
+
*/
|
|
247
|
+
getRootTasks() {
|
|
248
|
+
return Array.from(this._rootTasks);
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Get orphan tasks (no edges)
|
|
252
|
+
* @returns Array of task IDs
|
|
253
|
+
*/
|
|
254
|
+
getOrphanTasks() {
|
|
255
|
+
return Array.from(this._orphanTasks);
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Get all indexes as a ProjectIndexes object
|
|
259
|
+
* Cached result - only recomputed if indexes changed
|
|
260
|
+
*
|
|
261
|
+
* @returns ProjectIndexes interface
|
|
262
|
+
*/
|
|
263
|
+
getIndexes() {
|
|
264
|
+
if (this._cachedIndexes) {
|
|
265
|
+
return this._cachedIndexes;
|
|
266
|
+
}
|
|
267
|
+
// Build result object
|
|
268
|
+
const result = {
|
|
269
|
+
byStatus: {},
|
|
270
|
+
byPriority: {},
|
|
271
|
+
rootTasks: this.getRootTasks(),
|
|
272
|
+
orphanTasks: this.getOrphanTasks(),
|
|
273
|
+
searchText: {},
|
|
274
|
+
files: {},
|
|
275
|
+
};
|
|
276
|
+
// Convert status sets to arrays
|
|
277
|
+
for (const [status, taskIds] of this._byStatus) {
|
|
278
|
+
result.byStatus[status] = Array.from(taskIds);
|
|
279
|
+
}
|
|
280
|
+
// Convert priority sets to arrays
|
|
281
|
+
for (const [priority, taskIds] of this._byPriority) {
|
|
282
|
+
result.byPriority[priority] = Array.from(taskIds);
|
|
283
|
+
}
|
|
284
|
+
// Convert search index sets to arrays
|
|
285
|
+
for (const [token, taskIds] of this._searchText) {
|
|
286
|
+
result.searchText[token] = Array.from(taskIds);
|
|
287
|
+
}
|
|
288
|
+
// Convert file index sets to arrays
|
|
289
|
+
for (const [filePath, taskIds] of this._files) {
|
|
290
|
+
result.files[filePath] = Array.from(taskIds);
|
|
291
|
+
}
|
|
292
|
+
// Cache result
|
|
293
|
+
this._cachedIndexes = result;
|
|
294
|
+
return result;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Clear all indexes
|
|
298
|
+
*/
|
|
299
|
+
clear() {
|
|
300
|
+
this._byStatus.clear();
|
|
301
|
+
this._byPriority.clear();
|
|
302
|
+
this._searchText.clear();
|
|
303
|
+
this._files.clear();
|
|
304
|
+
this._rootTasks.clear();
|
|
305
|
+
this._orphanTasks.clear();
|
|
306
|
+
this._cachedIndexes = null;
|
|
307
|
+
// Re-initialize status and priority maps
|
|
308
|
+
const statuses = ['ready', 'in_progress', 'in_review', 'completed', 'blocked'];
|
|
309
|
+
for (const status of statuses) {
|
|
310
|
+
this._byStatus.set(status, new Set());
|
|
311
|
+
}
|
|
312
|
+
const priorities = ['top', 'second', 'later'];
|
|
313
|
+
for (const priority of priorities) {
|
|
314
|
+
this._byPriority.set(priority, new Set());
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Get index statistics (for debugging)
|
|
319
|
+
* @returns Statistics about the indexes
|
|
320
|
+
*/
|
|
321
|
+
getStats() {
|
|
322
|
+
const statusCounts = {
|
|
323
|
+
ready: 0,
|
|
324
|
+
in_progress: 0,
|
|
325
|
+
in_review: 0,
|
|
326
|
+
completed: 0,
|
|
327
|
+
blocked: 0,
|
|
328
|
+
};
|
|
329
|
+
for (const [status, taskIds] of this._byStatus) {
|
|
330
|
+
statusCounts[status] = taskIds.size;
|
|
331
|
+
}
|
|
332
|
+
const priorityCounts = {
|
|
333
|
+
top: 0,
|
|
334
|
+
second: 0,
|
|
335
|
+
later: 0,
|
|
336
|
+
};
|
|
337
|
+
for (const [priority, taskIds] of this._byPriority) {
|
|
338
|
+
priorityCounts[priority] = taskIds.size;
|
|
339
|
+
}
|
|
340
|
+
return {
|
|
341
|
+
statusCounts,
|
|
342
|
+
priorityCounts,
|
|
343
|
+
searchTermsCount: this._searchText.size,
|
|
344
|
+
fileRefCount: this._files.size,
|
|
345
|
+
rootTasksCount: this._rootTasks.size,
|
|
346
|
+
orphanTasksCount: this._orphanTasks.size,
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
//# sourceMappingURL=indexer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indexer.js","sourceRoot":"","sources":["../../../src/core/storage/indexer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Status Helper Functions
|
|
3
|
+
*
|
|
4
|
+
* Utilities for automatic status transitions in the graph-based task system.
|
|
5
|
+
*
|
|
6
|
+
* @module core/utils/status-helpers
|
|
7
|
+
*/
|
|
8
|
+
import type { TaskGraphStore } from '../graph/index.js';
|
|
9
|
+
/**
|
|
10
|
+
* Recalculate status of all tasks that depend on a blocker
|
|
11
|
+
*
|
|
12
|
+
* When a blocker task's status changes (e.g., completed), this function
|
|
13
|
+
* recalculates the status of all tasks that were blocked by it.
|
|
14
|
+
*
|
|
15
|
+
* This enables the "all blockers resolved → ready" automatic transition
|
|
16
|
+
* from the status refactor spec (Rule 5).
|
|
17
|
+
*
|
|
18
|
+
* @param blockerId - The ID of the task whose status changed
|
|
19
|
+
* @param graph - The task graph containing all tasks
|
|
20
|
+
* @returns Array of task IDs that had their status recalculated
|
|
21
|
+
*/
|
|
22
|
+
export declare function recalculateDependentStatuses(blockerId: string, graph: TaskGraphStore): string[];
|
|
23
|
+
/**
|
|
24
|
+
* Check if all blockers for a task are resolved
|
|
25
|
+
*
|
|
26
|
+
* A blocker is considered resolved if:
|
|
27
|
+
* - The blocker task has status 'completed', OR
|
|
28
|
+
* - The blocker task no longer exists in the graph
|
|
29
|
+
*
|
|
30
|
+
* @param taskBlockers - Array of blocker task IDs
|
|
31
|
+
* @param graph - The task graph to check blocker status
|
|
32
|
+
* @returns True if all blockers are resolved or there are no blockers
|
|
33
|
+
*/
|
|
34
|
+
export declare function areAllBlockersResolved(taskBlockers: string[], graph: TaskGraphStore): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Get all tasks that are blocking a given task
|
|
37
|
+
*
|
|
38
|
+
* @param taskId - The task to get blockers for
|
|
39
|
+
* @param graph - The task graph
|
|
40
|
+
* @returns Array of blocker task nodes
|
|
41
|
+
*/
|
|
42
|
+
export declare function getActiveBlockers(taskId: string, graph: TaskGraphStore): Array<{
|
|
43
|
+
id: string;
|
|
44
|
+
title: string;
|
|
45
|
+
status: string;
|
|
46
|
+
}>;
|
|
47
|
+
/**
|
|
48
|
+
* Get all tasks that this task is blocking
|
|
49
|
+
*
|
|
50
|
+
* @param taskId - The task to find dependents for
|
|
51
|
+
* @param graph - The task graph
|
|
52
|
+
* @returns Array of task nodes that are blocked by this task
|
|
53
|
+
*/
|
|
54
|
+
export declare function getTasksBlockedBy(taskId: string, graph: TaskGraphStore): Array<{
|
|
55
|
+
id: string;
|
|
56
|
+
title: string;
|
|
57
|
+
status: string;
|
|
58
|
+
}>;
|
|
59
|
+
//# sourceMappingURL=status-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status-helpers.d.ts","sourceRoot":"","sources":["../../../src/core/utils/status-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD;;;;;;;;;;;;GAYG;AACH,wBAAgB,4BAA4B,CAC1C,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,cAAc,GACpB,MAAM,EAAE,CAmCV;AAuCD;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CACpC,YAAY,EAAE,MAAM,EAAE,EACtB,KAAK,EAAE,cAAc,GACpB,OAAO,CAcT;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,cAAc,GACpB,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAoBtD;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,cAAc,GACpB,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CActD"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Status Helper Functions
|
|
3
|
+
*
|
|
4
|
+
* Utilities for automatic status transitions in the graph-based task system.
|
|
5
|
+
*
|
|
6
|
+
* @module core/utils/status-helpers
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Recalculate status of all tasks that depend on a blocker
|
|
10
|
+
*
|
|
11
|
+
* When a blocker task's status changes (e.g., completed), this function
|
|
12
|
+
* recalculates the status of all tasks that were blocked by it.
|
|
13
|
+
*
|
|
14
|
+
* This enables the "all blockers resolved → ready" automatic transition
|
|
15
|
+
* from the status refactor spec (Rule 5).
|
|
16
|
+
*
|
|
17
|
+
* @param blockerId - The ID of the task whose status changed
|
|
18
|
+
* @param graph - The task graph containing all tasks
|
|
19
|
+
* @returns Array of task IDs that had their status recalculated
|
|
20
|
+
*/
|
|
21
|
+
export function recalculateDependentStatuses(blockerId, graph) {
|
|
22
|
+
const updatedTaskIds = [];
|
|
23
|
+
// Find all tasks that have this blocker in their blockers array
|
|
24
|
+
for (const task of graph.getAllTasks()) {
|
|
25
|
+
if (task.blockers.includes(blockerId)) {
|
|
26
|
+
const oldStatus = task.status;
|
|
27
|
+
// Check if ALL blockers are now resolved (completed or deleted)
|
|
28
|
+
const allBlockersResolved = areAllBlockersResolved(task.blockers, graph);
|
|
29
|
+
if (allBlockersResolved) {
|
|
30
|
+
// All blockers are resolved - calculate new status without considering blockers
|
|
31
|
+
// Use the standard status calculation logic but skip the blockers check
|
|
32
|
+
const newStatus = calculateStatusIgnoringBlockers(task);
|
|
33
|
+
if (newStatus !== task.status) {
|
|
34
|
+
task.status = newStatus;
|
|
35
|
+
// Touch the task to update timestamp
|
|
36
|
+
task.recalculateStatus(); // This will update timestamp
|
|
37
|
+
// Override the status since recalculateStatus() would set it back to blocked
|
|
38
|
+
task.status = newStatus;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
// Still has active blockers - just recalculate normally
|
|
43
|
+
task.recalculateStatus();
|
|
44
|
+
}
|
|
45
|
+
if (task.status !== oldStatus) {
|
|
46
|
+
updatedTaskIds.push(task.id);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return updatedTaskIds;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Calculate task status ignoring blockers
|
|
54
|
+
*
|
|
55
|
+
* Used when all blockers are resolved to determine what the status should be.
|
|
56
|
+
* This is the same logic as TaskNode.calculateStatus() but skips the blockers check.
|
|
57
|
+
*
|
|
58
|
+
* @param task - The task to calculate status for
|
|
59
|
+
* @returns The calculated status (ready, in_progress, or in_review)
|
|
60
|
+
*/
|
|
61
|
+
function calculateStatusIgnoringBlockers(task) {
|
|
62
|
+
// Check if ready for review (all items complete)
|
|
63
|
+
const allCriteriaComplete = task.success_criteria.every(c => c.completed);
|
|
64
|
+
const allDeliverablesComplete = task.deliverables.every(d => d.completed);
|
|
65
|
+
const allNeedFixComplete = task.need_fix.every(f => f.completed);
|
|
66
|
+
const allComplete = allCriteriaComplete && allDeliverablesComplete && allNeedFixComplete;
|
|
67
|
+
if (allComplete) {
|
|
68
|
+
return 'in_review';
|
|
69
|
+
}
|
|
70
|
+
// Check if work has started
|
|
71
|
+
const anyCriteriaChecked = task.success_criteria.some(c => c.completed);
|
|
72
|
+
const anyDeliverableChecked = task.deliverables.some(d => d.completed);
|
|
73
|
+
const hasNeedFix = task.need_fix.length > 0;
|
|
74
|
+
if (anyCriteriaChecked || anyDeliverableChecked || hasNeedFix) {
|
|
75
|
+
return 'in_progress';
|
|
76
|
+
}
|
|
77
|
+
// Default - ready for work
|
|
78
|
+
return 'ready';
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Check if all blockers for a task are resolved
|
|
82
|
+
*
|
|
83
|
+
* A blocker is considered resolved if:
|
|
84
|
+
* - The blocker task has status 'completed', OR
|
|
85
|
+
* - The blocker task no longer exists in the graph
|
|
86
|
+
*
|
|
87
|
+
* @param taskBlockers - Array of blocker task IDs
|
|
88
|
+
* @param graph - The task graph to check blocker status
|
|
89
|
+
* @returns True if all blockers are resolved or there are no blockers
|
|
90
|
+
*/
|
|
91
|
+
export function areAllBlockersResolved(taskBlockers, graph) {
|
|
92
|
+
if (taskBlockers.length === 0) {
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
for (const blockerId of taskBlockers) {
|
|
96
|
+
const blockerTask = graph.getNode(blockerId);
|
|
97
|
+
// If blocker doesn't exist or is not completed, task is still blocked
|
|
98
|
+
if (blockerTask && blockerTask.status !== 'completed') {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Get all tasks that are blocking a given task
|
|
106
|
+
*
|
|
107
|
+
* @param taskId - The task to get blockers for
|
|
108
|
+
* @param graph - The task graph
|
|
109
|
+
* @returns Array of blocker task nodes
|
|
110
|
+
*/
|
|
111
|
+
export function getActiveBlockers(taskId, graph) {
|
|
112
|
+
const task = graph.getNode(taskId);
|
|
113
|
+
if (!task || task.blockers.length === 0) {
|
|
114
|
+
return [];
|
|
115
|
+
}
|
|
116
|
+
const blockers = [];
|
|
117
|
+
for (const blockerId of task.blockers) {
|
|
118
|
+
const blockerTask = graph.getNode(blockerId);
|
|
119
|
+
if (blockerTask && blockerTask.status !== 'completed') {
|
|
120
|
+
blockers.push({
|
|
121
|
+
id: blockerId,
|
|
122
|
+
title: blockerTask.title,
|
|
123
|
+
status: blockerTask.status,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return blockers;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Get all tasks that this task is blocking
|
|
131
|
+
*
|
|
132
|
+
* @param taskId - The task to find dependents for
|
|
133
|
+
* @param graph - The task graph
|
|
134
|
+
* @returns Array of task nodes that are blocked by this task
|
|
135
|
+
*/
|
|
136
|
+
export function getTasksBlockedBy(taskId, graph) {
|
|
137
|
+
const blockedTasks = [];
|
|
138
|
+
for (const task of graph.getAllTasks()) {
|
|
139
|
+
if (task.blockers.includes(taskId)) {
|
|
140
|
+
blockedTasks.push({
|
|
141
|
+
id: task.id,
|
|
142
|
+
title: task.title,
|
|
143
|
+
status: task.status,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return blockedTasks;
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=status-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status-helpers.js","sourceRoot":"","sources":["../../../src/core/utils/status-helpers.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Octie - Graph-based task management system
|
|
3
|
+
*
|
|
4
|
+
* Main entry point for the library.
|
|
5
|
+
*/
|
|
6
|
+
export { TaskGraphStore } from './core/graph/index.js';
|
|
7
|
+
export { TaskNode } from './core/models/task-node.js';
|
|
8
|
+
export { TaskStorage } from './core/storage/file-store.js';
|
|
9
|
+
export * from './types/index.js';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC3D,cAAc,kBAAkB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Octie - Graph-based task management system
|
|
3
|
+
*
|
|
4
|
+
* Main entry point for the library.
|
|
5
|
+
*/
|
|
6
|
+
export { TaskGraphStore } from './core/graph/index.js';
|
|
7
|
+
export { TaskNode } from './core/models/task-node.js';
|
|
8
|
+
export { TaskStorage } from './core/storage/file-store.js';
|
|
9
|
+
export * from './types/index.js';
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC3D,cAAc,kBAAkB,CAAC"}
|