@felan-ai/ext-tasks 0.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/dist/store.js ADDED
@@ -0,0 +1,165 @@
1
+ import { randomBytes } from 'node:crypto';
2
+ import { join } from 'node:path';
3
+ import { cloneTaskState, createTask, emptyTaskState, getTask, listTasks, parseTaskState, TASK_ID_PATTERN, updateTask, } from './graph.js';
4
+ const encoder = new TextEncoder();
5
+ const decoder = new TextDecoder();
6
+ const stores = new Map();
7
+ export class TaskStore {
8
+ root;
9
+ statePath;
10
+ #key;
11
+ #storage;
12
+ #shared;
13
+ #listeners = new Set();
14
+ #closed = false;
15
+ constructor(runtime) {
16
+ const storage = runtime.storage('session');
17
+ this.#storage = storage;
18
+ this.#key = `${runtime.kind}\0${storage.root}`;
19
+ this.root = join(storage.root, 'tasks');
20
+ this.statePath = join(this.root, 'state.json');
21
+ const existing = stores.get(this.#key);
22
+ this.#shared = existing ?? {
23
+ directory: this.root,
24
+ statePath: this.statePath,
25
+ listeners: new Set(),
26
+ control: Promise.resolve(),
27
+ refs: 0,
28
+ };
29
+ if (!existing)
30
+ stores.set(this.#key, this.#shared);
31
+ this.#shared.refs += 1;
32
+ }
33
+ async snapshot() {
34
+ return this.#run(async () => {
35
+ const state = await readState(this.#storage, this.#shared);
36
+ this.#replaceState(state);
37
+ return cloneTaskState(state);
38
+ });
39
+ }
40
+ async create(input) {
41
+ return this.#run(async () => {
42
+ const current = await readState(this.#storage, this.#shared);
43
+ let id = generateTaskId();
44
+ while (current.tasks.some((task) => task.id === id))
45
+ id = generateTaskId();
46
+ const result = createTask(current, input, id, new Date().toISOString());
47
+ await writeState(this.#storage, this.#shared, result.state);
48
+ this.#replaceState(result.state, true);
49
+ return cloneMutation(result);
50
+ });
51
+ }
52
+ async update(input, actorSessionId) {
53
+ return this.#run(async () => {
54
+ const current = await readState(this.#storage, this.#shared);
55
+ const result = updateTask(current, input, actorSessionId, new Date().toISOString());
56
+ await writeState(this.#storage, this.#shared, result.state);
57
+ this.#replaceState(result.state, true);
58
+ return cloneMutation(result);
59
+ });
60
+ }
61
+ async get(id) {
62
+ const state = await this.snapshot();
63
+ return { state, task: getTask(state, id) };
64
+ }
65
+ async list(view) {
66
+ const state = await this.snapshot();
67
+ return { state, tasks: listTasks(state, view) };
68
+ }
69
+ subscribe(listener) {
70
+ this.#assertOpen();
71
+ this.#listeners.add(listener);
72
+ this.#shared.listeners.add(listener);
73
+ if (this.#shared.state)
74
+ notify(listener, this.#shared.state);
75
+ return () => {
76
+ this.#listeners.delete(listener);
77
+ this.#shared.listeners.delete(listener);
78
+ };
79
+ }
80
+ close() {
81
+ if (this.#closed)
82
+ return;
83
+ this.#closed = true;
84
+ for (const listener of this.#listeners)
85
+ this.#shared.listeners.delete(listener);
86
+ this.#listeners.clear();
87
+ this.#shared.refs -= 1;
88
+ if (this.#shared.refs === 0 && stores.get(this.#key) === this.#shared)
89
+ stores.delete(this.#key);
90
+ }
91
+ async #run(operation) {
92
+ this.#assertOpen();
93
+ const previous = this.#shared.control;
94
+ let release;
95
+ this.#shared.control = new Promise((resolve) => {
96
+ release = resolve;
97
+ });
98
+ await previous;
99
+ try {
100
+ this.#assertOpen();
101
+ return await operation();
102
+ }
103
+ finally {
104
+ release();
105
+ }
106
+ }
107
+ #replaceState(state, alwaysNotify = false) {
108
+ const changed = this.#shared.state?.revision !== state.revision;
109
+ this.#shared.state = cloneTaskState(state);
110
+ if (!alwaysNotify && !changed)
111
+ return;
112
+ for (const listener of this.#shared.listeners)
113
+ notify(listener, state);
114
+ }
115
+ #assertOpen() {
116
+ if (this.#closed)
117
+ throw new Error('Task store is closed');
118
+ }
119
+ }
120
+ async function readState(storage, shared) {
121
+ let bytes;
122
+ try {
123
+ bytes = await storage.readFile(shared.statePath);
124
+ }
125
+ catch (error) {
126
+ if (isNotFoundError(error))
127
+ return emptyTaskState();
128
+ throw error;
129
+ }
130
+ let value;
131
+ try {
132
+ value = JSON.parse(decoder.decode(bytes));
133
+ }
134
+ catch {
135
+ throw new Error(`Task state is not valid JSON: ${shared.statePath}`);
136
+ }
137
+ return parseTaskState(value);
138
+ }
139
+ async function writeState(storage, shared, state) {
140
+ await storage.mkdir(shared.directory, { recursive: true });
141
+ await storage.writeFile(shared.statePath, encoder.encode(`${JSON.stringify(state, null, 2)}\n`));
142
+ }
143
+ function notify(listener, state) {
144
+ try {
145
+ listener(cloneTaskState(state));
146
+ }
147
+ catch {
148
+ // Presentation listeners cannot roll back an already persisted mutation.
149
+ }
150
+ }
151
+ function generateTaskId() {
152
+ const id = `T-${randomBytes(3).toString('hex').toUpperCase()}`;
153
+ if (!TASK_ID_PATTERN.test(id))
154
+ throw new Error('Generated an invalid task id');
155
+ return id;
156
+ }
157
+ function cloneMutation(result) {
158
+ const state = cloneTaskState(result.state);
159
+ return { state, task: getTask(state, result.task.id) };
160
+ }
161
+ function isNotFoundError(error) {
162
+ return error instanceof Error && (('code' in error && error.code === 'ENOENT')
163
+ || /(?:not found|does not exist|no such file)/iu.test(error.message));
164
+ }
165
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { ExtensionContext } from '@felan-ai/agent-core';
2
+ import type { TaskStore } from '../store.js';
3
+ type Theme = ExtensionContext['ui']['theme'];
4
+ export declare class TasksOverlay {
5
+ #private;
6
+ private readonly store;
7
+ private readonly theme;
8
+ private readonly done;
9
+ private readonly requestRender;
10
+ private readonly onDispose;
11
+ constructor(store: TaskStore, theme: Theme, done: () => void, requestRender: () => void, onDispose?: () => void);
12
+ handleInput(data: string): void;
13
+ render(width: number): string[];
14
+ invalidate(): void;
15
+ dispose(): void;
16
+ }
17
+ export {};
18
+ //# sourceMappingURL=tasks-overlay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks-overlay.d.ts","sourceRoot":"","sources":["../../src/ui/tasks-overlay.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAU7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAO7C,KAAK,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC;AAG7C,qBAAa,YAAY;;IAarB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAJT,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,MAAM,IAAI,EAChB,aAAa,EAAE,MAAM,IAAI,EACzB,SAAS,GAAE,MAAM,IAAe;IAUnD,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IA2C/B,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IAY/B,UAAU,IAAI,IAAI;IAElB,OAAO,IAAI,IAAI;CAuJhB"}
@@ -0,0 +1,267 @@
1
+ import { matchesKey, truncateToWidth } from '@earendil-works/pi-tui';
2
+ import { emptyTaskState, listTasks, taskAvailability } from '../graph.js';
3
+ import { formatTaskDetails, formatTaskLine, formatTaskSummary, taskGraphLayers, } from '../presentation.js';
4
+ const LIST_ROWS = 18;
5
+ const CONTENT_ROWS = 24;
6
+ const PADDING_X = 2;
7
+ const PADDING_Y = 1;
8
+ export class TasksOverlay {
9
+ store;
10
+ theme;
11
+ done;
12
+ requestRender;
13
+ onDispose;
14
+ #unsubscribe;
15
+ #state = emptyTaskState();
16
+ #tasks = [];
17
+ #selected = 0;
18
+ #scroll = 0;
19
+ #contentScroll = 0;
20
+ #loading = true;
21
+ #message = '';
22
+ #view = 'list';
23
+ #disposed = false;
24
+ constructor(store, theme, done, requestRender, onDispose = () => { }) {
25
+ this.store = store;
26
+ this.theme = theme;
27
+ this.done = done;
28
+ this.requestRender = requestRender;
29
+ this.onDispose = onDispose;
30
+ this.#unsubscribe = store.subscribe((state) => {
31
+ if (this.#disposed)
32
+ return;
33
+ this.#setState(state);
34
+ this.requestRender();
35
+ });
36
+ void this.#refresh();
37
+ }
38
+ handleInput(data) {
39
+ if (this.#disposed)
40
+ return;
41
+ if (matchesKey(data, 'escape') || data === 'q') {
42
+ this.#close();
43
+ return;
44
+ }
45
+ if (data === 'r') {
46
+ void this.#refresh();
47
+ return;
48
+ }
49
+ if (data === 'g') {
50
+ this.#view = this.#view === 'graph' ? 'list' : 'graph';
51
+ this.#contentScroll = 0;
52
+ this.requestRender();
53
+ return;
54
+ }
55
+ if (this.#view === 'detail') {
56
+ if (matchesKey(data, 'backspace') || matchesKey(data, 'left')) {
57
+ this.#view = 'list';
58
+ this.#contentScroll = 0;
59
+ this.requestRender();
60
+ }
61
+ else {
62
+ this.#handleContentInput(data);
63
+ }
64
+ return;
65
+ }
66
+ if (this.#view === 'graph') {
67
+ this.#handleContentInput(data);
68
+ return;
69
+ }
70
+ if (matchesKey(data, 'up') || data === 'k')
71
+ this.#select(-1);
72
+ if (matchesKey(data, 'down') || data === 'j')
73
+ this.#select(1);
74
+ if (matchesKey(data, 'ctrl+u'))
75
+ this.#select(-LIST_ROWS);
76
+ if (matchesKey(data, 'ctrl+d'))
77
+ this.#select(LIST_ROWS);
78
+ if (matchesKey(data, 'home'))
79
+ this.#select(-this.#tasks.length);
80
+ if (matchesKey(data, 'end'))
81
+ this.#select(this.#tasks.length);
82
+ if ((matchesKey(data, 'return') || matchesKey(data, 'right')) && this.#tasks.length > 0) {
83
+ this.#view = 'detail';
84
+ this.#contentScroll = 0;
85
+ this.requestRender();
86
+ }
87
+ }
88
+ render(width) {
89
+ const lines = this.#view === 'detail'
90
+ ? this.#renderDetail()
91
+ : this.#view === 'graph'
92
+ ? this.#renderGraph()
93
+ : this.#renderList();
94
+ const innerWidth = Math.max(1, width - PADDING_X * 2);
95
+ const prefix = ' '.repeat(PADDING_X);
96
+ const padded = lines.map((line) => `${prefix}${truncateToWidth(line, innerWidth, '…')}${prefix}`);
97
+ return [...Array(PADDING_Y).fill(''), ...padded, ...Array(PADDING_Y).fill('')];
98
+ }
99
+ invalidate() { }
100
+ dispose() {
101
+ if (this.#disposed)
102
+ return;
103
+ this.#disposed = true;
104
+ this.#unsubscribe();
105
+ this.onDispose();
106
+ }
107
+ #renderList() {
108
+ const lines = [
109
+ this.theme.fg('accent', this.theme.bold('Session Tasks'))
110
+ + this.theme.fg('dim', ' ↑↓ select • enter/→ details • g graph • r refresh • q/esc close'),
111
+ this.theme.fg('muted', formatTaskSummary(this.#state)),
112
+ ];
113
+ if (this.#loading)
114
+ lines.push(this.theme.fg('warning', 'Refreshing...'));
115
+ if (this.#message)
116
+ lines.push(this.theme.fg('muted', this.#message));
117
+ lines.push('');
118
+ if (this.#tasks.length === 0) {
119
+ lines.push(this.theme.fg('dim', 'No session tasks.'));
120
+ return lines;
121
+ }
122
+ const end = Math.min(this.#tasks.length, this.#scroll + LIST_ROWS);
123
+ lines.push(this.theme.fg('dim', `Showing tasks ${this.#scroll + 1}-${end}/${this.#tasks.length}`));
124
+ for (let index = this.#scroll; index < end; index += 1) {
125
+ const task = this.#tasks[index];
126
+ const marker = index === this.#selected ? this.theme.fg('accent', '▶') : ' ';
127
+ lines.push(`${marker} ${statusIcon(task, this.#state, this.theme)} ${formatTaskLine(task, this.#state)}`);
128
+ }
129
+ return lines;
130
+ }
131
+ #renderDetail() {
132
+ const task = this.#tasks[this.#selected];
133
+ if (!task)
134
+ return [this.theme.fg('dim', 'No task selected.')];
135
+ return this.#renderScrollable([
136
+ this.theme.fg('accent', this.theme.bold(task.id))
137
+ + this.theme.fg('dim', ' backspace/← tasks • ↑↓ scroll • g graph • r refresh • q/esc close'),
138
+ ], ['', ...formatTaskDetails(this.#state, task).split('\n')]);
139
+ }
140
+ #renderGraph() {
141
+ const header = [
142
+ this.theme.fg('accent', this.theme.bold('Task Graph'))
143
+ + this.theme.fg('dim', ' ↑↓ scroll • g tasks • r refresh • q/esc close'),
144
+ this.theme.fg('muted', formatTaskSummary(this.#state)),
145
+ ];
146
+ const lines = [''];
147
+ const layers = taskGraphLayers(this.#state);
148
+ if (layers.length === 0)
149
+ return [...header, '', this.theme.fg('dim', 'No session tasks.')];
150
+ layers.forEach((layer, index) => {
151
+ lines.push(this.theme.fg('accent', `Layer ${index}`));
152
+ for (const task of layer) {
153
+ const prerequisites = task.blockedBy.length > 0 ? ` ← ${task.blockedBy.join(', ')}` : '';
154
+ lines.push(` ${statusIcon(task, this.#state, this.theme)} ${task.id} ${task.title}${prerequisites}`);
155
+ }
156
+ lines.push('');
157
+ });
158
+ return this.#renderScrollable(header, lines);
159
+ }
160
+ async #refresh() {
161
+ if (this.#disposed)
162
+ return;
163
+ this.#loading = true;
164
+ this.requestRender();
165
+ try {
166
+ const state = await this.store.snapshot();
167
+ if (this.#disposed)
168
+ return;
169
+ this.#setState(state);
170
+ this.#message = `Last refresh: ${new Date().toLocaleTimeString()}`;
171
+ }
172
+ catch (error) {
173
+ if (this.#disposed)
174
+ return;
175
+ this.#message = error instanceof Error ? error.message : String(error);
176
+ }
177
+ finally {
178
+ if (!this.#disposed) {
179
+ this.#loading = false;
180
+ this.requestRender();
181
+ }
182
+ }
183
+ }
184
+ #setState(state) {
185
+ const selectedId = this.#tasks[this.#selected]?.id;
186
+ this.#state = state;
187
+ this.#tasks = listTasks(state, 'all');
188
+ const nextSelected = selectedId ? this.#tasks.findIndex((task) => task.id === selectedId) : -1;
189
+ this.#selected = nextSelected >= 0
190
+ ? nextSelected
191
+ : Math.min(this.#selected, Math.max(0, this.#tasks.length - 1));
192
+ this.#clampScroll();
193
+ this.#clampContentScroll();
194
+ }
195
+ #select(delta) {
196
+ if (this.#tasks.length === 0)
197
+ return;
198
+ this.#selected = Math.max(0, Math.min(this.#tasks.length - 1, this.#selected + delta));
199
+ this.#clampScroll();
200
+ this.requestRender();
201
+ }
202
+ #clampScroll() {
203
+ if (this.#selected < this.#scroll)
204
+ this.#scroll = this.#selected;
205
+ if (this.#selected >= this.#scroll + LIST_ROWS)
206
+ this.#scroll = this.#selected - LIST_ROWS + 1;
207
+ this.#scroll = Math.max(0, Math.min(this.#scroll, Math.max(0, this.#tasks.length - LIST_ROWS)));
208
+ }
209
+ #handleContentInput(data) {
210
+ if (matchesKey(data, 'up') || data === 'k')
211
+ this.#scrollContent(-1);
212
+ if (matchesKey(data, 'down') || data === 'j')
213
+ this.#scrollContent(1);
214
+ if (matchesKey(data, 'ctrl+u'))
215
+ this.#scrollContent(-CONTENT_ROWS);
216
+ if (matchesKey(data, 'ctrl+d'))
217
+ this.#scrollContent(CONTENT_ROWS);
218
+ if (matchesKey(data, 'home'))
219
+ this.#scrollContent(-this.#contentLength());
220
+ if (matchesKey(data, 'end'))
221
+ this.#scrollContent(this.#contentLength());
222
+ }
223
+ #scrollContent(delta) {
224
+ this.#contentScroll += delta;
225
+ this.#clampContentScroll();
226
+ this.requestRender();
227
+ }
228
+ #clampContentScroll() {
229
+ this.#contentScroll = Math.max(0, Math.min(this.#contentScroll, Math.max(0, this.#contentLength() - CONTENT_ROWS)));
230
+ }
231
+ #contentLength() {
232
+ if (this.#view === 'detail') {
233
+ const task = this.#tasks[this.#selected];
234
+ return task ? formatTaskDetails(this.#state, task).split('\n').length + 1 : 0;
235
+ }
236
+ if (this.#view === 'graph') {
237
+ return taskGraphLayers(this.#state).reduce((count, layer) => count + layer.length + 2, 1);
238
+ }
239
+ return 0;
240
+ }
241
+ #renderScrollable(header, body) {
242
+ const maxScroll = Math.max(0, body.length - CONTENT_ROWS);
243
+ this.#contentScroll = Math.min(this.#contentScroll, maxScroll);
244
+ const end = Math.min(body.length, this.#contentScroll + CONTENT_ROWS);
245
+ const range = body.length > CONTENT_ROWS
246
+ ? this.theme.fg('dim', `Showing lines ${this.#contentScroll + 1}-${end}/${body.length}`)
247
+ : '';
248
+ return [...header, ...(range ? [range] : []), ...body.slice(this.#contentScroll, end)];
249
+ }
250
+ #close() {
251
+ this.dispose();
252
+ this.done();
253
+ }
254
+ }
255
+ function statusIcon(task, state, theme) {
256
+ const availability = taskAvailability(task, state);
257
+ if (availability === 'completed')
258
+ return theme.fg('success', '✓');
259
+ if (availability === 'in_progress')
260
+ return theme.fg('accent', '◐');
261
+ if (availability === 'blocked' || availability === 'waiting')
262
+ return theme.fg('warning', '⊘');
263
+ if (availability === 'cancelled')
264
+ return theme.fg('dim', '×');
265
+ return theme.fg('muted', '○');
266
+ }
267
+ //# sourceMappingURL=tasks-overlay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks-overlay.js","sourceRoot":"","sources":["../../src/ui/tasks-overlay.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@felan-ai/ext-tasks",
3
+ "version": "0.0.0",
4
+ "description": "Dependency-aware session task tracking for Felan",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/felan-ai/felan.git",
10
+ "directory": "packages/ext-tasks"
11
+ },
12
+ "engines": {
13
+ "node": ">=22.19.0"
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "LICENSE",
18
+ "NOTICE",
19
+ "README.md"
20
+ ],
21
+ "exports": {
22
+ ".": {
23
+ "types": "./dist/index.d.ts",
24
+ "import": "./dist/index.js"
25
+ }
26
+ },
27
+ "dependencies": {
28
+ "@earendil-works/pi-tui": "0.83.0",
29
+ "typebox": "1.1.38"
30
+ },
31
+ "peerDependencies": {
32
+ "@felan-ai/agent-core": "^0.4.0"
33
+ },
34
+ "devDependencies": {
35
+ "@felan-ai/agent-core": "0.4.0"
36
+ },
37
+ "publishConfig": {
38
+ "access": "public",
39
+ "provenance": true
40
+ },
41
+ "scripts": {
42
+ "build": "rm -rf dist && tsc -p tsconfig.build.json",
43
+ "type-check": "tsc -p tsconfig.json --noEmit",
44
+ "test": "vitest run"
45
+ }
46
+ }