@luckydraw/cumulus 1.0.40 → 1.0.42
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/CHANGELOG.md +17 -0
- package/dist/gateway/adapters/webchat.js +5 -3
- package/dist/gateway/adapters/webchat.js.map +1 -1
- package/dist/gateway/static/widget.js +3 -4
- package/dist/gateway/tasks-refresh.d.ts +43 -9
- package/dist/gateway/tasks-refresh.d.ts.map +1 -1
- package/dist/gateway/tasks-refresh.js +153 -22
- package/dist/gateway/tasks-refresh.js.map +1 -1
- package/dist/gateway/tasks.d.ts +30 -19
- package/dist/gateway/tasks.d.ts.map +1 -1
- package/dist/gateway/tasks.js +42 -55
- package/dist/gateway/tasks.js.map +1 -1
- package/dist/lib/config.d.ts +11 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +32 -3
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/tasks-file.d.ts +6 -0
- package/dist/lib/tasks-file.d.ts.map +1 -1
- package/dist/lib/tasks-file.js +6 -0
- package/dist/lib/tasks-file.js.map +1 -1
- package/dist/lib/templates.d.ts.map +1 -1
- package/dist/lib/templates.js +5 -3
- package/dist/lib/templates.js.map +1 -1
- package/package.json +1 -1
|
@@ -17,11 +17,16 @@
|
|
|
17
17
|
* is checked before it is written, and a run that loses a task id, fails to
|
|
18
18
|
* parse, or comes back without the marker is refused WHOLE. The git snapshot is
|
|
19
19
|
* the belt; these checks are the braces.
|
|
20
|
+
*
|
|
21
|
+
* Task 180, after the first live press: `## Done` is now split off before the
|
|
22
|
+
* prompt is built and re-attached after, and an empty queue is refused outright.
|
|
23
|
+
* See {@link splitOffDone} — the model was rewriting the one section the format
|
|
24
|
+
* says is never sent to a model, because it was the only thing left to touch.
|
|
20
25
|
*/
|
|
21
26
|
import { execFileSync } from 'child_process';
|
|
22
27
|
import * as fs from 'fs';
|
|
23
28
|
import * as path from 'path';
|
|
24
|
-
import { TASKS_FORMAT_SECTION, hasTasksMarker, parseTasksFile } from '../lib/tasks-file.js';
|
|
29
|
+
import { TASKS_FORMAT_SECTION, emptyTasksFile, hasTasksMarker, parseTasksFile, } from '../lib/tasks-file.js';
|
|
25
30
|
import { getCurrentVersion } from '../lib/version-check.js';
|
|
26
31
|
import { readTasks, resolveRefreshTarget } from './tasks.js';
|
|
27
32
|
import { runWorker } from './worker.js';
|
|
@@ -61,6 +66,50 @@ export function taskIdsIn(content) {
|
|
|
61
66
|
}
|
|
62
67
|
return ids;
|
|
63
68
|
}
|
|
69
|
+
/** The `## Done` heading, alone on its line — the same shape the parser accepts. */
|
|
70
|
+
const DONE_HEADING_RE = /^## +Done *$/;
|
|
71
|
+
/**
|
|
72
|
+
* Split a tasks file at its `## Done` heading.
|
|
73
|
+
*
|
|
74
|
+
* Task 180: `## Done` is the record of work that has left the queue, and the
|
|
75
|
+
* format's own rule is that it is never sent to a model. The first live Refresh
|
|
76
|
+
* proved why that has to be enforced with scissors rather than with a sentence in
|
|
77
|
+
* the prompt: handed the whole file and an empty queue, the model spent its one
|
|
78
|
+
* call appending "the reload has happened" to twelve finished tasks.
|
|
79
|
+
*
|
|
80
|
+
* The LAST heading wins, because the manual carried inside every migrated file
|
|
81
|
+
* quotes `## Done` while describing the grammar.
|
|
82
|
+
*/
|
|
83
|
+
export function splitOffDone(content) {
|
|
84
|
+
const lines = content.split('\n');
|
|
85
|
+
let at = -1;
|
|
86
|
+
for (let i = 0; i < lines.length; i++)
|
|
87
|
+
if (DONE_HEADING_RE.test(lines[i]))
|
|
88
|
+
at = i;
|
|
89
|
+
if (at < 0)
|
|
90
|
+
return { head: content, done: null };
|
|
91
|
+
return { head: lines.slice(0, at).join('\n'), done: lines.slice(at).join('\n') };
|
|
92
|
+
}
|
|
93
|
+
/** The rows under a `## Done` heading, with the heading and its blank padding gone. */
|
|
94
|
+
function doneBody(section) {
|
|
95
|
+
return section.split('\n').slice(1).join('\n').trim();
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Re-attach the withheld record to the model's answer.
|
|
99
|
+
*
|
|
100
|
+
* The original section goes back byte-for-byte. If the model emitted a `## Done`
|
|
101
|
+
* of its own — it is told not to — those rows are spliced in ABOVE the preserved
|
|
102
|
+
* ones rather than discarded: dropping them would lose their ids, and the drop
|
|
103
|
+
* check would then refuse an answer whose only sin was disobedience.
|
|
104
|
+
*/
|
|
105
|
+
export function stitchDone(answer, originalDone) {
|
|
106
|
+
const split = splitOffDone(answer);
|
|
107
|
+
const moved = split.done ? doneBody(split.done) : '';
|
|
108
|
+
const kept = doneBody(originalDone);
|
|
109
|
+
const heading = originalDone.split('\n', 1)[0];
|
|
110
|
+
const body = [moved, kept].filter(Boolean).join('\n');
|
|
111
|
+
return `${split.head.trimEnd()}\n\n${heading}\n\n${body}\n`;
|
|
112
|
+
}
|
|
64
113
|
/** Strip a ```-fenced wrapper, which a chat-tuned model adds however firmly it is told not to. */
|
|
65
114
|
export function unfence(answer) {
|
|
66
115
|
const trimmed = answer.trim();
|
|
@@ -110,6 +159,17 @@ export function snapshotBeforeRefresh(filePath) {
|
|
|
110
159
|
throw new TasksRefreshError(`Could not commit a snapshot of ${rel} before refreshing: ${err instanceof Error ? err.message : String(err)}`);
|
|
111
160
|
}
|
|
112
161
|
}
|
|
162
|
+
/**
|
|
163
|
+
* Is there nothing in this file but headings and blank lines? The March-era
|
|
164
|
+
* scaffold wrote `# <name> Tasks` and nothing else; converting that through a
|
|
165
|
+
* model would be an invitation to invent tasks (task 183).
|
|
166
|
+
*/
|
|
167
|
+
export function isBlankTasksFile(content) {
|
|
168
|
+
return content.split('\n').every(line => {
|
|
169
|
+
const t = line.trim();
|
|
170
|
+
return t === '' || t.startsWith('#');
|
|
171
|
+
});
|
|
172
|
+
}
|
|
113
173
|
/** Filenames under `docs/tasks/`, so the model can attach `doc` fields it can verify exist. */
|
|
114
174
|
function taskDocListing(cwd) {
|
|
115
175
|
try {
|
|
@@ -131,10 +191,43 @@ function taskDocListing(cwd) {
|
|
|
131
191
|
* running. That last one is the thing Karl complained about — rows still saying
|
|
132
192
|
* "needs reload" long after the reload happened.
|
|
133
193
|
*/
|
|
194
|
+
/**
|
|
195
|
+
* Rules 1 and 6 — the two that change when the record is withheld: what to
|
|
196
|
+
* output, and where a finished task goes.
|
|
197
|
+
*/
|
|
198
|
+
function promptShape(doneWithheld) {
|
|
199
|
+
if (doneWithheld) {
|
|
200
|
+
return {
|
|
201
|
+
rule1: [
|
|
202
|
+
'1. Output the file down to the END OF THE QUEUE and stop there: a `# <name> Tasks`',
|
|
203
|
+
' title, the marker line `<!-- cumulus:tasks v1 -->` alone on its own line within',
|
|
204
|
+
' the first ten lines, then `## Format` (verbatim as given above) and `## Queue`.',
|
|
205
|
+
' Do NOT write a `## Done` section. The file has one; it is finished work, it was',
|
|
206
|
+
' deliberately withheld from you, and it is re-attached unchanged after you answer.',
|
|
207
|
+
].join('\n'),
|
|
208
|
+
rule6: [
|
|
209
|
+
'6. When a task is finished, mark its row `[✅]` and LEAVE IT IN THE QUEUE. Moving a',
|
|
210
|
+
" task out of the queue is the user's decision, taken in the drawer, not yours.",
|
|
211
|
+
].join('\n'),
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
return {
|
|
215
|
+
rule1: [
|
|
216
|
+
'1. Output the whole file: a `# <name> Tasks` title, the marker line',
|
|
217
|
+
' `<!-- cumulus:tasks v1 -->` alone on its own line within the first ten lines,',
|
|
218
|
+
' then `## Format` (verbatim as given above), `## Queue`, and `## Done`.',
|
|
219
|
+
].join('\n'),
|
|
220
|
+
rule6: [
|
|
221
|
+
'6. Finished work belongs in `## Done` with a `done <YYYY-MM-DD>` field. Work still',
|
|
222
|
+
' to do belongs in `## Queue`, in build order, most important first.',
|
|
223
|
+
].join('\n'),
|
|
224
|
+
};
|
|
225
|
+
}
|
|
134
226
|
export function buildRefreshPrompt(input) {
|
|
135
227
|
const docs = input.docs.length
|
|
136
228
|
? input.docs.map(d => `- docs/tasks/${d}`).join('\n')
|
|
137
229
|
: '(no docs/tasks directory)';
|
|
230
|
+
const shape = promptShape(input.doneWithheld);
|
|
138
231
|
return [
|
|
139
232
|
'You are rewriting a project task file into the exact format specified below.',
|
|
140
233
|
'Return ONLY the complete new file. No preamble, no explanation, no code fence.',
|
|
@@ -143,30 +236,30 @@ export function buildRefreshPrompt(input) {
|
|
|
143
236
|
TASKS_FORMAT_SECTION,
|
|
144
237
|
'',
|
|
145
238
|
'=== RULES ===',
|
|
146
|
-
|
|
147
|
-
'
|
|
148
|
-
' then `## Format` (verbatim as given above), `## Queue`, and `## Done`.',
|
|
149
|
-
'2. EVERY task in the current file must appear in your output, with the SAME id.',
|
|
239
|
+
shape.rule1,
|
|
240
|
+
'2. EVERY task shown to you must appear in your output, with the SAME id.',
|
|
150
241
|
' Losing an id fails the whole refresh and nothing is written. If a task has no',
|
|
151
242
|
' id, mint one that does not collide with any other id in the file.',
|
|
152
243
|
'3. Prose belongs in `note` lines and nowhere else. A task row is one line.',
|
|
153
244
|
"4. Re-check each task's status against the evidence below. If you CANNOT ground a",
|
|
154
245
|
' status change in that evidence, leave the status exactly as it is.',
|
|
155
246
|
'5. When you do change a status, add a `note` saying why, so the change is auditable.',
|
|
156
|
-
|
|
157
|
-
' to do belongs in `## Queue`, in build order, most important first.',
|
|
247
|
+
shape.rule6,
|
|
158
248
|
'',
|
|
159
249
|
'=== EVIDENCE YOU CANNOT GET FROM THE FILE ===',
|
|
160
|
-
`The gateway is currently running version ${input.version}.
|
|
161
|
-
'change is "published, needs reload" for a version at or below this one is
|
|
162
|
-
'the reload has happened
|
|
250
|
+
`The gateway is currently running version ${input.version}. A QUEUED task whose note`,
|
|
251
|
+
'claims its change is "published, needs reload" for a version at or below this one is',
|
|
252
|
+
'stale — the reload has happened, and that is grounds to re-check its status. Do not',
|
|
253
|
+
'rewrite a note merely to say so: an edit that changes no status is not worth making.',
|
|
163
254
|
'',
|
|
164
255
|
'Task documents that exist on disk (use these for `doc` fields; do not invent paths):',
|
|
165
256
|
docs,
|
|
166
257
|
'',
|
|
167
|
-
input.
|
|
168
|
-
? '=== THE CURRENT FILE
|
|
169
|
-
:
|
|
258
|
+
input.doneWithheld
|
|
259
|
+
? '=== THE CURRENT FILE, DOWN TO THE END OF THE QUEUE (its `## Done` is withheld) ==='
|
|
260
|
+
: input.migrated
|
|
261
|
+
? '=== THE CURRENT FILE (already in this format — re-check it) ==='
|
|
262
|
+
: '=== THE CURRENT FILE (free-form — convert it) ===',
|
|
170
263
|
input.content,
|
|
171
264
|
].join('\n');
|
|
172
265
|
}
|
|
@@ -179,22 +272,62 @@ export function buildRefreshPrompt(input) {
|
|
|
179
272
|
*/
|
|
180
273
|
export async function refreshTasksFile(threadName, opts = {}) {
|
|
181
274
|
const target = await resolveRefreshTarget(threadName);
|
|
182
|
-
|
|
183
|
-
|
|
275
|
+
// Task 183: no file, or a file that is nothing but headings, is not a
|
|
276
|
+
// conversion — there are no tasks to carry across, so no model is asked and no
|
|
277
|
+
// undo point is needed. The schema is written directly, git repository or not,
|
|
278
|
+
// and the drawer works on its next open. This is the path a new thread takes.
|
|
279
|
+
if (!target.exists || isBlankTasksFile(target.content)) {
|
|
280
|
+
fs.mkdirSync(path.dirname(target.filePath), { recursive: true });
|
|
281
|
+
fs.writeFileSync(target.filePath, emptyTasksFile(path.basename(target.cwd)), 'utf-8');
|
|
282
|
+
return {
|
|
283
|
+
payload: await readTasks(threadName),
|
|
284
|
+
committed: false,
|
|
285
|
+
created: true,
|
|
286
|
+
droppedIds: [],
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
// Task 180: nothing in the queue, nothing to refresh. Refused BEFORE the
|
|
290
|
+
// snapshot and the model call, because the alternative is what happened on the
|
|
291
|
+
// first live press — a model with no legal work finding some anyway. A file
|
|
292
|
+
// that fails to parse is exempt: a queue that reads as empty because the file
|
|
293
|
+
// is broken is precisely the case Refresh exists to fix.
|
|
294
|
+
if (target.migrated) {
|
|
295
|
+
const current = parseTasksFile(target.content);
|
|
296
|
+
if (current.queue.length === 0 && current.errors.length === 0) {
|
|
297
|
+
throw new TasksRefreshError('Nothing to refresh — the queue is empty. Finished work in `## Done` is the record ' +
|
|
298
|
+
'and is left alone.');
|
|
299
|
+
}
|
|
184
300
|
}
|
|
185
301
|
const committed = snapshotBeforeRefresh(target.filePath);
|
|
302
|
+
// The record is split off rather than trusted to the prompt — see splitOffDone.
|
|
303
|
+
const split = target.migrated
|
|
304
|
+
? splitOffDone(target.content)
|
|
305
|
+
: { head: target.content, done: null };
|
|
186
306
|
const prompt = buildRefreshPrompt({
|
|
187
|
-
content: target.content,
|
|
307
|
+
content: split.done ? split.head : target.content,
|
|
188
308
|
migrated: target.migrated,
|
|
189
309
|
docs: taskDocListing(target.cwd),
|
|
190
310
|
version: getCurrentVersion(),
|
|
311
|
+
doneWithheld: split.done !== null,
|
|
191
312
|
});
|
|
192
313
|
const raw = opts.runModel
|
|
193
314
|
? await opts.runModel(prompt)
|
|
194
315
|
: await runWorker(threadName, 'tasks-refresh', prompt, opts);
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
316
|
+
const answer = unfence(raw);
|
|
317
|
+
const next = split.done ? stitchDone(answer, split.done) : answer;
|
|
318
|
+
assertUsable(answer, next, target.content);
|
|
319
|
+
fs.writeFileSync(target.filePath, next.endsWith('\n') ? next : `${next}\n`, 'utf-8');
|
|
320
|
+
return { payload: await readTasks(threadName), committed, droppedIds: [] };
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* The guard rails. Each one refuses the WHOLE answer; none patches it up, and
|
|
324
|
+
* every one throws before the single `writeFileSync` above runs, so a refusal
|
|
325
|
+
* leaves the file byte-identical to what the snapshot just committed.
|
|
326
|
+
*/
|
|
327
|
+
function assertUsable(answer, next, original) {
|
|
328
|
+
// Emptiness is judged on the ANSWER, not the stitched file: re-attaching the
|
|
329
|
+
// record to nothing would produce a plausible-looking file with no queue.
|
|
330
|
+
if (!answer) {
|
|
198
331
|
throw new TasksRefreshError('The worker returned an empty file. Nothing was written.');
|
|
199
332
|
}
|
|
200
333
|
if (!hasTasksMarker(next)) {
|
|
@@ -209,7 +342,7 @@ export async function refreshTasksFile(threadName, opts = {}) {
|
|
|
209
342
|
// The one check that catches the failure this whole task is built around: a
|
|
210
343
|
// wholesale rewrite that silently loses a row. Compared against the RAW ids of
|
|
211
344
|
// the file that went in, so it holds for un-migrated files too.
|
|
212
|
-
const before = new Set(taskIdsIn(
|
|
345
|
+
const before = new Set(taskIdsIn(original));
|
|
213
346
|
const after = new Set(parsed.queue.concat(parsed.done).map(row => row.id));
|
|
214
347
|
const droppedIds = [...before].filter(id => !after.has(id));
|
|
215
348
|
if (droppedIds.length > 0) {
|
|
@@ -218,7 +351,5 @@ export async function refreshTasksFile(threadName, opts = {}) {
|
|
|
218
351
|
if (after.size === 0 && before.size > 0) {
|
|
219
352
|
throw new TasksRefreshError('The worker returned a file with no tasks in it. Nothing was written.');
|
|
220
353
|
}
|
|
221
|
-
fs.writeFileSync(target.filePath, next.endsWith('\n') ? next : `${next}\n`, 'utf-8');
|
|
222
|
-
return { payload: await readTasks(threadName), committed, droppedIds: [] };
|
|
223
354
|
}
|
|
224
355
|
//# sourceMappingURL=tasks-refresh.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tasks-refresh.js","sourceRoot":"","sources":["../../src/gateway/tasks-refresh.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"tasks-refresh.js","sourceRoot":"","sources":["../../src/gateway/tasks-refresh.ts"],"names":[],"mappings":"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"}
|
package/dist/gateway/tasks.d.ts
CHANGED
|
@@ -2,42 +2,53 @@
|
|
|
2
2
|
* Task 176 — server side of the `/tasks` drawer.
|
|
3
3
|
*
|
|
4
4
|
* The drawer edits the SAME file the prompt projection reads, found the same
|
|
5
|
-
* way:
|
|
6
|
-
* There is deliberately no
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* way: `Tasks.md` at the root of the thread's project directory (task 183).
|
|
6
|
+
* There is deliberately no setting pointing at a tasks file — one resolution
|
|
7
|
+
* rule, so the drawer and the prompt can never disagree about which file is the
|
|
8
|
+
* queue (Rule #8).
|
|
9
|
+
*
|
|
10
|
+
* Before task 183 the file was found among the thread's always-include entries.
|
|
11
|
+
* Creating a thread scaffolds a `Tasks.md` but persists only `projectDir`, so a
|
|
12
|
+
* new thread had a tasks file that neither the prompt nor the drawer ever saw.
|
|
9
13
|
*/
|
|
10
14
|
import { TaskDisposition, TaskRow, TasksFile } from '../lib/tasks-file.js';
|
|
11
15
|
export interface ResolvedTasksFile {
|
|
12
16
|
filePath: string;
|
|
13
17
|
file: TasksFile;
|
|
14
18
|
}
|
|
19
|
+
export interface TasksLocation {
|
|
20
|
+
cwd: string;
|
|
21
|
+
filePath: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Where a thread's tasks file lives: `<projectDir>/Tasks.md`.
|
|
25
|
+
*
|
|
26
|
+
* The single place that answers the question, so the drawer, Refresh and the
|
|
27
|
+
* prompt (via `readAlwaysIncludeFiles`, which applies the same rule to the cwd
|
|
28
|
+
* it is handed) cannot resolve to different files (Rule #8).
|
|
29
|
+
*/
|
|
30
|
+
export declare function threadTasksLocation(threadName: string): Promise<TasksLocation>;
|
|
15
31
|
/**
|
|
16
|
-
*
|
|
32
|
+
* The thread's schema tasks file, or null when it has none.
|
|
17
33
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
34
|
+
* "Schema" is the marker inside the file: a `Tasks.md` that has not been
|
|
35
|
+
* migrated exists but is not yet a tasks file, and the drawer says so rather than
|
|
36
|
+
* half-parsing it.
|
|
21
37
|
*/
|
|
22
38
|
export declare function resolveTasksFile(threadName: string): Promise<ResolvedTasksFile | null>;
|
|
23
|
-
/** What task 179's Refresh is pointed at, and
|
|
39
|
+
/** What task 179's Refresh is pointed at, and what state it is in. */
|
|
24
40
|
export interface RefreshTarget {
|
|
25
41
|
filePath: string;
|
|
42
|
+
/** Empty string when the file does not exist. */
|
|
26
43
|
content: string;
|
|
27
44
|
cwd: string;
|
|
28
45
|
/** True when the file already carries the marker — Refresh re-checks rather than converts. */
|
|
29
46
|
migrated: boolean;
|
|
47
|
+
/** False when there is no file yet — Refresh then creates the empty schema. */
|
|
48
|
+
exists: boolean;
|
|
30
49
|
}
|
|
31
|
-
/**
|
|
32
|
-
|
|
33
|
-
*
|
|
34
|
-
* A superset of {@link resolveTasksFile}: a marked file wins wherever it sits,
|
|
35
|
-
* and failing that, an always-included file *named* `Tasks.md` — which is
|
|
36
|
-
* precisely the un-migrated case Refresh exists to convert. Filename is the
|
|
37
|
-
* fallback ONLY here; the prompt projection still keys on the marker alone, so
|
|
38
|
-
* conversion never happens by accident on a file nobody pointed at.
|
|
39
|
-
*/
|
|
40
|
-
export declare function resolveRefreshTarget(threadName: string): Promise<RefreshTarget | null>;
|
|
50
|
+
/** The file Refresh acts on (task 179): the same path, whatever is or is not there. */
|
|
51
|
+
export declare function resolveRefreshTarget(threadName: string): Promise<RefreshTarget>;
|
|
41
52
|
/** Wire shape for the drawer — flat rows, depth carried explicitly. */
|
|
42
53
|
export interface TasksPayload {
|
|
43
54
|
filePath: string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/gateway/tasks.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/gateway/tasks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAOH,OAAO,EAEL,eAAe,EACf,OAAO,EACP,SAAS,EASV,MAAM,sBAAsB,CAAC;AAG9B,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAKpF;AAYD;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAK5F;AAED,sEAAsE;AACtE,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,8FAA8F;IAC9F,QAAQ,EAAE,OAAO,CAAC;IAClB,+EAA+E;IAC/E,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,uFAAuF;AACvF,wBAAsB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAKrF;AAED,uEAAuE;AACvE,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,MAAM,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC5B,mEAAmE;IACnE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAsB,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAWzE;AAkDD,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,QAAQ,GAAG,OAAO,GAC3B,OAAO,CAAC,YAAY,CAAC,CAEvB;AAED,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,OAAO,GACd,OAAO,CAAC,YAAY,CAAC,CAEvB;AAED,0DAA0D;AAC1D,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,MAAM,EAAE,EACb,WAAW,EAAE,eAAe,GAC3B,OAAO,CAAC,YAAY,CAAC,CAEvB"}
|
package/dist/gateway/tasks.js
CHANGED
|
@@ -2,79 +2,66 @@
|
|
|
2
2
|
* Task 176 — server side of the `/tasks` drawer.
|
|
3
3
|
*
|
|
4
4
|
* The drawer edits the SAME file the prompt projection reads, found the same
|
|
5
|
-
* way:
|
|
6
|
-
* There is deliberately no
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* way: `Tasks.md` at the root of the thread's project directory (task 183).
|
|
6
|
+
* There is deliberately no setting pointing at a tasks file — one resolution
|
|
7
|
+
* rule, so the drawer and the prompt can never disagree about which file is the
|
|
8
|
+
* queue (Rule #8).
|
|
9
|
+
*
|
|
10
|
+
* Before task 183 the file was found among the thread's always-include entries.
|
|
11
|
+
* Creating a thread scaffolds a `Tasks.md` but persists only `projectDir`, so a
|
|
12
|
+
* new thread had a tasks file that neither the prompt nor the drawer ever saw.
|
|
9
13
|
*/
|
|
10
14
|
import * as fs from 'fs';
|
|
11
15
|
import * as os from 'os';
|
|
12
16
|
import * as path from 'path';
|
|
13
|
-
import { loadGlobalConfig, loadThreadConfig, mergeConfigs
|
|
14
|
-
import { TasksFileError, assertWritable, dispositionTasks, hasTasksMarker, moveTask, parseTasksFile, resolveProposedDep, serializeTasksFile, } from '../lib/tasks-file.js';
|
|
17
|
+
import { loadGlobalConfig, loadThreadConfig, mergeConfigs } from '../lib/config.js';
|
|
18
|
+
import { TASKS_FILE_NAME, TasksFileError, assertWritable, dispositionTasks, hasTasksMarker, moveTask, parseTasksFile, resolveProposedDep, serializeTasksFile, } from '../lib/tasks-file.js';
|
|
15
19
|
import { resolveThreadCwd } from '../lib/worktree.js';
|
|
16
20
|
/**
|
|
17
|
-
*
|
|
21
|
+
* Where a thread's tasks file lives: `<projectDir>/Tasks.md`.
|
|
18
22
|
*
|
|
19
|
-
* The single place that answers
|
|
20
|
-
*
|
|
21
|
-
* different
|
|
23
|
+
* The single place that answers the question, so the drawer, Refresh and the
|
|
24
|
+
* prompt (via `readAlwaysIncludeFiles`, which applies the same rule to the cwd
|
|
25
|
+
* it is handed) cannot resolve to different files (Rule #8).
|
|
22
26
|
*/
|
|
23
|
-
async function
|
|
27
|
+
export async function threadTasksLocation(threadName) {
|
|
24
28
|
const merged = mergeConfigs(await loadGlobalConfig(), await loadThreadConfig(threadName));
|
|
25
29
|
const resolved = await resolveThreadCwd(threadName, merged.projectDir);
|
|
26
30
|
const cwd = resolved.cwd || merged.projectDir || path.join(os.homedir(), 'projects', threadName);
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
31
|
+
return { cwd, filePath: path.join(cwd, TASKS_FILE_NAME) };
|
|
32
|
+
}
|
|
33
|
+
/** The file's contents, or null when there is no regular file there. */
|
|
34
|
+
function readIfFile(filePath) {
|
|
35
|
+
try {
|
|
36
|
+
if (!fs.existsSync(filePath) || fs.statSync(filePath).isDirectory())
|
|
37
|
+
return null;
|
|
38
|
+
return fs.readFileSync(filePath, 'utf-8');
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return null;
|
|
38
42
|
}
|
|
39
|
-
return { cwd, files };
|
|
40
43
|
}
|
|
41
44
|
/**
|
|
42
|
-
*
|
|
45
|
+
* The thread's schema tasks file, or null when it has none.
|
|
43
46
|
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
+
* "Schema" is the marker inside the file: a `Tasks.md` that has not been
|
|
48
|
+
* migrated exists but is not yet a tasks file, and the drawer says so rather than
|
|
49
|
+
* half-parsing it.
|
|
47
50
|
*/
|
|
48
51
|
export async function resolveTasksFile(threadName) {
|
|
49
|
-
const {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
return null;
|
|
52
|
+
const { filePath } = await threadTasksLocation(threadName);
|
|
53
|
+
const content = readIfFile(filePath);
|
|
54
|
+
if (content === null || !hasTasksMarker(content))
|
|
55
|
+
return null;
|
|
56
|
+
return { filePath, file: parseTasksFile(content) };
|
|
56
57
|
}
|
|
57
|
-
/**
|
|
58
|
-
* The file Refresh acts on (task 179).
|
|
59
|
-
*
|
|
60
|
-
* A superset of {@link resolveTasksFile}: a marked file wins wherever it sits,
|
|
61
|
-
* and failing that, an always-included file *named* `Tasks.md` — which is
|
|
62
|
-
* precisely the un-migrated case Refresh exists to convert. Filename is the
|
|
63
|
-
* fallback ONLY here; the prompt projection still keys on the marker alone, so
|
|
64
|
-
* conversion never happens by accident on a file nobody pointed at.
|
|
65
|
-
*/
|
|
58
|
+
/** The file Refresh acts on (task 179): the same path, whatever is or is not there. */
|
|
66
59
|
export async function resolveRefreshTarget(threadName) {
|
|
67
|
-
const { cwd,
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
for (const { filePath, content } of files) {
|
|
73
|
-
if (path.basename(filePath).toLowerCase() === 'tasks.md') {
|
|
74
|
-
return { filePath, content, cwd, migrated: false };
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
return null;
|
|
60
|
+
const { cwd, filePath } = await threadTasksLocation(threadName);
|
|
61
|
+
const content = readIfFile(filePath);
|
|
62
|
+
if (content === null)
|
|
63
|
+
return { filePath, content: '', cwd, migrated: false, exists: false };
|
|
64
|
+
return { filePath, content, cwd, migrated: hasTasksMarker(content), exists: true };
|
|
78
65
|
}
|
|
79
66
|
export async function readTasks(threadName) {
|
|
80
67
|
const resolved = await resolveTasksFile(threadName);
|
|
@@ -98,7 +85,7 @@ export async function readTasks(threadName) {
|
|
|
98
85
|
async function mutateFile(threadName, mutate) {
|
|
99
86
|
const resolved = await resolveTasksFile(threadName);
|
|
100
87
|
if (!resolved) {
|
|
101
|
-
throw new TasksFileError(
|
|
88
|
+
throw new TasksFileError(`This thread's project has no ${TASKS_FILE_NAME} in the current format — press Refresh first`);
|
|
102
89
|
}
|
|
103
90
|
assertWritable(resolved.file);
|
|
104
91
|
const next = mutate(resolved.file);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/gateway/tasks.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/gateway/tasks.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -179,6 +179,17 @@ export declare function mergeConfigs(global: CumulusConfig, thread: CumulusConfi
|
|
|
179
179
|
* @param cwd - Current working directory for relative paths
|
|
180
180
|
*/
|
|
181
181
|
export declare function resolveFilePath(filePath: string, cwd: string): string;
|
|
182
|
+
/**
|
|
183
|
+
* The files a turn always carries, in send order.
|
|
184
|
+
*
|
|
185
|
+
* Task 183: the project's own `Tasks.md` is always sent, with no configuration.
|
|
186
|
+
* It is the file the /tasks drawer edits, found by the same rule (gateway/tasks.ts),
|
|
187
|
+
* and the projection in `readAlwaysIncludeFiles` keeps a migrated one small. A
|
|
188
|
+
* configured entry that resolves to the same file is dropped rather than sent
|
|
189
|
+
* twice. The one opt-out is `alwaysIncludeExcludes`, the existing way to keep a
|
|
190
|
+
* file out of a thread's prompt.
|
|
191
|
+
*/
|
|
192
|
+
export declare function alwaysIncludePaths(config: CumulusConfig, cwd: string): string[];
|
|
182
193
|
/**
|
|
183
194
|
* Read and format all always-include files from config.
|
|
184
195
|
* @param config - Merged configuration
|
package/dist/lib/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/config.js
CHANGED
|
@@ -8,7 +8,7 @@ import * as fs from 'fs';
|
|
|
8
8
|
import * as os from 'os';
|
|
9
9
|
import * as path from 'path';
|
|
10
10
|
import { estimateTokens } from './context-budget.js';
|
|
11
|
-
import { projectTasksFile } from './tasks-file.js';
|
|
11
|
+
import { TASKS_FILE_NAME, projectTasksFile } from './tasks-file.js';
|
|
12
12
|
// Mutable so tests can redirect both the global config and the threads dir to
|
|
13
13
|
// a sandbox without polluting ~/.cumulus. The gateway sets these once on boot;
|
|
14
14
|
// production callers never invoke the setters.
|
|
@@ -340,6 +340,36 @@ export function resolveFilePath(filePath, cwd) {
|
|
|
340
340
|
// Relative path - resolve from cwd
|
|
341
341
|
return path.resolve(cwd, filePath);
|
|
342
342
|
}
|
|
343
|
+
/**
|
|
344
|
+
* The files a turn always carries, in send order.
|
|
345
|
+
*
|
|
346
|
+
* Task 183: the project's own `Tasks.md` is always sent, with no configuration.
|
|
347
|
+
* It is the file the /tasks drawer edits, found by the same rule (gateway/tasks.ts),
|
|
348
|
+
* and the projection in `readAlwaysIncludeFiles` keeps a migrated one small. A
|
|
349
|
+
* configured entry that resolves to the same file is dropped rather than sent
|
|
350
|
+
* twice. The one opt-out is `alwaysIncludeExcludes`, the existing way to keep a
|
|
351
|
+
* file out of a thread's prompt.
|
|
352
|
+
*/
|
|
353
|
+
export function alwaysIncludePaths(config, cwd) {
|
|
354
|
+
const tasksPath = cwd ? path.resolve(cwd, TASKS_FILE_NAME) : null;
|
|
355
|
+
const excluded = (config.alwaysIncludeExcludes ?? []).map(entry => resolveFilePath(entry, cwd));
|
|
356
|
+
let tasksImplied = false;
|
|
357
|
+
if (tasksPath && !excluded.includes(tasksPath)) {
|
|
358
|
+
try {
|
|
359
|
+
tasksImplied = fs.statSync(tasksPath).isFile();
|
|
360
|
+
}
|
|
361
|
+
catch {
|
|
362
|
+
tasksImplied = false;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
const paths = tasksImplied ? [TASKS_FILE_NAME] : [];
|
|
366
|
+
for (const entry of config.alwaysInclude ?? []) {
|
|
367
|
+
if (tasksImplied && resolveFilePath(entry, cwd) === tasksPath)
|
|
368
|
+
continue;
|
|
369
|
+
paths.push(entry);
|
|
370
|
+
}
|
|
371
|
+
return paths;
|
|
372
|
+
}
|
|
343
373
|
/**
|
|
344
374
|
* Read and format all always-include files from config.
|
|
345
375
|
* @param config - Merged configuration
|
|
@@ -348,8 +378,7 @@ export function resolveFilePath(filePath, cwd) {
|
|
|
348
378
|
export async function readAlwaysIncludeFiles(config, cwd) {
|
|
349
379
|
const files = [];
|
|
350
380
|
let totalTokens = 0;
|
|
351
|
-
const
|
|
352
|
-
for (const filePath of paths) {
|
|
381
|
+
for (const filePath of alwaysIncludePaths(config, cwd)) {
|
|
353
382
|
const resolvedPath = resolveFilePath(filePath, cwd);
|
|
354
383
|
const fileInfo = {
|
|
355
384
|
path: filePath,
|