@luckydraw/cumulus 1.0.36 → 1.0.37

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.
@@ -1898,6 +1898,94 @@
1898
1898
  ' font-size: 0.8em; white-space: nowrap;',
1899
1899
  '}',
1900
1900
  '.cumulus-scope-toggle:hover { border-color: #555; color: #ddd; }',
1901
+
1902
+ /* ── Tasks drawer (task 176) — slides over the chat from the right ── */
1903
+ '.cumulus-tasks-drawer {',
1904
+ ' position: absolute; top: 0; right: 0; bottom: 0; width: 400px; max-width: 100%;',
1905
+ ' background: #1e1e1e; border-left: 1px solid #3a3a3a; z-index: 11;',
1906
+ ' display: flex; flex-direction: column; overflow: hidden;',
1907
+ ' box-shadow: -10px 0 28px rgba(0, 0, 0, 0.45);',
1908
+ '}',
1909
+ '.cumulus-tasks-header {',
1910
+ ' display: flex; align-items: center; gap: 8px;',
1911
+ ' padding: 0 0.6em 0 0.85em; height: 40px; flex-shrink: 0;',
1912
+ ' background: #2d2d2d; border-bottom: 1px solid #3a3a3a;',
1913
+ '}',
1914
+ '.cumulus-tasks-title { font-weight: 600; font-size: 13px; color: #e0e0e0; letter-spacing: 0.06em; }',
1915
+ '.cumulus-tasks-count { font-size: 11px; color: #888; margin-left: auto; }',
1916
+ '.cumulus-tasks-close {',
1917
+ ' background: none; border: none; color: #666; cursor: pointer;',
1918
+ ' font-size: 18px; padding: 2px 4px; line-height: 1;',
1919
+ '}',
1920
+ '.cumulus-tasks-close:hover { color: #e0e0e0; }',
1921
+ '.cumulus-tasks-body { flex: 1; overflow-y: auto; padding: 0.5em 0.4em; }',
1922
+ '.cumulus-tasks-empty { color: #777; font-size: 12px; padding: 1.2em 0.8em; line-height: 1.5; }',
1923
+ '.cumulus-tasks-error {',
1924
+ ' background: #3a2222; border-bottom: 1px solid #5a2a2a; color: #f3b3b3;',
1925
+ ' font-size: 11.5px; padding: 0.5em 0.85em; line-height: 1.45; flex-shrink: 0;',
1926
+ '}',
1927
+ '.cumulus-tasks-section {',
1928
+ ' font-size: 10.5px; color: #777; letter-spacing: 0.08em; text-transform: uppercase;',
1929
+ ' padding: 1em 0.5em 0.4em; border-top: 1px solid #2a2a2a; margin-top: 0.6em;',
1930
+ '}',
1931
+
1932
+ /* Rows */
1933
+ '.cumulus-task-row {',
1934
+ ' display: flex; align-items: flex-start; gap: 6px;',
1935
+ ' padding: 4px 6px; border-radius: 4px; border: 1px solid transparent;',
1936
+ ' font-size: 12px; line-height: 1.35; color: #ccc;',
1937
+ '}',
1938
+ '.cumulus-task-row:hover { background: #262626; border-color: #333; }',
1939
+ '.cumulus-task-row--now { background: #1d2a1d; border-color: #2f4a2f; }',
1940
+ '.cumulus-task-row--dragging { opacity: 0.4; }',
1941
+ '.cumulus-task-row--drop-before { border-top-color: #4da6ff; }',
1942
+ '.cumulus-task-row--drop-after { border-bottom-color: #4da6ff; }',
1943
+ '.cumulus-task-row--done { opacity: 0.55; }',
1944
+ '.cumulus-task-grip {',
1945
+ ' cursor: grab; color: #555; font-size: 12px; user-select: none;',
1946
+ ' padding: 0 1px; flex-shrink: 0; line-height: 1.35;',
1947
+ '}',
1948
+ '.cumulus-task-grip:active { cursor: grabbing; }',
1949
+ '.cumulus-task-row--done .cumulus-task-grip { visibility: hidden; cursor: default; }',
1950
+ '.cumulus-task-check { margin: 2px 0 0 0; flex-shrink: 0; accent-color: #4da6ff; }',
1951
+ '.cumulus-task-branch { color: #555; flex-shrink: 0; }',
1952
+ '.cumulus-task-status { flex-shrink: 0; width: 1.1em; text-align: center; color: #888; }',
1953
+ '.cumulus-task-id {',
1954
+ ' font-family: "SF Mono", Consolas, monospace; font-size: 11px;',
1955
+ ' color: #7a9a7a; flex-shrink: 0;',
1956
+ '}',
1957
+ '.cumulus-task-title { flex: 1; min-width: 0; }',
1958
+ '.cumulus-task-phase {',
1959
+ ' font-size: 9.5px; color: #777; background: #262626; border: 1px solid #333;',
1960
+ ' border-radius: 3px; padding: 0 4px; flex-shrink: 0; align-self: center;',
1961
+ '}',
1962
+ '.cumulus-task-now {',
1963
+ ' font-size: 9.5px; color: #8fbf8f; border: 1px solid #3f5f3f; border-radius: 3px;',
1964
+ ' padding: 0 4px; flex-shrink: 0; align-self: center; letter-spacing: 0.06em;',
1965
+ '}',
1966
+
1967
+ /* Proposed dependency — the only thing in the drawer that asks a question */
1968
+ '.cumulus-task-dep {',
1969
+ ' display: flex; align-items: center; gap: 4px; flex-shrink: 0;',
1970
+ ' font-size: 10px; color: #d9a441;',
1971
+ '}',
1972
+ '.cumulus-task-dep button {',
1973
+ ' background: #2a2a2a; border: 1px solid #444; color: #bbb; cursor: pointer;',
1974
+ ' border-radius: 3px; font-size: 10px; line-height: 1; padding: 2px 5px;',
1975
+ '}',
1976
+ '.cumulus-task-dep button:hover { border-color: #666; color: #eee; }',
1977
+
1978
+ /* Selection bar — same shape as the message selection bar */
1979
+ '.cumulus-tasks-selbar {',
1980
+ ' display: flex; align-items: center; gap: 8px; flex-shrink: 0;',
1981
+ ' padding: 0.5em 0.85em; background: #2d2d2d; border-top: 1px solid #3a3a3a;',
1982
+ '}',
1983
+ '.cumulus-tasks-selcount { font-size: 11.5px; color: #aaa; }',
1984
+ '.cumulus-tasks-comment-btn {',
1985
+ ' margin-left: auto; background: #2f4a35; border: 1px solid #3f5f45; color: #ddd;',
1986
+ ' border-radius: 4px; padding: 0.3em 0.8em; cursor: pointer; font-size: 11.5px;',
1987
+ '}',
1988
+ '.cumulus-tasks-comment-btn:disabled { background: #2a2a2a; border-color: #333; color: #666; cursor: not-allowed; }',
1901
1989
  '.cumulus-include-add-btn {',
1902
1990
  ' background: #0066cc; border: none; color: white;',
1903
1991
  ' padding: 0.4em 0.8em; border-radius: 4px; cursor: pointer;',
@@ -2066,6 +2154,9 @@
2066
2154
  ' .cumulus-include-add-row { flex-wrap: wrap; }',
2067
2155
  ' .cumulus-include-add-input { min-width: 0; }',
2068
2156
 
2157
+ /* Tasks drawer takes the whole panel on a phone (task 176) */
2158
+ ' .cumulus-tasks-drawer { width: 100%; }',
2159
+
2069
2160
  /* Topbar: tighter on mobile */
2070
2161
  ' .cumulus-topbar { padding: 0 10px; }',
2071
2162
  ' .cumulus-topbar-title { font-size: 14px; }',
@@ -7840,6 +7931,16 @@
7840
7931
  });
7841
7932
  actions.appendChild(includeBtn);
7842
7933
 
7934
+ var tasksBtn = document.createElement('button');
7935
+ tasksBtn.className = 'cumulus-panel-action-btn';
7936
+ tasksBtn.setAttribute('data-testid', 'webchat-tasks-btn');
7937
+ tasksBtn.setAttribute('title', 'Task queue — drag to reorder');
7938
+ tasksBtn.textContent = '/tasks';
7939
+ tasksBtn.addEventListener('click', function () {
7940
+ openTasksDrawer(panel, threadName);
7941
+ });
7942
+ actions.appendChild(tasksBtn);
7943
+
7843
7944
  var revertBtn = document.createElement('button');
7844
7945
  revertBtn.className = 'cumulus-panel-action-btn';
7845
7946
  revertBtn.setAttribute('data-testid', 'webchat-revert-btn');
@@ -9074,6 +9175,351 @@
9074
9175
  }
9075
9176
 
9076
9177
  // ── Include overlay ──
9178
+ // ── Tasks drawer (task 176) ────────────────────────────────────────────
9179
+ //
9180
+ // Every drag is a write to Tasks.md, and the server answers with the file's
9181
+ // new truth — the DOM is never the source of record. An illegal drop comes
9182
+ // back as the UNCHANGED list plus a reason, which is why nothing here tries
9183
+ // to predict whether a move is legal: one rule, enforced in one place.
9184
+
9185
+ function openTasksDrawer(panel, threadName) {
9186
+ var existing = panel.querySelector('.cumulus-tasks-drawer');
9187
+ if (existing) {
9188
+ existing.remove();
9189
+ return;
9190
+ }
9191
+
9192
+ var drawer = document.createElement('div');
9193
+ drawer.className = 'cumulus-tasks-drawer';
9194
+ drawer.setAttribute('data-testid', 'webchat-tasks-drawer');
9195
+ drawer._threadName = threadName;
9196
+ drawer._selected = {};
9197
+
9198
+ var header = document.createElement('div');
9199
+ header.className = 'cumulus-tasks-header';
9200
+ var title = document.createElement('span');
9201
+ title.className = 'cumulus-tasks-title';
9202
+ title.textContent = 'TASKS';
9203
+ header.appendChild(title);
9204
+ var count = document.createElement('span');
9205
+ count.className = 'cumulus-tasks-count';
9206
+ count.setAttribute('data-testid', 'webchat-tasks-count');
9207
+ header.appendChild(count);
9208
+ var closeBtn = document.createElement('button');
9209
+ closeBtn.className = 'cumulus-tasks-close';
9210
+ closeBtn.setAttribute('data-testid', 'webchat-tasks-close');
9211
+ closeBtn.textContent = '\xD7';
9212
+ closeBtn.addEventListener('click', function () {
9213
+ drawer.remove();
9214
+ });
9215
+ header.appendChild(closeBtn);
9216
+ drawer.appendChild(header);
9217
+
9218
+ var errorEl = document.createElement('div');
9219
+ errorEl.className = 'cumulus-tasks-error';
9220
+ errorEl.setAttribute('data-testid', 'webchat-tasks-error');
9221
+ errorEl.style.display = 'none';
9222
+ drawer.appendChild(errorEl);
9223
+
9224
+ var body = document.createElement('div');
9225
+ body.className = 'cumulus-tasks-body';
9226
+ body.innerHTML = '<div class="cumulus-tasks-empty">Loading…</div>';
9227
+ drawer.appendChild(body);
9228
+
9229
+ var selbar = document.createElement('div');
9230
+ selbar.className = 'cumulus-tasks-selbar';
9231
+ var selcount = document.createElement('span');
9232
+ selcount.className = 'cumulus-tasks-selcount';
9233
+ selcount.setAttribute('data-testid', 'webchat-tasks-selcount');
9234
+ selcount.textContent = '0 selected';
9235
+ selbar.appendChild(selcount);
9236
+ var commentBtn = document.createElement('button');
9237
+ commentBtn.className = 'cumulus-tasks-comment-btn';
9238
+ commentBtn.setAttribute('data-testid', 'webchat-tasks-comment-btn');
9239
+ commentBtn.textContent = 'Comment';
9240
+ commentBtn.disabled = true;
9241
+ commentBtn.addEventListener('click', function () {
9242
+ var labels = drawer._selectedLabels ? drawer._selectedLabels() : [];
9243
+ if (labels.length === 0) return;
9244
+ // The same popover the chat uses for a highlighted quote — the selected
9245
+ // rows ARE the quote, so the chip that lands in the composer is
9246
+ // indistinguishable from one made by highlighting text.
9247
+ showAnnotationPopover(
9248
+ panel,
9249
+ labels.join('\n'),
9250
+ commentBtn.getBoundingClientRect(),
9251
+ false,
9252
+ ''
9253
+ );
9254
+ });
9255
+ selbar.appendChild(commentBtn);
9256
+ drawer.appendChild(selbar);
9257
+
9258
+ drawer._body = body;
9259
+ drawer._errorEl = errorEl;
9260
+ drawer._countEl = count;
9261
+ drawer._selcount = selcount;
9262
+ drawer._commentBtn = commentBtn;
9263
+
9264
+ panel.appendChild(drawer);
9265
+ if (connection) connection.send({ type: 'tasks_list', threadName: threadName });
9266
+ }
9267
+
9268
+ function clearTaskDropMarkers(drawer) {
9269
+ var marked = drawer.querySelectorAll(
9270
+ '.cumulus-task-row--drop-before, .cumulus-task-row--drop-after'
9271
+ );
9272
+ for (var i = 0; i < marked.length; i++) {
9273
+ marked[i].classList.remove('cumulus-task-row--drop-before');
9274
+ marked[i].classList.remove('cumulus-task-row--drop-after');
9275
+ }
9276
+ }
9277
+
9278
+ function wireTaskDrag(row, drawer, threadName) {
9279
+ row.setAttribute('draggable', 'true');
9280
+
9281
+ row.addEventListener('dragstart', function (e) {
9282
+ drawer._dragId = row.getAttribute('data-task-id');
9283
+ row.classList.add('cumulus-task-row--dragging');
9284
+ if (e.dataTransfer) {
9285
+ e.dataTransfer.effectAllowed = 'move';
9286
+ try {
9287
+ e.dataTransfer.setData('text/plain', drawer._dragId);
9288
+ } catch {
9289
+ /* Safari refuses setData outside a user gesture — the drag still works */
9290
+ }
9291
+ }
9292
+ });
9293
+
9294
+ row.addEventListener('dragend', function () {
9295
+ row.classList.remove('cumulus-task-row--dragging');
9296
+ clearTaskDropMarkers(drawer);
9297
+ drawer._dragId = null;
9298
+ });
9299
+
9300
+ row.addEventListener('dragover', function (e) {
9301
+ if (!drawer._dragId || drawer._dragId === row.getAttribute('data-task-id')) return;
9302
+ e.preventDefault();
9303
+ if (e.dataTransfer) e.dataTransfer.dropEffect = 'move';
9304
+ var rect = row.getBoundingClientRect();
9305
+ var before = e.clientY - rect.top < rect.height / 2;
9306
+ clearTaskDropMarkers(drawer);
9307
+ row.classList.add(
9308
+ before ? 'cumulus-task-row--drop-before' : 'cumulus-task-row--drop-after'
9309
+ );
9310
+ drawer._dropPosition = before ? 'before' : 'after';
9311
+ });
9312
+
9313
+ row.addEventListener('drop', function (e) {
9314
+ e.preventDefault();
9315
+ var dragId = drawer._dragId;
9316
+ var targetId = row.getAttribute('data-task-id');
9317
+ clearTaskDropMarkers(drawer);
9318
+ drawer._dragId = null;
9319
+ if (!dragId || dragId === targetId) return;
9320
+ if (connection)
9321
+ connection.send({
9322
+ type: 'tasks_move',
9323
+ threadName: threadName,
9324
+ dragId: dragId,
9325
+ targetId: targetId,
9326
+ position: drawer._dropPosition === 'after' ? 'after' : 'before',
9327
+ });
9328
+ });
9329
+ }
9330
+
9331
+ function buildTaskRow(task, opts) {
9332
+ var row = document.createElement('div');
9333
+ row.className = 'cumulus-task-row';
9334
+ if (opts.done) row.classList.add('cumulus-task-row--done');
9335
+ if (opts.isNow) row.classList.add('cumulus-task-row--now');
9336
+ row.setAttribute('data-task-id', task.id);
9337
+ row.setAttribute('data-task-depth', String(task.depth || 0));
9338
+ row.setAttribute('data-testid', 'webchat-task-row-' + cssEscape(task.id));
9339
+ row.style.marginLeft = (task.depth || 0) * 16 + 'px';
9340
+
9341
+ var grip = document.createElement('span');
9342
+ grip.className = 'cumulus-task-grip';
9343
+ grip.textContent = '⠿';
9344
+ row.appendChild(grip);
9345
+
9346
+ var check = document.createElement('input');
9347
+ check.type = 'checkbox';
9348
+ check.className = 'cumulus-task-check';
9349
+ check.setAttribute('data-testid', 'webchat-task-check-' + cssEscape(task.id));
9350
+ row.appendChild(check);
9351
+
9352
+ if (task.depth > 0) {
9353
+ var branch = document.createElement('span');
9354
+ branch.className = 'cumulus-task-branch';
9355
+ branch.textContent = '└';
9356
+ row.appendChild(branch);
9357
+ }
9358
+
9359
+ var status = document.createElement('span');
9360
+ status.className = 'cumulus-task-status';
9361
+ status.textContent = (task.status || ' ').trim() || '○';
9362
+ row.appendChild(status);
9363
+
9364
+ var id = document.createElement('span');
9365
+ id.className = 'cumulus-task-id';
9366
+ id.textContent = task.id;
9367
+ row.appendChild(id);
9368
+
9369
+ var title = document.createElement('span');
9370
+ title.className = 'cumulus-task-title';
9371
+ title.textContent = task.title;
9372
+ row.appendChild(title);
9373
+
9374
+ if (task.phase) {
9375
+ var phase = document.createElement('span');
9376
+ phase.className = 'cumulus-task-phase';
9377
+ phase.textContent = task.phase;
9378
+ row.appendChild(phase);
9379
+ }
9380
+
9381
+ if (opts.isNow) {
9382
+ var now = document.createElement('span');
9383
+ now.className = 'cumulus-task-now';
9384
+ now.textContent = 'NOW';
9385
+ row.appendChild(now);
9386
+ }
9387
+
9388
+ return { row: row, check: check };
9389
+ }
9390
+
9391
+ function renderTasks(panel, threadName, data) {
9392
+ var drawer = panel.querySelector('.cumulus-tasks-drawer');
9393
+ if (!drawer || drawer._threadName !== threadName) return;
9394
+
9395
+ var body = drawer._body;
9396
+ var errorEl = drawer._errorEl;
9397
+
9398
+ if (data.error) {
9399
+ errorEl.textContent = data.error;
9400
+ errorEl.style.display = '';
9401
+ } else {
9402
+ errorEl.textContent = '';
9403
+ errorEl.style.display = 'none';
9404
+ }
9405
+
9406
+ var queue = data.queue || [];
9407
+ var done = data.done || [];
9408
+ drawer._countEl.textContent = data.missing ? '' : queue.length + ' open';
9409
+
9410
+ body.innerHTML = '';
9411
+
9412
+ if (data.missing) {
9413
+ body.innerHTML =
9414
+ '<div class="cumulus-tasks-empty">This thread has no tasks file.<br><br>' +
9415
+ 'Add a <code>Tasks.md</code> carrying the <code>cumulus:tasks</code> marker to the ' +
9416
+ 'thread’s always-include list, and it will appear here.</div>';
9417
+ drawer._selected = {};
9418
+ updateTaskSelection(drawer);
9419
+ return;
9420
+ }
9421
+
9422
+ // Parse errors are shown as rows of their own — a line the parser could not
9423
+ // read is the one thing you most need to see, and while any exist the
9424
+ // server refuses every write.
9425
+ (data.errors || []).forEach(function (err) {
9426
+ var e = document.createElement('div');
9427
+ e.className = 'cumulus-tasks-error';
9428
+ e.setAttribute('data-testid', 'webchat-task-parse-error');
9429
+ e.textContent = 'line ' + err.line + ': ' + err.reason;
9430
+ body.appendChild(e);
9431
+ });
9432
+
9433
+ queue.forEach(function (task, i) {
9434
+ var built = buildTaskRow(task, { isNow: i === 0, done: false });
9435
+ wireTaskDrag(built.row, drawer, threadName);
9436
+ wireTaskCheck(built, drawer);
9437
+
9438
+ if (task.depProposed) {
9439
+ var dep = document.createElement('span');
9440
+ dep.className = 'cumulus-task-dep';
9441
+ var label = document.createElement('span');
9442
+ label.textContent = 'blocked?';
9443
+ label.title = 'This dependency was proposed during migration, not confirmed.';
9444
+ dep.appendChild(label);
9445
+ dep.appendChild(depButton('✓', 'accept', task.id, threadName));
9446
+ dep.appendChild(depButton('✗', 'reject', task.id, threadName));
9447
+ built.row.appendChild(dep);
9448
+ }
9449
+
9450
+ body.appendChild(built.row);
9451
+ });
9452
+
9453
+ if (done.length > 0) {
9454
+ var sect = document.createElement('div');
9455
+ sect.className = 'cumulus-tasks-section';
9456
+ sect.textContent = 'Done · ' + done.length;
9457
+ body.appendChild(sect);
9458
+
9459
+ done.forEach(function (task) {
9460
+ var built = buildTaskRow(task, { isNow: false, done: true });
9461
+ wireTaskCheck(built, drawer);
9462
+ body.appendChild(built.row);
9463
+ });
9464
+ }
9465
+
9466
+ // A row that vanished from the file (moved, or its id changed) must not
9467
+ // keep a ghost selection alive.
9468
+ var live = {};
9469
+ queue.concat(done).forEach(function (t) {
9470
+ live[t.id] = t;
9471
+ });
9472
+ Object.keys(drawer._selected).forEach(function (id) {
9473
+ if (!live[id]) delete drawer._selected[id];
9474
+ });
9475
+ drawer._selectedLabels = function () {
9476
+ return Object.keys(drawer._selected).map(function (id) {
9477
+ return live[id] ? live[id].id + ' · ' + live[id].title : id;
9478
+ });
9479
+ };
9480
+ Object.keys(drawer._selected).forEach(function (id) {
9481
+ var box = body.querySelector('[data-testid="webchat-task-check-' + cssEscape(id) + '"]');
9482
+ if (box) box.checked = true;
9483
+ });
9484
+ updateTaskSelection(drawer);
9485
+ }
9486
+
9487
+ function depButton(glyph, action, taskId, threadName) {
9488
+ var btn = document.createElement('button');
9489
+ btn.textContent = glyph;
9490
+ btn.setAttribute('data-testid', 'webchat-task-dep-' + action + '-' + cssEscape(taskId));
9491
+ btn.setAttribute(
9492
+ 'title',
9493
+ action === 'accept' ? 'Keep this dependency' : 'Not blocked — move it out'
9494
+ );
9495
+ btn.addEventListener('click', function (e) {
9496
+ e.stopPropagation();
9497
+ if (connection)
9498
+ connection.send({
9499
+ type: 'tasks_dep',
9500
+ threadName: threadName,
9501
+ id: taskId,
9502
+ accept: action === 'accept',
9503
+ });
9504
+ });
9505
+ return btn;
9506
+ }
9507
+
9508
+ function wireTaskCheck(built, drawer) {
9509
+ built.check.addEventListener('change', function () {
9510
+ var id = built.row.getAttribute('data-task-id');
9511
+ if (built.check.checked) drawer._selected[id] = true;
9512
+ else delete drawer._selected[id];
9513
+ updateTaskSelection(drawer);
9514
+ });
9515
+ }
9516
+
9517
+ function updateTaskSelection(drawer) {
9518
+ var n = Object.keys(drawer._selected).length;
9519
+ drawer._selcount.textContent = n + ' selected';
9520
+ drawer._commentBtn.disabled = n === 0;
9521
+ }
9522
+
9077
9523
  function openIncludeOverlay(panel, threadName) {
9078
9524
  // Remove existing overlay if any
9079
9525
  var existing = panel.querySelector('.cumulus-overlay');
@@ -10195,6 +10641,18 @@
10195
10641
  }
10196
10642
  break;
10197
10643
 
10644
+ // Tasks drawer (task 176). One response type for reads, writes and
10645
+ // rejected writes — a rejection carries the unchanged list plus a
10646
+ // reason, so the drawer always re-renders from the file's truth.
10647
+ case 'tasks_data':
10648
+ if (data.threadName) {
10649
+ var tasksPanel = document.querySelector(
10650
+ '[data-thread-panel="' + data.threadName + '"]'
10651
+ );
10652
+ if (tasksPanel) renderTasks(tasksPanel, data.threadName, data);
10653
+ }
10654
+ break;
10655
+
10198
10656
  case 'include_added':
10199
10657
  case 'include_removed':
10200
10658
  // List already updated by the handler — no extra action needed
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Task 176 — server side of the `/tasks` drawer.
3
+ *
4
+ * The drawer edits the SAME file the prompt projection reads, found the same
5
+ * way: whichever of the thread's always-include files carries the schema marker.
6
+ * There is deliberately no second setting pointing at a tasks file — one
7
+ * resolution rule, so the drawer and the prompt can never disagree about which
8
+ * file is the queue (Rule #8).
9
+ */
10
+ import { TaskRow, TasksFile } from '../lib/tasks-file.js';
11
+ export interface ResolvedTasksFile {
12
+ filePath: string;
13
+ file: TasksFile;
14
+ }
15
+ /**
16
+ * Find the thread's schema tasks file, or null when it has none.
17
+ *
18
+ * Detection is the marker inside the file, never the filename: a project whose
19
+ * `Tasks.md` has not been migrated is not a tasks file, and a migrated file
20
+ * under any other name is.
21
+ */
22
+ export declare function resolveTasksFile(threadName: string): Promise<ResolvedTasksFile | null>;
23
+ /** Wire shape for the drawer — flat rows, depth carried explicitly. */
24
+ export interface TasksPayload {
25
+ filePath: string | null;
26
+ queue: TaskRow[];
27
+ done: TaskRow[];
28
+ errors: TasksFile['errors'];
29
+ /** Absent only when the thread has no schema tasks file at all. */
30
+ missing?: boolean;
31
+ }
32
+ export declare function readTasks(threadName: string): Promise<TasksPayload>;
33
+ export declare function moveTaskInThread(threadName: string, dragId: string, targetId: string, position: 'before' | 'after'): Promise<TasksPayload>;
34
+ export declare function resolveDepInThread(threadName: string, id: string, accept: boolean): Promise<TasksPayload>;
35
+ //# sourceMappingURL=tasks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/gateway/tasks.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAYH,OAAO,EACL,OAAO,EACP,SAAS,EAQV,MAAM,sBAAsB,CAAC;AAG9B,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,SAAS,CAAC;CACjB;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAkB5F;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;AA8BD,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"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Task 176 — server side of the `/tasks` drawer.
3
+ *
4
+ * The drawer edits the SAME file the prompt projection reads, found the same
5
+ * way: whichever of the thread's always-include files carries the schema marker.
6
+ * There is deliberately no second setting pointing at a tasks file — one
7
+ * resolution rule, so the drawer and the prompt can never disagree about which
8
+ * file is the queue (Rule #8).
9
+ */
10
+ import * as fs from 'fs';
11
+ import * as os from 'os';
12
+ import * as path from 'path';
13
+ import { loadGlobalConfig, loadThreadConfig, mergeConfigs, resolveFilePath, } from '../lib/config.js';
14
+ import { TasksFileError, assertWritable, hasTasksMarker, moveTask, parseTasksFile, resolveProposedDep, serializeTasksFile, } from '../lib/tasks-file.js';
15
+ import { resolveThreadCwd } from '../lib/worktree.js';
16
+ /**
17
+ * Find the thread's schema tasks file, or null when it has none.
18
+ *
19
+ * Detection is the marker inside the file, never the filename: a project whose
20
+ * `Tasks.md` has not been migrated is not a tasks file, and a migrated file
21
+ * under any other name is.
22
+ */
23
+ export async function resolveTasksFile(threadName) {
24
+ const merged = mergeConfigs(await loadGlobalConfig(), await loadThreadConfig(threadName));
25
+ const resolved = await resolveThreadCwd(threadName, merged.projectDir);
26
+ const cwd = resolved.cwd || merged.projectDir || path.join(os.homedir(), 'projects', threadName);
27
+ for (const entry of merged.alwaysInclude ?? []) {
28
+ const filePath = resolveFilePath(entry, cwd);
29
+ let content;
30
+ try {
31
+ if (!fs.existsSync(filePath) || fs.statSync(filePath).isDirectory())
32
+ continue;
33
+ content = fs.readFileSync(filePath, 'utf-8');
34
+ }
35
+ catch {
36
+ continue;
37
+ }
38
+ if (!hasTasksMarker(content))
39
+ continue;
40
+ return { filePath, file: parseTasksFile(content) };
41
+ }
42
+ return null;
43
+ }
44
+ export async function readTasks(threadName) {
45
+ const resolved = await resolveTasksFile(threadName);
46
+ if (!resolved) {
47
+ return { filePath: null, queue: [], done: [], errors: [], missing: true };
48
+ }
49
+ return {
50
+ filePath: resolved.filePath,
51
+ queue: resolved.file.queue,
52
+ done: resolved.file.done,
53
+ errors: resolved.file.errors,
54
+ };
55
+ }
56
+ /**
57
+ * Apply a mutation to the queue and write it back.
58
+ *
59
+ * Every write goes through {@link assertWritable} first: a file with lines the
60
+ * parser did not understand is refused whole rather than rewritten without them,
61
+ * because serializing a partial parse is how a drag silently deletes a line.
62
+ */
63
+ async function mutateQueue(threadName, mutate) {
64
+ const resolved = await resolveTasksFile(threadName);
65
+ if (!resolved) {
66
+ throw new TasksFileError('This thread has no tasks file in its always-include list');
67
+ }
68
+ assertWritable(resolved.file);
69
+ const next = { ...resolved.file, queue: mutate(resolved.file.queue) };
70
+ fs.writeFileSync(resolved.filePath, serializeTasksFile(next), 'utf-8');
71
+ return {
72
+ filePath: resolved.filePath,
73
+ queue: next.queue,
74
+ done: next.done,
75
+ errors: [],
76
+ };
77
+ }
78
+ export function moveTaskInThread(threadName, dragId, targetId, position) {
79
+ return mutateQueue(threadName, queue => moveTask(queue, dragId, targetId, position));
80
+ }
81
+ export function resolveDepInThread(threadName, id, accept) {
82
+ return mutateQueue(threadName, queue => resolveProposedDep(queue, id, accept));
83
+ }
84
+ //# sourceMappingURL=tasks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/gateway/tasks.ts"],"names":[],"mappings":"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"}
@@ -135,6 +135,8 @@ export interface AlwaysIncludeFile {
135
135
  truncated: boolean;
136
136
  /** Error message if file couldn't be read */
137
137
  error?: string;
138
+ /** True when a schema `Tasks.md` was projected down for the prompt (task 176). */
139
+ projected?: boolean;
138
140
  }
139
141
  /** Result of reading all always-include files */
140
142
  export interface AlwaysIncludeResult {
@@ -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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"}